diff --git a/changelogs/fragments/t6823_ipv6_autoconf.yml b/changelogs/fragments/t6823_ipv6_autoconf.yml new file mode 100644 index 00000000..8dfa04ee --- /dev/null +++ b/changelogs/fragments/t6823_ipv6_autoconf.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - vyos_l3_interfaces - ipv6 auto-config option incorrectly set diff --git a/docs/vyos.vyos.vyos_vrrp_module.rst b/docs/vyos.vyos.vyos_vrrp_module.rst new file mode 100644 index 00000000..a74b0802 --- /dev/null +++ b/docs/vyos.vyos.vyos_vrrp_module.rst @@ -0,0 +1,1240 @@ +.. _vyos.vyos.vyos_vrrp_module: + + +******************* +vyos.vyos.vyos_vrrp +******************* + +**High Availability (VRRP) resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages VRRP configuration of interfaces on devices running VYOS. +- The provided examples of commands are valid for VyOS 1.4+ + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
A dict of VRRP configuration.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
Disable instance
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the EOS device by executing the command show running-config | section bgp.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • deleted
  • +
  • merged ←
  • +
  • purged
  • +
  • replaced
  • +
  • gathered
  • +
  • rendered
  • +
  • parsed
  • +
+
+
The state the configuration should be left in.
+
State purged removes all the BGP configurations from the target device. Use caution with this state.('delete protocols bgp <x>')
+
State deleted only removes BGP attributes that this modules manages and does not negate the BGP process completely. Thereby, preserving address-family related configurations under BGP context.
+
Running states deleted and replaced will result in an error if there are address-family configuration lines present under neighbor context that is is to be removed. Please use the vyos.vyos.vyos_bgp_address_family module for prior cleanup.
+
Refer to examples for more details.
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # Before state + + # vyos@vyos:~$ show configuration commands | match "set protocols bgp" + # vyos@vyos:~$ + + - name: Merge provided configuration with device configuration + vyos.vyos.vyos_vrrp: + config: + as_number: "65536" + aggregate_address: + - prefix: "203.0.113.0/24" + as_set: true + - prefix: "192.0.2.0/24" + summary_only: true + network: + - address: "192.1.13.0/24" + backdoor: true + redistribute: + - protocol: "kernel" + metric: 45 + - protocol: "connected" + route_map: "map01" + maximum_paths: + - path: "ebgp" + count: 20 + - path: "ibgp" + count: 55 + timers: + keepalive: 35 + bgp_params: + bestpath: + as_path: "confed" + compare_routerid: true + default: + no_ipv4_unicast: true + router_id: "192.1.2.9" + confederation: + - peers: 20 + - peers: 55 + - identifier: 66 + neighbor: + - address: "192.0.2.25" + disable_connected_check: true + timers: + holdtime: 30 + keepalive: 10 + - address: "203.0.113.5" + attribute_unchanged: + as_path: true + med: true + ebgp_multihop: 2 + remote_as: 101 + update_source: "192.0.2.25" + - address: "5001::64" + maximum_prefix: 34 + distribute_list: + - acl: 20 + action: "export" + - acl: 40 + action: "import" + state: merged + + # After State + # vyos@vyos:~$ show configuration commands | match "set protocols bgp" + # set protocols bgp system-as 65536 + # set protocols bgp aggregate-address 192.0.2.0/24 'summary-only' + # set protocols bgp aggregate-address 203.0.113.0/24 'as-set' + # set protocols bgp maximum-paths ebgp '20' + # set protocols bgp maximum-paths ibgp '55' + # set protocols bgp neighbor 192.0.2.25 'disable-connected-check' + # set protocols bgp neighbor 192.0.2.25 timers holdtime '30' + # set protocols bgp neighbor 192.0.2.25 timers keepalive '10' + # set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'as-path' + # set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'med' + # set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'next-hop' + # set protocols bgp neighbor 203.0.113.5 ebgp-multihop '2' + # set protocols bgp neighbor 203.0.113.5 remote-as '101' + # set protocols bgp neighbor 203.0.113.5 update-source '192.0.2.25' + # set protocols bgp neighbor 5001::64 distribute-list export '20' + # set protocols bgp neighbor 5001::64 distribute-list import '40' + # set protocols bgp neighbor 5001::64 maximum-prefix '34' + # set protocols bgp network 192.1.13.0/24 'backdoor' + # set protocols bgp parameters bestpath as-path 'confed' + # set protocols bgp parameters bestpath 'compare-routerid' + # set protocols bgp parameters confederation identifier '66' + # set protocols bgp parameters confederation peers '20' + # set protocols bgp parameters confederation peers '55' + # set protocols bgp parameters default 'no-ipv4-unicast' + # set protocols bgp parameters router-id '192.1.2.9' + # set protocols bgp redistribute connected route-map 'map01' + # set protocols bgp redistribute kernel metric '45' + # set protocols bgp timers keepalive '35' + # vyos@vyos:~$ + # + # # Module Execution: + # + # "after": { + # "aggregate_address": [ + # { + # "prefix": "192.0.2.0/24", + # "summary_only": true + # }, + # { + # "prefix": "203.0.113.0/24", + # "as_set": true + # } + # ], + # "as_number": 65536, + # "bgp_params": { + # "bestpath": { + # "as_path": "confed", + # "compare_routerid": true + # }, + # "confederation": [ + # { + # "identifier": 66 + # }, + # { + # "peers": 20 + # }, + # { + # "peers": 55 + # } + # ], + # "default": { + # "no_ipv4_unicast": true + # }, + # "router_id": "192.1.2.9" + # }, + # "maximum_paths": [ + # { + # "count": 20, + # "path": "ebgp" + # }, + # { + # "count": 55, + # "path": "ibgp" + # } + # ], + # "neighbor": [ + # { + # "address": "192.0.2.25", + # "disable_connected_check": true, + # "timers": { + # "holdtime": 30, + # "keepalive": 10 + # } + # }, + # { + # "address": "203.0.113.5", + # "attribute_unchanged": { + # "as_path": true, + # "med": true, + # "next_hop": true + # }, + # "ebgp_multihop": 2, + # "remote_as": 101, + # "update_source": "192.0.2.25" + # }, + # { + # "address": "5001::64", + # "distribute_list": [ + # { + # "acl": 20, + # "action": "export" + # }, + # { + # "acl": 40, + # "action": "import" + # } + # ], + # "maximum_prefix": 34 + # } + # ], + # "network": [ + # { + # "address": "192.1.13.0/24", + # "backdoor": true + # } + # ], + # "redistribute": [ + # { + # "protocol": "connected", + # "route_map": "map01" + # }, + # { + # "metric": 45, + # "protocol": "kernel" + # } + # ], + # "timers": { + # "keepalive": 35 + # } + # }, + # "before": {}, + # "changed": true, + # "commands": [ + # "set protocols bgp neighbor 192.0.2.25 disable-connected-check", + # "set protocols bgp neighbor 192.0.2.25 timers holdtime 30", + # "set protocols bgp neighbor 192.0.2.25 timers keepalive 10", + # "set protocols bgp neighbor 203.0.113.5 attribute-unchanged as-path", + # "set protocols bgp neighbor 203.0.113.5 attribute-unchanged med", + # "set protocols bgp neighbor 203.0.113.5 attribute-unchanged next-hop", + # "set protocols bgp neighbor 203.0.113.5 ebgp-multihop 2", + # "set protocols bgp neighbor 203.0.113.5 remote-as 101", + # "set protocols bgp neighbor 203.0.113.5 update-source 192.0.2.25", + # "set protocols bgp neighbor 5001::64 maximum-prefix 34", + # "set protocols bgp neighbor 5001::64 distribute-list export 20", + # "set protocols bgp neighbor 5001::64 distribute-list import 40", + # "set protocols bgp redistribute kernel metric 45", + # "set protocols bgp redistribute connected route-map map01", + # "set protocols bgp network 192.1.13.0/24 backdoor", + # "set protocols bgp aggregate-address 203.0.113.0/24 as-set", + # "set protocols bgp aggregate-address 192.0.2.0/24 summary-only", + # "set protocols bgp parameters bestpath as-path confed", + # "set protocols bgp parameters bestpath compare-routerid", + # "set protocols bgp parameters default no-ipv4-unicast", + # "set protocols bgp parameters router-id 192.1.2.9", + # "set protocols bgp parameters confederation peers 20", + # "set protocols bgp parameters confederation peers 55", + # "set protocols bgp parameters confederation identifier 66", + # "set protocols bgp maximum-paths ebgp 20", + # "set protocols bgp maximum-paths ibgp 55", + # "set protocols bgp timers keepalive 35" + # ], + + # Using replaced: + # -------------- + + # Before state: + + # vyos@vyos:~$ show configuration commands | match "set protocols bgp" + # set protocols bgp system-as 65536 + # set protocols bgp aggregate-address 192.0.2.0/24 'summary-only' + # set protocols bgp aggregate-address 203.0.113.0/24 'as-set' + # set protocols bgp maximum-paths ebgp '20' + # set protocols bgp maximum-paths ibgp '55' + # set protocols bgp neighbor 192.0.2.25 'disable-connected-check' + # set protocols bgp neighbor 192.0.2.25 timers holdtime '30' + # set protocols bgp neighbor 192.0.2.25 timers keepalive '10' + # set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'as-path' + # set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'med' + # set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'next-hop' + # set protocols bgp neighbor 203.0.113.5 ebgp-multihop '2' + # set protocols bgp neighbor 203.0.113.5 remote-as '101' + # set protocols bgp neighbor 203.0.113.5 update-source '192.0.2.25' + # set protocols bgp neighbor 5001::64 distribute-list export '20' + # set protocols bgp neighbor 5001::64 distribute-list import '40' + # set protocols bgp neighbor 5001::64 maximum-prefix '34' + # set protocols bgp network 192.1.13.0/24 'backdoor' + # set protocols bgp parameters bestpath as-path 'confed' + # set protocols bgp parameters bestpath 'compare-routerid' + # set protocols bgp parameters confederation identifier '66' + # set protocols bgp parameters confederation peers '20' + # set protocols bgp parameters confederation peers '55' + # set protocols bgp parameters default 'no-ipv4-unicast' + # set protocols bgp parameters router-id '192.1.2.9' + # set protocols bgp redistribute connected route-map 'map01' + # set protocols bgp redistribute kernel metric '45' + # set protocols bgp timers keepalive '35' + # vyos@vyos:~$ + + - name: Replace + vyos.vyos.vyos_vrrp: + config: + as_number: "65536" + network: + - address: "203.0.113.0/24" + route_map: map01 + redistribute: + - protocol: "static" + route_map: "map01" + neighbor: + - address: "192.0.2.40" + advertisement_interval: 72 + capability: + orf: "receive" + bgp_params: + bestpath: + as_path: "confed" + state: replaced + # After state: + + # vyos@vyos:~$ show configuration commands | match "set protocols bgp" + # set protocols bgp system-as 65536 + # set protocols bgp neighbor 192.0.2.40 advertisement-interval '72' + # set protocols bgp neighbor 192.0.2.40 capability orf prefix-list 'receive' + # set protocols bgp network 203.0.113.0/24 route-map 'map01' + # set protocols bgp parameters bestpath as-path 'confed' + # set protocols bgp redistribute static route-map 'map01' + # vyos@vyos:~$ + # + # + # Module Execution: + # + # "after": { + # "as_number": 65536, + # "bgp_params": { + # "bestpath": { + # "as_path": "confed" + # } + # }, + # "neighbor": [ + # { + # "address": "192.0.2.40", + # "advertisement_interval": 72, + # "capability": { + # "orf": "receive" + # } + # } + # ], + # "network": [ + # { + # "address": "203.0.113.0/24", + # "route_map": "map01" + # } + # ], + # "redistribute": [ + # { + # "protocol": "static", + # "route_map": "map01" + # } + # ] + # }, + # "before": { + # "aggregate_address": [ + # { + # "prefix": "192.0.2.0/24", + # "summary_only": true + # }, + # { + # "prefix": "203.0.113.0/24", + # "as_set": true + # } + # ], + # "as_number": 65536, + # "bgp_params": { + # "bestpath": { + # "as_path": "confed", + # "compare_routerid": true + # }, + # "confederation": [ + # { + # "identifier": 66 + # }, + # { + # "peers": 20 + # }, + # { + # "peers": 55 + # } + # ], + # "default": { + # "no_ipv4_unicast": true + # }, + # "router_id": "192.1.2.9" + # }, + # "maximum_paths": [ + # { + # "count": 20, + # "path": "ebgp" + # }, + # { + # "count": 55, + # "path": "ibgp" + # } + # ], + # "neighbor": [ + # { + # "address": "192.0.2.25", + # "disable_connected_check": true, + # "timers": { + # "holdtime": 30, + # "keepalive": 10 + # } + # }, + # { + # "address": "203.0.113.5", + # "attribute_unchanged": { + # "as_path": true, + # "med": true, + # "next_hop": true + # }, + # "ebgp_multihop": 2, + # "remote_as": 101, + # "update_source": "192.0.2.25" + # }, + # { + # "address": "5001::64", + # "distribute_list": [ + # { + # "acl": 20, + # "action": "export" + # }, + # { + # "acl": 40, + # "action": "import" + # } + # ], + # "maximum_prefix": 34 + # } + # ], + # "network": [ + # { + # "address": "192.1.13.0/24", + # "backdoor": true + # } + # ], + # "redistribute": [ + # { + # "protocol": "connected", + # "route_map": "map01" + # }, + # { + # "metric": 45, + # "protocol": "kernel" + # } + # ], + # "timers": { + # "keepalive": 35 + # } + # }, + # "changed": true, + # "commands": [ + # "delete protocols bgp timers", + # "delete protocols bgp maximum-paths ", + # "delete protocols bgp maximum-paths ", + # "delete protocols bgp parameters router-id 192.1.2.9", + # "delete protocols bgp parameters default", + # "delete protocols bgp parameters confederation", + # "delete protocols bgp parameters bestpath compare-routerid", + # "delete protocols bgp aggregate-address", + # "delete protocols bgp network 192.1.13.0/24", + # "delete protocols bgp redistribute kernel", + # "delete protocols bgp redistribute kernel", + # "delete protocols bgp redistribute connected", + # "delete protocols bgp redistribute connected", + # "delete protocols bgp neighbor 5001::64", + # "delete protocols bgp neighbor 203.0.113.5", + # "delete protocols bgp neighbor 192.0.2.25", + # "set protocols bgp neighbor 192.0.2.40 advertisement-interval 72", + # "set protocols bgp neighbor 192.0.2.40 capability orf prefix-list receive", + # "set protocols bgp redistribute static route-map map01", + # "set protocols bgp network 203.0.113.0/24 route-map map01" + # ], + + # Using deleted: + # ------------- + + # Before state: + + # vyos@vyos:~$ show configuration commands | match "set protocols bgp" + # set protocols bgp system-as 65536 + # set protocols bgp neighbor 192.0.2.40 advertisement-interval '72' + # set protocols bgp neighbor 192.0.2.40 capability orf prefix-list 'receive' + # set protocols bgp network 203.0.113.0/24 route-map 'map01' + # set protocols bgp parameters bestpath as-path 'confed' + # set protocols bgp redistribute static route-map 'map01' + # vyos@vyos:~$ + + - name: Delete configuration + vyos.vyos.vyos_vrrp: + config: + as_number: "65536" + state: deleted + + # After state: + + # vyos@vyos:~$ show configuration commands | match "set protocols bgp" + # set protocols bgp '65536' + # vyos@vyos:~$ + # + # + # Module Execution: + # + # "after": { + # "as_number": 65536 + # }, + # "before": { + # "as_number": 65536, + # "bgp_params": { + # "bestpath": { + # "as_path": "confed" + # } + # }, + # "neighbor": [ + # { + # "address": "192.0.2.40", + # "advertisement_interval": 72, + # "capability": { + # "orf": "receive" + # } + # } + # ], + # "network": [ + # { + # "address": "203.0.113.0/24", + # "route_map": "map01" + # } + # ], + # "redistribute": [ + # { + # "protocol": "static", + # "route_map": "map01" + # } + # ] + # }, + # "changed": true, + # "commands": [ + # "delete protocols bgp neighbor 192.0.2.40", + # "delete protocols bgp redistribute", + # "delete protocols bgp network", + # "delete protocols bgp parameters" + # ], + + # Using purged: + + # Before state: + + # vyos@vyos:~$ show configuration commands | match "set protocols bgp" + # set protocols bgp system-as 65536 + # set protocols bgp aggregate-address 192.0.2.0/24 'summary-only' + # set protocols bgp aggregate-address 203.0.113.0/24 'as-set' + # set protocols bgp maximum-paths ebgp '20' + # set protocols bgp maximum-paths ibgp '55' + # set protocols bgp neighbor 192.0.2.25 'disable-connected-check' + # set protocols bgp neighbor 192.0.2.25 timers holdtime '30' + # set protocols bgp neighbor 192.0.2.25 timers keepalive '10' + # set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'as-path' + # set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'med' + # set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'next-hop' + # set protocols bgp neighbor 203.0.113.5 ebgp-multihop '2' + # set protocols bgp neighbor 203.0.113.5 remote-as '101' + # set protocols bgp neighbor 203.0.113.5 update-source '192.0.2.25' + # set protocols bgp neighbor 5001::64 distribute-list export '20' + # set protocols bgp neighbor 5001::64 distribute-list import '40' + # set protocols bgp neighbor 5001::64 maximum-prefix '34' + # set protocols bgp network 192.1.13.0/24 'backdoor' + # set protocols bgp parameters bestpath as-path 'confed' + # set protocols bgp parameters bestpath 'compare-routerid' + # set protocols bgp parameters confederation identifier '66' + # set protocols bgp parameters confederation peers '20' + # set protocols bgp parameters confederation peers '55' + # set protocols bgp parameters default 'no-ipv4-unicast' + # set protocols bgp parameters router-id '192.1.2.9' + # set protocols bgp redistribute connected route-map 'map01' + # set protocols bgp redistribute kernel metric '45' + # set protocols bgp timers keepalive '35' + # vyos@vyos:~$ + + + - name: Purge configuration + vyos.vyos.vyos_vrrp: + config: + as_number: "65536" + state: purged + + # After state: + + # vyos@vyos:~$ show configuration commands | match "set protocols bgp" + # vyos@vyos:~$ + # + # Module Execution: + # + # "after": {}, + # "before": { + # "aggregate_address": [ + # { + # "prefix": "192.0.2.0/24", + # "summary_only": true + # }, + # { + # "prefix": "203.0.113.0/24", + # "as_set": true + # } + # ], + # "as_number": 65536, + # "bgp_params": { + # "bestpath": { + # "as_path": "confed", + # "compare_routerid": true + # }, + # "confederation": [ + # { + # "identifier": 66 + # }, + # { + # "peers": 20 + # }, + # { + # "peers": 55 + # } + # ], + # "default": { + # "no_ipv4_unicast": true + # }, + # "router_id": "192.1.2.9" + # }, + # "maximum_paths": [ + # { + # "count": 20, + # "path": "ebgp" + # }, + # { + # "count": 55, + # "path": "ibgp" + # } + # ], + # "neighbor": [ + # { + # "address": "192.0.2.25", + # "disable_connected_check": true, + # "timers": { + # "holdtime": 30, + # "keepalive": 10 + # } + # }, + # { + # "address": "203.0.113.5", + # "attribute_unchanged": { + # "as_path": true, + # "med": true, + # "next_hop": true + # }, + # "ebgp_multihop": 2, + # "remote_as": 101, + # "update_source": "192.0.2.25" + # }, + # { + # "address": "5001::64", + # "distribute_list": [ + # { + # "acl": 20, + # "action": "export" + # }, + # { + # "acl": 40, + # "action": "import" + # } + # ], + # "maximum_prefix": 34 + # } + # ], + # "network": [ + # { + # "address": "192.1.13.0/24", + # "backdoor": true + # } + # ], + # "redistribute": [ + # { + # "protocol": "connected", + # "route_map": "map01" + # }, + # { + # "metric": 45, + # "protocol": "kernel" + # } + # ], + # "timers": { + # "keepalive": 35 + # } + # }, + # "changed": true, + # "commands": [ + # "delete protocols bgp 65536" + # ], + + + # Deleted in presence of address family under neighbors: + + # Before state: + # vyos@vyos:~$ show configuration commands | match "set protocols bgp" + # set protocols bgp system-as 65536 + # set protocols bgp neighbor 192.0.2.43 advertisement-interval '72' + # set protocols bgp neighbor 192.0.2.43 capability 'dynamic' + # set protocols bgp neighbor 192.0.2.43 'disable-connected-check' + # set protocols bgp neighbor 192.0.2.43 timers holdtime '30' + # set protocols bgp neighbor 192.0.2.43 timers keepalive '10' + # set protocols bgp neighbor 203.0.113.0 address-family 'ipv6-unicast' + # set protocols bgp neighbor 203.0.113.0 capability orf prefix-list 'receive' + # set protocols bgp network 203.0.113.0/24 route-map 'map01' + # set protocols bgp parameters 'always-compare-med' + # set protocols bgp parameters bestpath as-path 'confed' + # set protocols bgp parameters bestpath 'compare-routerid' + # set protocols bgp parameters dampening half-life '33' + # set protocols bgp parameters dampening max-suppress-time '20' + # set protocols bgp parameters dampening re-use '60' + # set protocols bgp parameters dampening start-suppress-time '5' + # set protocols bgp parameters default 'no-ipv4-unicast' + # set protocols bgp parameters distance global external '66' + # set protocols bgp parameters distance global internal '20' + # set protocols bgp parameters distance global local '10' + # set protocols bgp redistribute static route-map 'map01' + # vyos@vyos:~$ ^C + # vyos@vyos:~$ + + - name: Delete configuration + vyos.vyos.vyos_vrrp: + config: + as_number: "65536" + state: deleted + + # Module Execution: + # + # "changed": false, + # "invocation": { + # "module_args": { + # "config": { + # "aggregate_address": null, + # "as_number": 65536, + # "bgp_params": null, + # "maximum_paths": null, + # "neighbor": null, + # "network": null, + # "redistribute": null, + # "timers": null + # }, + # "running_config": null, + # "state": "deleted" + # } + # }, + # "msg": "Use the _bgp_address_family module to delete the address_family under neighbor 203.0.113.0, before replacing/deleting the neighbor." + # } + + # using gathered: + # -------------- + + # Before state: + # vyos@vyos:~$ show configuration commands | match "set protocols bgp" + # set protocols bgp system-as 65536 + # set protocols bgp neighbor 192.0.2.43 advertisement-interval '72' + # set protocols bgp neighbor 192.0.2.43 capability 'dynamic' + # set protocols bgp neighbor 192.0.2.43 'disable-connected-check' + # set protocols bgp neighbor 192.0.2.43 timers holdtime '30' + # set protocols bgp neighbor 192.0.2.43 timers keepalive '10' + # set protocols bgp neighbor 203.0.113.0 address-family 'ipv6-unicast' + # set protocols bgp neighbor 203.0.113.0 capability orf prefix-list 'receive' + # set protocols bgp network 203.0.113.0/24 route-map 'map01' + # set protocols bgp parameters 'always-compare-med' + # set protocols bgp parameters bestpath as-path 'confed' + # set protocols bgp parameters bestpath 'compare-routerid' + # set protocols bgp parameters dampening half-life '33' + # set protocols bgp parameters dampening max-suppress-time '20' + # set protocols bgp parameters dampening re-use '60' + # set protocols bgp parameters dampening start-suppress-time '5' + # set protocols bgp parameters default 'no-ipv4-unicast' + # set protocols bgp parameters distance global external '66' + # set protocols bgp parameters distance global internal '20' + # set protocols bgp parameters distance global local '10' + # set protocols bgp redistribute static route-map 'map01' + # vyos@vyos:~$ ^C + + - name: gather configs + vyos.vyos.vyos_vrrp: + state: gathered + + # Module Execution: + # "gathered": { + # "as_number": 65536, + # "bgp_params": { + # "always_compare_med": true, + # "bestpath": { + # "as_path": "confed", + # "compare_routerid": true + # }, + # "default": { + # "no_ipv4_unicast": true + # }, + # "distance": [ + # { + # "type": "external", + # "value": 66 + # }, + # { + # "type": "internal", + # "value": 20 + # }, + # { + # "type": "local", + # "value": 10 + # } + # ] + # }, + # "neighbor": [ + # { + # "address": "192.0.2.43", + # "advertisement_interval": 72, + # "capability": { + # "dynamic": true + # }, + # "disable_connected_check": true, + # "timers": { + # "holdtime": 30, + # "keepalive": 10 + # } + # }, + # { + # "address": "203.0.113.0", + # "capability": { + # "orf": "receive" + # } + # } + # ], + # "network": [ + # { + # "address": "203.0.113.0/24", + # "route_map": "map01" + # } + # ], + # "redistribute": [ + # { + # "protocol": "static", + # "route_map": "map01" + # } + # ] + # }, + # + + # Using parsed: + # ------------ + + # parsed.cfg + + # set protocols bgp neighbor 192.0.2.43 advertisement-interval '72' + # set protocols bgp neighbor 192.0.2.43 capability 'dynamic' + # set protocols bgp neighbor 192.0.2.43 'disable-connected-check' + # set protocols bgp neighbor 192.0.2.43 timers holdtime '30' + # set protocols bgp neighbor 192.0.2.43 timers keepalive '10' + # set protocols bgp neighbor 203.0.113.0 address-family 'ipv6-unicast' + # set protocols bgp neighbor 203.0.113.0 capability orf prefix-list 'receive' + # set protocols bgp network 203.0.113.0/24 route-map 'map01' + # set protocols bgp parameters 'always-compare-med' + # set protocols bgp parameters bestpath as-path 'confed' + # set protocols bgp parameters bestpath 'compare-routerid' + # set protocols bgp parameters dampening half-life '33' + # set protocols bgp parameters dampening max-suppress-time '20' + # set protocols bgp parameters dampening re-use '60' + # set protocols bgp parameters dampening start-suppress-time '5' + # set protocols bgp parameters default 'no-ipv4-unicast' + # set protocols bgp parameters distance global external '66' + # set protocols bgp parameters distance global internal '20' + # set protocols bgp parameters distance global local '10' + # set protocols bgp redistribute static route-map 'map01' + + - name: parse configs + vyos.vyos.vyos_vrrp: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + tags: + - parsed + + # Module execution: + # "parsed": { + # "as_number": 65536, + # "bgp_params": { + # "always_compare_med": true, + # "bestpath": { + # "as_path": "confed", + # "compare_routerid": true + # }, + # "default": { + # "no_ipv4_unicast": true + # }, + # "distance": [ + # { + # "type": "external", + # "value": 66 + # }, + # { + # "type": "internal", + # "value": 20 + # }, + # { + # "type": "local", + # "value": 10 + # } + # ] + # }, + # "neighbor": [ + # { + # "address": "192.0.2.43", + # "advertisement_interval": 72, + # "capability": { + # "dynamic": true + # }, + # "disable_connected_check": true, + # "timers": { + # "holdtime": 30, + # "keepalive": 10 + # } + # }, + # { + # "address": "203.0.113.0", + # "capability": { + # "orf": "receive" + # } + # } + # ], + # "network": [ + # { + # "address": "203.0.113.0/24", + # "route_map": "map01" + # } + # ], + # "redistribute": [ + # { + # "protocol": "static", + # "route_map": "map01" + # } + # ] + # } + # + + # Using rendered: + # -------------- + + - name: Render + vyos.vyos.vyos_vrrp: + config: + as_number: "65536" + network: + - address: "203.0.113.0/24" + route_map: map01 + redistribute: + - protocol: "static" + route_map: "map01" + bgp_params: + always_compare_med: true + dampening: + start_suppress_time: 5 + max_suppress_time: 20 + half_life: 33 + re_use: 60 + distance: + - type: "internal" + value: 20 + - type: "local" + value: 10 + - type: "external" + value: 66 + bestpath: + as_path: "confed" + compare_routerid: true + default: + no_ipv4_unicast: true + neighbor: + - address: "192.0.2.43" + disable_connected_check: true + advertisement_interval: 72 + capability: + dynamic: true + timers: + holdtime: 30 + keepalive: 10 + - address: "203.0.113.0" + capability: + orf: "receive" + state: rendered + + # Module Execution: + # "rendered": [ + # "set protocols bgp neighbor 192.0.2.43 disable-connected-check", + # "set protocols bgp neighbor 192.0.2.43 advertisement-interval 72", + # "set protocols bgp neighbor 192.0.2.43 capability dynamic", + # "set protocols bgp neighbor 192.0.2.43 timers holdtime 30", + # "set protocols bgp neighbor 192.0.2.43 timers keepalive 10", + # "set protocols bgp neighbor 203.0.113.0 capability orf prefix-list receive", + # "set protocols bgp redistribute static route-map map01", + # "set protocols bgp network 203.0.113.0/24 route-map map01", + # "set protocols bgp parameters always-compare-med", + # "set protocols bgp parameters dampening half-life 33", + # "set protocols bgp parameters dampening max-suppress-time 20", + # "set protocols bgp parameters dampening re-use 60", + # "set protocols bgp parameters dampening start-suppress-time 5", + # "set protocols bgp parameters distance global internal 20", + # "set protocols bgp parameters distance global local 10", + # "set protocols bgp parameters distance global external 66", + # "set protocols bgp parameters bestpath as-path confed", + # "set protocols bgp parameters bestpath compare-routerid", + # "set protocols bgp parameters default no-ipv4-unicast" + # ] + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration after module execution.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ before + +
+ dictionary +
+
when state is merged, replaced, overridden, deleted or purged +
The configuration prior to the module execution.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ commands + +
+ list +
+
when state is merged, replaced, overridden, deleted or purged +
The set of commands pushed to the remote device.
+
+
Sample:
+
['set protocols bgp redistribute static route-map map01', 'set protocols bgp network 203.0.113.0/24 route-map map01', 'set protocols bgp parameters always-compare-med']
+
+
+ gathered + +
+ list +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ list +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ list +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['set protocols bgp redistribute static route-map map01', 'set protocols bgp network 203.0.113.0/24 route-map map01', 'set protocols bgp parameters always-compare-med']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Evgeny Molotkov (@omnom62) diff --git a/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py b/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py index ee709e2a..a23494cd 100644 --- a/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py +++ b/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py @@ -1,319 +1,354 @@ # # -*- coding: utf-8 -*- # Copyright 2019 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) """ The vyos_l3_interfaces class 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 it's desired end-state is created """ from __future__ import absolute_import, division, print_function __metaclass__ = type from copy import deepcopy from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import ( ConfigBase, ) from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( remove_empties, to_list, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import Facts from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import ( diff_list_of_dicts, get_interface_type, search_obj_in_list, ) class L3_interfaces(ConfigBase): """ The vyos_l3_interfaces class """ gather_subset = [ "!all", "!min", ] gather_network_resources = [ "l3_interfaces", ] def __init__(self, module): super(L3_interfaces, self).__init__(module) def get_l3_interfaces_facts(self, data=None): """Get the 'facts' (the current configuration) :rtype: A dictionary :returns: The current configuration as a dictionary """ facts, _warnings = Facts(self._module).get_facts( self.gather_subset, self.gather_network_resources, data=data, ) l3_interfaces_facts = facts["ansible_network_resources"].get("l3_interfaces") if not l3_interfaces_facts: return [] return l3_interfaces_facts def execute_module(self): """Execute the module :rtype: A dictionary :returns: The result from module execution """ result = {"changed": False} warnings = list() commands = list() if self.state in self.ACTION_STATES: - existing_l3_interfaces_facts = self.get_l3_interfaces_facts() + existing_l3_interfaces_facts = self.mutate_autoconfig(self.get_l3_interfaces_facts()) else: existing_l3_interfaces_facts = [] if self.state in self.ACTION_STATES or self.state == "rendered": commands.extend(self.set_config(existing_l3_interfaces_facts)) if commands and self.state in self.ACTION_STATES: if not self._module.check_mode: self._connection.edit_config(commands) result["changed"] = True if self.state in self.ACTION_STATES: result["commands"] = commands if self.state in self.ACTION_STATES or self.state == "gathered": - changed_l3_interfaces_facts = self.get_l3_interfaces_facts() + changed_l3_interfaces_facts = self.mutate_autoconfig(self.get_l3_interfaces_facts()) elif self.state == "rendered": result["rendered"] = commands elif self.state == "parsed": running_config = self._module.params["running_config"] + if not running_config: self._module.fail_json( msg="value of running_config parameter must not be empty for state parsed", ) - result["parsed"] = self.get_l3_interfaces_facts(data=running_config) + result["parsed"] = self.mutate_autoconfig( + self.get_l3_interfaces_facts(data=running_config), + ) else: changed_l3_interfaces_facts = [] if self.state in self.ACTION_STATES: result["before"] = existing_l3_interfaces_facts if result["changed"]: result["after"] = changed_l3_interfaces_facts elif self.state == "gathered": result["gathered"] = changed_l3_interfaces_facts result["warnings"] = warnings return result def set_config(self, existing_l3_interfaces_facts): """Collect the configuration from the args passed to the module, collect the current configuration (as a dict from facts) :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ want = self._module.params["config"] have = existing_l3_interfaces_facts + resp = self.set_state(want, have) return to_list(resp) def set_state(self, want, have): """Select the appropriate function based on the state provided :param want: the desired configuration as a dictionary :param have: the current configuration as a dictionary :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ commands = [] state = self._module.params["state"] if state in ("merged", "replaced", "overridden", "rendered") and not want: self._module.fail_json( msg="value of config parameter must not be empty for state {0}".format(state), ) if state == "overridden": commands.extend(self._state_overridden(want=want, have=have)) elif state == "deleted": if not want: for intf in have: commands.extend(self._state_deleted({"name": intf["name"]}, intf)) else: for item in want: obj_in_have = search_obj_in_list(item["name"], have) commands.extend(self._state_deleted(item, obj_in_have)) else: for item in want: name = item["name"] obj_in_have = search_obj_in_list(name, have) if not obj_in_have: obj_in_have = {"name": item["name"]} if state in ("merged", "rendered"): commands.extend(self._state_merged(item, obj_in_have)) elif state == "replaced": commands.extend(self._state_replaced(item, obj_in_have)) + commands = [command.replace("auto-config", "autoconf") for command in commands] return commands def _state_replaced(self, want, have): """The command generator when state is replaced :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ commands = [] if have: commands.extend(self._state_deleted(want, have)) commands.extend(self._state_merged(want, have)) return commands def _state_overridden(self, want, have): """The command generator when state is overridden :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ commands = [] for intf in have: intf_in_want = search_obj_in_list(intf["name"], want) if not intf_in_want: commands.extend(self._state_deleted({"name": intf["name"]}, intf)) for intf in want: intf_in_have = search_obj_in_list(intf["name"], have) commands.extend(self._state_replaced(intf, intf_in_have)) return commands def _state_merged(self, want, have): """The command generator when state is merged :rtype: A list :returns: the commands necessary to merge the provided into the current configuration """ commands = [] want_copy = deepcopy(remove_empties(want)) have_copy = deepcopy(remove_empties(have)) want_vifs = want_copy.pop("vifs", []) have_vifs = have_copy.pop("vifs", []) for update in self._get_updates(want_copy, have_copy): for key, value in update.items(): commands.append( self._compute_commands(key=key, value=value, interface=want_copy["name"]), ) if want_vifs: for want_vif in want_vifs: have_vif = search_obj_in_list(want_vif["vlan_id"], have_vifs, key="vlan_id") if not have_vif: have_vif = {} for update in self._get_updates(want_vif, have_vif): for key, value in update.items(): commands.append( self._compute_commands( key=key, value=value, interface=want_copy["name"], vif=want_vif["vlan_id"], ), ) - return commands def _state_deleted(self, want, have): """The command generator when state is deleted :rtype: A list :returns: the commands necessary to remove the current configuration of the provided objects """ commands = [] want_copy = deepcopy(remove_empties(want)) have_copy = deepcopy(have) - want_vifs = want_copy.pop("vifs", []) - have_vifs = have_copy.pop("vifs", []) - - for update in self._get_updates(have_copy, want_copy): - for key, value in update.items(): + if have_copy is not None: + if all(v in (None, {}, []) for k, v in want_copy.items() if k != "name"): commands.append( self._compute_commands( - key=key, - value=value, + key=None, + value=None, interface=want_copy["name"], remove=True, ), ) - - if have_vifs: - for have_vif in have_vifs: - want_vif = search_obj_in_list(have_vif["vlan_id"], want_vifs, key="vlan_id") - if not want_vif: - want_vif = {"vlan_id": have_vif["vlan_id"]} - - for update in self._get_updates(have_vif, want_vif): - for key, value in update.items(): - commands.append( - self._compute_commands( - key=key, - interface=want_copy["name"], - value=value, - vif=want_vif["vlan_id"], - remove=True, - ), - ) + return commands + + want_vifs = want_copy.pop("vifs", []) + have_vifs = have_copy.pop("vifs", []) + + if have_vifs: + for have_vif in have_vifs: + want_vif = search_obj_in_list(have_vif["vlan_id"], want_vifs, key="vlan_id") + if not want_vif: + want_vif = {"vlan_id": have_vif["vlan_id"]} + + for update in self._get_updates(have_vif, want_vif): + for key, value in update.items(): + commands.append( + self._compute_commands( + key=key, + interface=want_copy["name"], + value=value, + vif=want_vif["vlan_id"], + remove=True, + ), + ) + + for update in self._get_updates(have_copy, want_copy): + for key, value in update.items(): + commands.append( + self._compute_commands( + key=key, + value=value, + interface=want_copy["name"], + remove=True, + ), + ) return commands def _compute_commands(self, interface, key, vif=None, value=None, remove=False): - intf_context = "interfaces {0} {1}".format(get_interface_type(interface), interface) + if value == "auto-config" and vif is None: + intf_context = "interfaces {0} {1} ipv6".format( + get_interface_type(interface), + interface, + ) + else: + intf_context = "interfaces {0} {1}".format(get_interface_type(interface), interface) + set_cmd = "set {0}".format(intf_context) del_cmd = "delete {0}".format(intf_context) if vif: - set_cmd = set_cmd + (" vif {0}".format(vif)) - del_cmd = del_cmd + (" vif {0}".format(vif)) + suffix = " ipv6" if value == "auto-config" else "" + set_cmd += f" vif {vif}{suffix}" + del_cmd += f" vif {vif}{suffix}" - if remove: + if remove and key and value: command = "{0} {1} '{2}'".format(del_cmd, key, value) + elif remove and not (key and value): + command = "{0}".format(del_cmd) else: command = "{0} {1} '{2}'".format(set_cmd, key, value) return command def _get_updates(self, want, have): updates = [] updates = diff_list_of_dicts(want.get("ipv4", []), have.get("ipv4", [])) updates.extend(diff_list_of_dicts(want.get("ipv6", []), have.get("ipv6", []))) return updates + + def mutate_autoconfig(self, obj): + if isinstance(obj, dict): + return dict(map(lambda kv: (kv[0], self.mutate_autoconfig(kv[1])), obj.items())) + if isinstance(obj, list): + return list(map(self.mutate_autoconfig, obj)) + if isinstance(obj, str): + return obj.replace("autoconf", "auto-config") + return obj diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/_parsed_config.cfg b/tests/integration/targets/vyos_l3_interfaces/tests/cli/_parsed_config.cfg index 9232a0a4..a34ac606 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/_parsed_config.cfg +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/_parsed_config.cfg @@ -1,7 +1,8 @@ set interfaces ethernet eth1 address '192.0.2.10/24' +set interfaces ethernet eth1 vif 102 ipv6 address 'autoconf' set interfaces ethernet eth1 address '2001:db8::10/32' set interfaces ethernet eth1 hw-id '08:00:27:da:67:43' set interfaces ethernet eth2 address '198.51.100.10/24' set interfaces ethernet eth2 hw-id '08:00:27:d8:70:b0' set interfaces ethernet eth2 vif 101 address '198.51.100.130/25' set interfaces ethernet eth2 vif 101 address '2001:db8::20/32' diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/_populate.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/_populate.yaml index 6f6c5066..d6ccd116 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/_populate.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/_populate.yaml @@ -1,13 +1,13 @@ --- - ansible.builtin.include_tasks: _remove_config.yaml - name: Setup vars: lines: |- set interfaces ethernet eth1 address '192.0.2.14/24' set interfaces ethernet eth2 address '192.0.2.10/24' set interfaces ethernet eth2 address '192.0.2.11/24' - set interfaces ethernet eth2 address '2001:db8::10/32' + set interfaces ethernet eth2 address '2001:db8::10/32' set interfaces ethernet eth2 address '2001:db8::12/32' ansible.netcommon.cli_config: config: "{{ lines }}" diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/_remove_config.yaml index aa5a628f..13774cd5 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/_remove_config.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/_remove_config.yaml @@ -1,11 +1,14 @@ --- - name: Remove Config vars: - lines: "delete interfaces ethernet \"{{ intf }}\" address\ndelete interfaces ethernet \"{{ intf }}\" vif\n" + lines: | + delete interfaces ethernet "{{ intf }}" address + delete interfaces ethernet "{{ intf }}" vif + delete interfaces ethernet "{{ intf }}" ipv6 loop: - eth1 - eth2 loop_control: loop_var: intf ansible.netcommon.cli_config: config: "{{ lines }}" diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/deleted.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/deleted.yaml index df21b431..000d55e0 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/deleted.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/deleted.yaml @@ -1,46 +1,82 @@ --- - debug: msg: START vyos_interfaces deleted integration tests ansible_connection={{ ansible_connection }} - include_tasks: _populate.yaml - block: - name: Delete attributes of given interfaces register: result vyos.vyos.vyos_l3_interfaces: &id001 config: - name: eth1 - - name: eth2 state: deleted - name: Assert that the before dicts were correctly generated assert: that: - "{{ populate | symmetric_difference(result['before']) |length == 0 }}" - name: Assert that the correct set of commands were generated assert: that: - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" - name: Assert that the after dicts were correctly generated assert: that: - "{{ deleted['after'] | symmetric_difference(result['after']) |length == 0 }}" - name: Delete attributes of given interfaces (IDEMPOTENT) register: result vyos.vyos.vyos_l3_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - result.changed == false - name: Assert that the before dicts were correctly generated assert: that: - "{{ deleted['after'] | symmetric_difference(result['before']) |length == 0 }}" + + - name: Prepare delete test for SLAAC auto-config + vyos.vyos.vyos_l3_interfaces: + config: + - name: eth1 + ipv6: + - address: auto-config + - name: eth2 + vifs: + - vlan_id: 101 + ipv6: + - address: auto-config + state: replaced + + - name: Delete SLACC auto-config of given interfaces + register: result + vyos.vyos.vyos_l3_interfaces: + config: + - name: eth1 + - name: eth2 + state: deleted + + - name: Assert that the before dicts were correctly generated (SLAAC) + assert: + that: + - "{{ deleted['before_slaac'] | symmetric_difference(result['before']) |length == 0 }}" + + - name: Assert that the correct set of commands were generated (SLAAC) + assert: + that: + - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that the after dicts were correctly generated (SLAAC) + assert: + that: + - "{{ deleted['after'] | symmetric_difference(result['after']) |length == 0 }}" + always: - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/gathered.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/gathered.yaml index 41a53d87..0a3db05b 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/gathered.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/gathered.yaml @@ -1,28 +1,60 @@ --- - debug: msg: START vyos_l3_interfaces gathered 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_l3_interfaces: &id001 config: state: gathered - name: Assert that gathered dicts was correctly generated assert: that: - "{{ populate | symmetric_difference(result['gathered']) |length == 0 }}" - name: Gather the existing running configuration (IDEMPOTENT) register: result vyos.vyos.vyos_l3_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - result['changed'] == false + + - name: Merge the provided configuration for SLAAC tesitng + register: result + vyos.vyos.vyos_l3_interfaces: + config: + - name: eth1 + vifs: + - vlan_id: 102 + ipv6: + - address: auto-config + state: merged + + - name: Gather the provided configuration with the existing running configuration + register: result + vyos.vyos.vyos_l3_interfaces: &id002 + config: + state: gathered + + - name: Assert that gathered dicts was correctly generated for SLAAC + assert: + that: + - "{{ populate_slaac | symmetric_difference(result['gathered']) |length == 0 }}" + + - name: Gather the existing running configuration for SLAAC (IDEMPOTENT) + register: result + vyos.vyos.vyos_l3_interfaces: *id002 + + - 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_l3_interfaces/tests/cli/merged.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/merged.yaml index 4ec4d0f2..fcb5e896 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/merged.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/merged.yaml @@ -1,57 +1,61 @@ --- - debug: msg: START vyos_l3_interfaces merged integration tests on connection={{ ansible_connection }} - include_tasks: _remove_config.yaml - block: - name: Merge the provided configuration with the existing running configuration register: result vyos.vyos.vyos_l3_interfaces: &id001 config: - name: eth1 ipv4: - address: 192.0.2.10/24 ipv6: - address: 2001:db8::10/32 + vifs: + - vlan_id: 102 + ipv6: + - address: auto-config - name: eth2 ipv4: - address: 198.51.100.10/24 vifs: - vlan_id: 101 ipv4: - address: 198.51.100.130/25 ipv6: - address: 2001:db8::20/32 state: merged - name: Assert that before dicts were correctly generated assert: that: "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}" - name: Assert that correct set of commands were generated assert: that: - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" - name: Assert that after dicts was correctly generated assert: that: - "{{ merged['after'] | symmetric_difference(result['after']) |length == 0 }}" - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) register: result vyos.vyos.vyos_l3_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - result['changed'] == false - name: Assert that before dicts were correctly generated assert: that: - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}" always: - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/overridden.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/overridden.yaml index 8334a610..240d01ac 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/overridden.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/overridden.yaml @@ -1,50 +1,58 @@ --- - debug: msg: START vyos_l3_interfaces merged integration tests on connection={{ ansible_connection }} - include_tasks: _populate.yaml - block: - name: Overrides all device configuration with provided configuration register: result vyos.vyos.vyos_l3_interfaces: &id001 config: - name: eth0 ipv4: - address: dhcp - name: eth1 ipv4: - address: 192.0.2.15/24 + vifs: + - vlan_id: 102 + ipv6: + - address: auto-config + + - name: eth2 + ipv6: + - address: auto-config state: overridden - name: Assert that before dicts were correctly generated assert: that: - "{{ populate | symmetric_difference(result['before']) |length == 0 }}" - name: Assert that correct commands were generated assert: that: - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" - name: Assert that after dicts were correctly generated assert: that: - "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}" - name: Overrides all device configuration with provided configurations (IDEMPOTENT) register: result vyos.vyos.vyos_l3_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - result['changed'] == false - name: Assert that before dicts were correctly generated assert: that: - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}" always: - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/rendered.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/rendered.yaml index 199879f4..9f5de20a 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/rendered.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/rendered.yaml @@ -1,38 +1,48 @@ --- - debug: msg: START vyos_l3_interfaces rendered integration tests on connection={{ ansible_connection }} - include_tasks: _populate.yaml - block: - name: Structure provided configuration into device specific commands register: result vyos.vyos.vyos_l3_interfaces: &id001 config: - name: eth1 ipv4: - address: 192.0.2.14/24 + vifs: + - vlan_id: 102 + ipv6: + - address: auto-config - name: eth2 ipv4: - address: 192.0.2.10/24 - address: 192.0.2.11/24 ipv6: - address: 2001:db8::10/32 - address: 2001:db8::12/32 + vifs: + - vlan_id: 101 + ipv4: + - address: 198.51.100.130/25 + ipv6: + - address: 2001:db8::20/32 state: rendered - name: Assert that correct set of commands were generated assert: that: - "{{ rendered['commands'] | symmetric_difference(result['rendered']) |length == 0 }}" - name: Structure provided configuration into device specific commands (IDEMPOTENT) register: result vyos.vyos.vyos_l3_interfaces: *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_l3_interfaces/tests/cli/replaced.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/replaced.yaml index 502175fc..0715172d 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/replaced.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/replaced.yaml @@ -1,50 +1,94 @@ --- - debug: msg: START vyos_l3_interfaces replaced integration tests on connection={{ ansible_connection }} - include_tasks: _populate.yaml - block: - name: Replace device configurations of listed interfaces with provided configurations register: result vyos.vyos.vyos_l3_interfaces: &id001 config: - name: eth1 ipv4: - address: 192.0.2.19/24 - name: eth2 ipv6: - address: 2001:db8::11/32 state: replaced - name: Assert that correct set of commands were generated assert: that: - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" - name: Assert that before dicts are correctly generated assert: that: - "{{ populate | symmetric_difference(result['before']) |length == 0 }}" - name: Assert that after dict is correctly generated assert: that: - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}" - name: Replace device configurations of listed interfaces with provided configurarions (IDEMPOTENT) register: result vyos.vyos.vyos_l3_interfaces: *id001 - name: Assert that task was idempotent assert: that: - result['changed'] == false - name: Assert that before dict is correctly generated assert: that: - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}" + + - name: Replace device configurations (autoconf) + register: result + vyos.vyos.vyos_l3_interfaces: &id002 + config: + - name: eth2 + ipv6: + - address: auto-config + - name: eth1 + vifs: + - vlan_id: 102 + ipv6: + - address: auto-config + state: replaced + + - name: Assert that correct set of commands were generated (autoconf) + assert: + that: + - "{{ replaced['af_commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that before dict is correctly generated (autoconf) + assert: + that: + - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}" + + - name: Assert that after dict is correctly generated + assert: + that: + - "{{ replaced['af_after'] | symmetric_difference(result['after']) |length == 0 }}" + + - name: Replace device autoconf configurations (IDEMPOTENT) + register: result + vyos.vyos.vyos_l3_interfaces: *id002 + + - name: Assert that task was idempotent (autoconf) + assert: + that: + - result['changed'] == false + + - name: Assert that before dict is correctly generated (autoconf) + assert: + that: + - "{{ replaced['af_after'] | symmetric_difference(result['before']) |length == 0 }}" + always: - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/vars/main.yaml b/tests/integration/targets/vyos_l3_interfaces/vars/main.yaml index e9781e6a..84f1c637 100644 --- a/tests/integration/targets/vyos_l3_interfaces/vars/main.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/vars/main.yaml @@ -1,118 +1,184 @@ --- merged: before: - name: eth0 ipv4: - address: dhcp - name: eth1 - name: eth2 commands: - set interfaces ethernet eth1 address '192.0.2.10/24' - set interfaces ethernet eth1 address '2001:db8::10/32' + - set interfaces ethernet eth1 vif 102 ipv6 address 'autoconf' - set interfaces ethernet eth2 address '198.51.100.10/24' - set interfaces ethernet eth2 vif 101 address '198.51.100.130/25' - set interfaces ethernet eth2 vif 101 address '2001:db8::20/32' after: - - name: eth0 - ipv4: - - address: dhcp - - name: eth1 - ipv4: - - address: 192.0.2.10/24 - ipv6: - - address: 2001:db8::10/32 - - name: eth2 - ipv4: + - ipv4: - address: 198.51.100.10/24 + name: eth2 vifs: - - vlan_id: 101 - ipv4: + - ipv4: - address: 198.51.100.130/25 ipv6: - address: 2001:db8::20/32 + vlan_id: 101 + - ipv4: + - address: dhcp + name: eth0 + - ipv4: + - address: 192.0.2.10/24 + ipv6: + - address: 2001:db8::10/32 + name: eth1 + vifs: + - ipv6: + - address: auto-config + vlan_id: 102 populate: - name: eth1 ipv4: - address: 192.0.2.14/24 - name: eth2 ipv4: - address: 192.0.2.10/24 - address: 192.0.2.11/24 ipv6: - address: 2001:db8::10/32 - address: 2001:db8::12/32 - name: eth0 ipv4: - address: dhcp + +populate_slaac: + - name: eth1 + ipv4: + - address: 192.0.2.14/24 + vifs: + - vlan_id: 102 + ipv6: + - address: auto-config + - name: eth2 + ipv4: + - address: 192.0.2.10/24 + - address: 192.0.2.11/24 + ipv6: + - address: 2001:db8::10/32 + - address: 2001:db8::12/32 + - name: eth0 + ipv4: + - address: dhcp replaced: commands: - delete interfaces ethernet eth2 address '192.0.2.10/24' - delete interfaces ethernet eth2 address '192.0.2.11/24' - delete interfaces ethernet eth2 address '2001:db8::10/32' - delete interfaces ethernet eth2 address '2001:db8::12/32' - set interfaces ethernet eth2 address '2001:db8::11/32' - delete interfaces ethernet eth1 address '192.0.2.14/24' - set interfaces ethernet eth1 address '192.0.2.19/24' + af_commands: + - delete interfaces ethernet eth2 address '2001:db8::11/32' + - set interfaces ethernet eth2 ipv6 address 'autoconf' + - delete interfaces ethernet eth1 address '192.0.2.19/24' + - set interfaces ethernet eth1 vif 102 ipv6 address 'autoconf' after: - name: eth2 ipv6: - address: 2001:db8::11/32 - name: eth1 ipv4: - address: 192.0.2.19/24 - name: eth0 ipv4: - address: dhcp + af_after: + - name: eth2 + ipv6: + - address: auto-config + - name: eth1 + vifs: + - vlan_id: 102 + ipv6: + - address: auto-config + - name: eth0 + ipv4: + - address: dhcp overridden: commands: - delete interfaces ethernet eth1 address '192.0.2.14/24' - set interfaces ethernet eth1 address '192.0.2.15/24' - - delete interfaces ethernet eth2 address '192.0.2.10/24' + - set interfaces ethernet eth1 vif 102 ipv6 address 'autoconf' - delete interfaces ethernet eth2 address '192.0.2.11/24' - - delete interfaces ethernet eth2 address '2001:db8::10/32' + - delete interfaces ethernet eth2 address '192.0.2.10/24' - delete interfaces ethernet eth2 address '2001:db8::12/32' + - delete interfaces ethernet eth2 address '2001:db8::10/32' + - set interfaces ethernet eth2 ipv6 address 'autoconf' after: - name: eth0 ipv4: - address: dhcp - name: eth1 ipv4: - address: 192.0.2.15/24 + vifs: + - vlan_id: 102 + ipv6: + - address: auto-config - name: eth2 + ipv6: + - address: auto-config parsed: after: - name: eth1 ipv4: - address: 192.0.2.10/24 ipv6: - address: 2001:db8::10/32 + vifs: + - vlan_id: 102 + ipv6: + - address: auto-config - name: eth2 ipv4: - address: 198.51.100.10/24 vifs: - vlan_id: 101 ipv4: - address: 198.51.100.130/25 ipv6: - address: 2001:db8::20/32 rendered: commands: - set interfaces ethernet eth1 address '192.0.2.14/24' + - set interfaces ethernet eth1 vif 102 ipv6 address 'autoconf' - set interfaces ethernet eth2 address '192.0.2.11/24' - set interfaces ethernet eth2 address '192.0.2.10/24' - - set interfaces ethernet eth2 address '2001:db8::10/32' - set interfaces ethernet eth2 address '2001:db8::12/32' + - set interfaces ethernet eth2 address '2001:db8::10/32' + - set interfaces ethernet eth2 vif 101 address '198.51.100.130/25' + - set interfaces ethernet eth2 vif 101 address '2001:db8::20/32' deleted: commands: - - delete interfaces ethernet eth1 address '192.0.2.14/24' - - delete interfaces ethernet eth2 address '192.0.2.10/24' - - delete interfaces ethernet eth2 address '192.0.2.11/24' - - delete interfaces ethernet eth2 address '2001:db8::10/32' - - delete interfaces ethernet eth2 address '2001:db8::12/32' + - delete interfaces ethernet eth1 + - delete interfaces ethernet eth2 + commands_slaac: + - delete interfaces ethernet eth1 ipv6 address 'autoconf' + - delete interfaces ethernet eth2 vif 101 ipv6 address 'autoconf' after: - name: eth0 ipv4: - address: dhcp + before_slaac: + - name: eth0 + ipv4: + - address: dhcp - name: eth1 + ipv6: + - address: auto-config - name: eth2 + vifs: + - vlan_id: 101 + ipv6: + - address: auto-config diff --git a/tests/sanity/ignore-2.20.txt.bak b/tests/sanity/ignore-2.20.txt.bak new file mode 100644 index 00000000..b2139bc6 --- /dev/null +++ b/tests/sanity/ignore-2.20.txt.bak @@ -0,0 +1,2 @@ +plugins/action/vyos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +* ansible-bad-import-from