summaryrefslogtreecommitdiffstats
path: root/ansible_collections/cisco/iosxr/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 16:03:42 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 16:03:42 +0000
commit66cec45960ce1d9c794e9399de15c138acb18aed (patch)
tree59cd19d69e9d56b7989b080da7c20ef1a3fe2a5a /ansible_collections/cisco/iosxr/tests
parentInitial commit. (diff)
downloadansible-66cec45960ce1d9c794e9399de15c138acb18aed.tar.xz
ansible-66cec45960ce1d9c794e9399de15c138acb18aed.zip
Adding upstream version 7.3.0+dfsg.upstream/7.3.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/cisco/iosxr/tests')
-rw-r--r--ansible_collections/cisco/iosxr/tests/.gitignore1
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/target-prefixes.network1
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/_populate.yaml16
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/_remove_config.yaml27
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/deleted.yaml31
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/deleted_all.yaml44
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/fixtures/parsed.cfg14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/gathered.yaml53
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/merged.yaml110
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/overridden.yaml63
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/rendered.yaml38
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/replaced.yaml51
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/rtt.yaml95
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/vars/main.yaml172
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/_populate_config.yaml10
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/_remove_config.yaml9
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/deleted.yaml87
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/fixtures/parsed.cfg8
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/gathered.yaml19
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/merged.yaml165
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/overridden.yaml66
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/rendered.yaml93
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/replaced.yaml66
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/rtt.yaml84
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/vars/main.yaml317
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/meta/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tasks/main.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tasks/netconf.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/cli/basic-login.yaml37
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/cli/basic-motd.yaml37
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/cli/basic-no-login.yaml35
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/netconf/basic-login.yaml37
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/netconf/basic-motd.yaml37
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/netconf/basic-no-login.yaml34
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/meta/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/tasks/cli.yaml19
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/tests/cli/basic.yaml239
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/defaults/main.yaml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/meta/main.yaml0
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tasks/cli.yaml21
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_parsed.cfg10
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_base_vrf.yaml15
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_config.yaml16
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_config1.yaml17
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_vrf.yaml16
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_remove_config.yaml8
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/deleted.yaml64
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/empty_config.yaml50
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/gathered.yaml31
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/merged.yaml90
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/overridden.yaml44
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/rendered.yaml46
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/replaced.yaml86
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/vars/main.yaml99
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/defaults/main.yml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/meta/main.yml0
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tasks/cli.yaml21
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_parsed.cfg19
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_populate_af.yml15
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_populate_config.yaml23
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_populate_vrf.yaml16
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_remove_config.yaml8
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_replaced_af.yaml0
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/deleted.yaml39
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/deleted_af.yaml25
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/deleted_af_with_vrf.yaml25
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/empty_config.yaml50
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/gathered.yaml22
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/merged.yaml61
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/purged.yaml41
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/rendered.yaml43
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/replaced.yaml64
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/replaced_af.yaml40
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/vars/main.yaml94
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/defaults/main.yaml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/meta/main.yaml0
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tasks/cli.yaml21
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_parsed.cfg26
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_base_config.yaml23
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_config.yaml27
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_vrf_base_config.yaml25
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_vrf_config.yaml26
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_remove_config.yaml10
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_route_policy.cfg6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/deleted.yaml71
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/empty_config.yaml50
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/gathered.yaml24
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/merged.yaml138
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/overridden.yaml45
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/rendered.yaml54
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/replaced.yaml105
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/vars/main.yml145
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/defaults/main.yml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/meta/main.yml0
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/tasks/cli.yaml21
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/tests/common/commit_conf.yaml33
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/vars/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/defaults/main.yaml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/meta/main.yml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tasks/cli.yaml21
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/bad_operator.yaml19
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/cli_command.yaml45
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/contains.yaml19
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/invalid.yaml32
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/output.yaml28
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/prompt.yaml26
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/timeout.yaml18
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/fixtures/config_add_interface.txt42
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/fixtures/config_del_interface.txt36
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/meta/main.yml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/cli_config.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/main.yaml10
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/redirection.yaml18
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/change_prefix_set.j25
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/config.j23
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/configuration.j23
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/init_prefix_set.j23
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/route_policy.j2121
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/route_policy_change.j268
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/route_policy_clean.j232
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/defaults/config.j23
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/backup.yaml69
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/comment-too-long.yaml26
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/comment.yaml76
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/commit_confirmed.yaml35
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/commit_label.yaml70
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/extcommunity_set_config.yaml26
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/misplaced_sublevel.yaml27
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/prefix_set_remark.yaml28
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/replace_config.yaml40
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/route_policy.yaml53
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/src_basic.yaml33
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/src_invalid.yaml16
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/src_match_none.yaml34
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel.yaml43
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_block.yaml59
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_exact.yaml63
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_strict.yaml65
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_strict_mul_parents.yaml73
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel.yaml37
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel_after.yaml44
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel_before.yaml44
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel_nonidempotent.yaml42
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli_config/cli_backup.yaml59
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli_config/cli_basic.yaml28
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/redirection/shortname.yaml27
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/meta/main.yml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/all_facts.yaml33
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/default_facts.yaml22
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/invalid_subset.yaml32
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/not_hardware.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/defaults/main.yml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/meta/main.yml0
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tasks/cli.yaml21
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/_parsed.cfg1
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/_populate_config.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/_remove_config.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/deleted.yaml27
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/gathered.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/merged.yaml33
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/rendered.yaml16
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/vars/main.yaml24
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/meta/main.yaml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_deleted.yaml38
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_overridden.yaml45
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_populate_config.yaml18
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_remove_config.yaml17
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/fixtures/parsed.cfg19
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/gathered.yaml38
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/merged.yaml99
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/rendered.yaml26
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/replaced.yaml46
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/vars/main.yaml231
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/meta/main.yaml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/_populate_config.yaml8
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/_remove_config.yaml8
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/deleted.yaml38
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/fixtures/parsed.cfg16
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/gathered.yaml35
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/merged.yaml46
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/overridden.yaml47
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/rendered.yaml24
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/replaced.yaml43
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/vars/main.yaml107
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/meta/main.yaml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/_populate_config.yaml8
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/_remove_config.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/deleted.yaml42
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/fixtures/parsed.cfg31
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/gathered.yaml35
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/merged.yaml49
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/overridden.yaml44
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/rendered.yaml26
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/replaced.yaml45
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/rtt.yaml39
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/vars/main.yaml133
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/_populate.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/_remove_config.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/deleted.yaml43
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/empty_config.yaml47
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/fixtures/parsed.cfg2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/gathered.yaml27
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/merged.yaml45
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/rendered.yaml18
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/replaced.yaml46
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/rtt.yaml50
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/vars/main.yaml44
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/_populate.yaml26
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/_remove_config.yaml27
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/deleted.yaml44
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/fixtures/parsed.cfg14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/gathered.yaml34
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/merged.yaml53
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/overridden.yaml52
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/rendered.yaml25
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/replaced.yaml50
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/rtt.yaml59
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/vars/main.yaml130
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/_populate_config.yaml25
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/_remove_config.yaml31
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/deleted.yaml44
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/fixtures/parsed.cfg30
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/gathered.yaml43
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/merged.yaml62
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/overridden.yaml56
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/rendered.yaml31
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/replaced.yaml53
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/rtt.yaml63
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/vars/main.yaml168
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/_populate.yaml9
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/_remove_config.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/deleted.yaml43
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/empty_config.yaml47
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/fixtures/parsed.cfg10
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/gathered.yaml31
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/merged.yaml48
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/rendered.yaml21
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/replaced.yaml49
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/rtt.yaml48
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/vars/main.yaml63
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/_populate.yaml12
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/_remove_config.yaml22
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/deleted.yaml44
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/fixtures/parsed.cfg16
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/gathered.yaml28
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/merged.yaml47
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/overridden.yaml47
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/rendered.yaml24
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/replaced.yaml47
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/rtt.yaml49
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/vars/main.yaml73
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/meta/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tasks/cli.yaml23
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tasks/main.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tasks/netconf.yaml23
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tests/cli/basic.yaml140
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tests/netconf/basic.yaml208
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/defaults/main.yml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/meta/main.yml0
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tasks/cli.yaml21
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/_parsed.cfg19
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/_populate_config.yaml23
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/_remove_config.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/deleted.yaml36
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/empty_config.yaml50
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/gathered.yaml22
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/merged.yaml63
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/overridden.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/rendered.yaml59
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/replaced.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/vars/main.yaml98
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/meta/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/tasks/cli.yaml18
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/tests/cli/basic.yaml65
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/defaults/main.yml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/meta/main.yml0
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tasks/cli.yaml21
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/_parsed.cfg29
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/_populate_config.yaml34
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/_remove_config.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/deleted.yaml36
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/empty_config.yaml50
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/gathered.yaml22
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/merged.yaml74
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/overridden.yaml76
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/rendered.yaml71
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/replaced.yaml79
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/vars/main.yaml136
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/fixtures/parsed.cfg51
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/_populate_config.yaml23
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/_remove_config.yaml7
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/deleted.yaml74
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/gathered.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/merged.yaml108
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/overridden.yaml57
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/parsed.yaml15
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/rendered.yaml46
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/replaced.yaml63
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/rtt.yaml74
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/vars/main.yaml138
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/fixtures/parsed.cfg42
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/_populate_config.yaml46
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/_remove_config.yaml7
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/deleted.yaml76
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/gathered.yaml18
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/merged.yaml124
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/overridden.yaml60
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/parsed.yaml13
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/rendered.yaml67
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/replaced.yaml60
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/rtt.yaml98
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/vars/main.yaml316
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/fixtures/parsed.cfg36
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/_populate_config.yaml38
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/_remove_config.yaml7
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/deleted.yaml76
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/gathered.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/merged.yaml112
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/overridden.yaml56
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/parsed.yaml15
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/rendered.yaml63
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/replaced.yaml56
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/rtt.yaml88
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/vars/main.yaml260
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/tests/cli/ping.yaml51
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/_populate_config.yaml22
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/_remove_config.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/deleted.yaml60
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/empty_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/fixtures/parsed.cfg7
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/gathered.yaml19
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/merged.yaml61
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/overridden.yaml55
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/rendered.yaml32
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/replaced.yaml54
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/rtt.yaml81
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/vars/main.yaml87
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/meta/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tasks/cli.yaml28
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tasks/main.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tasks/netconf.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tests/cli/caching.yaml127
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tests/cli/common_config.yaml105
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tests/netconf/common_netconf.yaml46
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/defaults/main.yml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/meta/main.yml0
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tasks/cli.yaml21
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/_parsed.cfg54
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/_populate_config.yaml59
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/_remove_config.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/deleted.yaml36
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/empty_config.yaml61
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/gathered.yaml22
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/merged.yaml130
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/overridden.yaml112
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/parsed.yaml14
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/rendered.yaml108
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/replaced.yaml114
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/vars/main.yaml249
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/fixtures/parsed.cfg18
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tasks/cli.yaml20
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tasks/main.yaml5
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/_populate_config.yaml58
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/_remove_config.yaml7
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/deleted.yaml68
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/empty_config.yaml47
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/gathered.yaml18
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/merged.yaml138
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/overridden.yaml65
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/parsed.yaml13
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/rendered.yaml75
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/replaced.yaml56
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/rtt.yaml73
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/vars/main.yaml264
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/defaults/main.yaml2
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/meta/main.yml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tasks/cli.yaml23
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tasks/main.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tasks/netconf.yaml21
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_domain_list.yaml111
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_domain_name.yaml32
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_hostname.yaml32
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_lookup_source.yaml34
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_name_servers.yaml59
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_domain_list.yaml164
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_domain_name.yaml70
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_hostname.yaml39
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_lookup_source.yaml149
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_name_servers.yaml127
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/defaults/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/files/private30
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/files/public.pub1
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/files/public2.pub1
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/meta/main.yaml3
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tasks/cli.yaml34
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tasks/main.yaml6
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tasks/netconf.yaml32
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tests/cli/basic.yaml165
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tests/common/auth.yaml109
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tests/netconf/_basic.yaml177
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/prepare_iosxr_tests/tasks/main.yml17
-rw-r--r--ansible_collections/cisco/iosxr/tests/integration/targets/prepare_iosxr_tests/templates/config.j23
-rw-r--r--ansible_collections/cisco/iosxr/tests/sanity/ignore-2.10.txt30
-rw-r--r--ansible_collections/cisco/iosxr/tests/sanity/ignore-2.11.txt36
-rw-r--r--ansible_collections/cisco/iosxr/tests/sanity/ignore-2.12.txt39
-rw-r--r--ansible_collections/cisco/iosxr/tests/sanity/ignore-2.13.txt12
-rw-r--r--ansible_collections/cisco/iosxr/tests/sanity/ignore-2.14.txt12
-rw-r--r--ansible_collections/cisco/iosxr/tests/sanity/ignore-2.15.txt12
-rw-r--r--ansible_collections/cisco/iosxr/tests/sanity/ignore-2.9.txt32
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/__init__.py0
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/compat/__init__.py0
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/compat/builtins.py35
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/compat/mock.py129
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/compat/unittest.py41
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/mock/__init__.py0
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/mock/loader.py117
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/mock/path.py13
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/mock/procenv.py97
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/mock/vault_helper.py44
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/mock/yaml_helper.py177
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/__init__.py0
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/conftest.py34
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/__init__.py0
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/__init__.py0
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/__init__.py0
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf/iosxr/show_running-config_hostname1
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf/iosxr/show_version__utility_head_-n_2017
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf_ncs540/iosxr/show_running-config_hostname1
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf_ncs540/iosxr/show_version__utility_head_-n_2015
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/dir_7all6
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_acl_interfaces_config.cfg11
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_acls_config.cfg8
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_banner_config.cfg2
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_config_config.cfg12
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_config_src.cfg11
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_interface_config.cfg9
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_l2_interface_config.cfg9
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_l3_interface_config.cfg6
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lacp_config.cfg2
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lacp_interfaces_config.cfg11
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lag_interface_config.cfg24
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lldp_global_config.cfg10
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lldp_interfaces_config.cfg16
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_ospf_interfaces.cfg8
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_ospfv2.cfg8
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_ospfv3.cfg8
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_static_routes_config.cfg18
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_system_config.cfg8
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_user_config.cfg8
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_interfaces41
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_ipv6_interface5
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_lldp1
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_lldp_neighbors_detail1
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_memory_summary5
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_running-config43
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_version84
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_version___utility_head_-n_2018
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_version_brief18
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/iosxr_module.py108
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_hostname.py114
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr.py97
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_acl_interfaces.py329
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_acls.py496
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_banner.py117
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_bgp_address_family.py384
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_bgp_global.py493
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_bgp_neighbor_address_family.py826
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_command.py128
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_config.py313
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_facts.py120
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_interfaces.py288
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_l2_interfaces.py246
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_l3_interfaces.py255
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lacp.py93
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lacp_interfaces.py263
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lag_interfaces.py375
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lldp_global.py206
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lldp_interfaces.py206
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_logging_global.py1263
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_n540.py96
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_netconf.py115
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ntp_global.py902
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ospf_interfaces.py359
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ospfv2.py277
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ospfv3.py271
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ping.py180
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_prefix_lists.py442
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_snmp_server.py3612
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_static_routes.py380
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_system.py123
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_user.py131
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_utils.py28
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/modules/utils.py55
-rw-r--r--ansible_collections/cisco/iosxr/tests/unit/requirements.txt42
591 files changed, 34739 insertions, 0 deletions
diff --git a/ansible_collections/cisco/iosxr/tests/.gitignore b/ansible_collections/cisco/iosxr/tests/.gitignore
new file mode 100644
index 00000000..ea1472ec
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/.gitignore
@@ -0,0 +1 @@
+output/
diff --git a/ansible_collections/cisco/iosxr/tests/integration/target-prefixes.network b/ansible_collections/cisco/iosxr/tests/integration/target-prefixes.network
new file mode 100644
index 00000000..c61a1902
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/target-prefixes.network
@@ -0,0 +1 @@
+iosxr
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/_populate.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/_populate.yaml
new file mode 100644
index 00000000..968b356d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/_populate.yaml
@@ -0,0 +1,16 @@
+---
+- name: Populate the device with acls
+ cisco.iosxr.iosxr_config:
+ lines:
+ "ipv4 access-list acl_1\n10 permit ipv4 any any\nipv4 access-list acl_2\n10 permit ipv4 any any\nipv4 access-list acl_3\n10 permit ipv4 any any\nipv6 access-list\
+ \ acl6_1\n10 permit ipv6 any any\nipv6 access-list acl6_2\n10 permit ipv6 any any\nipv6 access-list acl6_3\n10 permit ipv6 any any\n"
+
+- name: Setup ACL interfaces configuration for gigabitethernet0/0/0/0
+ cisco.iosxr.iosxr_config:
+ lines: "ipv4 access-group acl_1 ingress\nipv4 access-group acl_2 egress\nipv6 access-group acl6_1 ingress\nipv6 access-group acl6_2 egress\n"
+ parents: interface GigabitEthernet0/0/0/0
+
+- name: Setup ACL interfaces configuration for gigabitethernet0/0/0/1
+ cisco.iosxr.iosxr_config:
+ lines: ipv4 access-group acl_1 egress
+ parents: interface GigabitEthernet0/0/0/1
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..b86f3d84
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/_remove_config.yaml
@@ -0,0 +1,27 @@
+---
+- name: Remove/default resources
+ vars:
+ lines:
+ "default interface GigabitEthernet0/0/0/0\ndefault interface GigabitEthernet0/0/0/1\nno ipv4 access-list acl_1\nno ipv4 access-list acl_2\nno ipv6 access-list\
+ \ acl6_1\nno ipv6 access-list acl6_2\nno ipv6 access-list acl6_3\n"
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
+
+- name: Initialize interfaces
+ loop:
+ - interface GigabitEthernet0/0/0/0
+ - interface GigabitEthernet0/0/0/1
+ cisco.iosxr.iosxr_config:
+ lines: shutdown
+ parents: "{{ item }}"
+
+- name: Remove unwanted interfaces from configuration
+ loop:
+ - 0/0/0/2
+ - 0/0/0/3
+ - 0/0/0/4
+ - 0/0/0/5
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no interface GigabitEthernet{{ item }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/deleted.yaml
new file mode 100644
index 00000000..5dfe512b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/deleted.yaml
@@ -0,0 +1,31 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_acl_interfaces deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Delete ACL attributes of gigabitethernet0/0/0/1
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/1
+ state: deleted
+
+ - ansible.builtin.assert:
+ that:
+ - "'interface GigabitEthernet0/0/0/1' in result.commands"
+ - "'no ipv4 access-group acl_1 egress' in result.commands"
+ - result.commands|length == 2
+
+ - name: Delete ACL attributes of gigabitethernet0/0/0/1 (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces: *id001
+ - ansible.builtin.assert:
+ that:
+ - result.changed == False
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/deleted_all.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/deleted_all.yaml
new file mode 100644
index 00000000..16f5195a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/deleted_all.yaml
@@ -0,0 +1,44 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_acl_interfaces deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Delete all ACL interfaces configuration from the device
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces: &id001
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Delete ACL attributes of all interfaces (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands|length == 0
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..24723a9d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acl_interfaces empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_acl_interfaces:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_acl_interfaces:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_acl_interfaces:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_acl_interfaces:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_acl_interfaces:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/fixtures/parsed.cfg
new file mode 100644
index 00000000..f2f4eea7
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/fixtures/parsed.cfg
@@ -0,0 +1,14 @@
+interface MgmtEth0/RP0/CPU0/0
+ ipv4 address dhcp
+!
+interface GigabitEthernet0/0/0/0
+ shutdown
+ ipv4 access-group acl_1 ingress
+ ipv4 access-group acl_2 egress
+ ipv6 access-group acl6_1 ingress
+ ipv6 access-group acl6_2 egress
+!
+interface GigabitEthernet0/0/0/1
+ shutdown
+ ipv4 access-group acl_1 egress
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/gathered.yaml
new file mode 100644
index 00000000..aaa2982d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/gathered.yaml
@@ -0,0 +1,53 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acl_interfaces gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- name: Populate the device with acls
+ cisco.iosxr.iosxr_config:
+ lines:
+ "ipv4 access-list acl_1\n10 permit ipv4 any any\nipv4 access-list acl_2\n10 permit ipv4 any any\nipv6 access-list acl6_1\n10 permit ipv6 any any\nipv6\
+ \ access-list acl6_2\n10 permit ipv6 any any\n"
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ access_groups:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ direction: in
+
+ - name: acl_2
+ direction: out
+
+ - afi: ipv6
+ acls:
+ - name: acl6_1
+ direction: in
+
+ - name: acl6_2
+ direction: out
+
+ - name: GigabitEthernet0/0/0/1
+ access_groups:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ direction: out
+ state: merged
+
+ - name: Gather ACL interfaces facts using gathered state
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces:
+ state: gathered
+
+ - name: Assert that facts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['after'] | symmetric_difference(result['gathered']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/merged.yaml
new file mode 100644
index 00000000..5d2708a3
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/merged.yaml
@@ -0,0 +1,110 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acl_interfaces merged integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- name: Populate the device with acls
+ cisco.iosxr.iosxr_config:
+ lines:
+ "ipv4 access-list acl_1\n10 permit ipv4 any any\nipv4 access-list acl_2\n10 permit ipv4 any any\nipv6 access-list acl6_1\n10 permit ipv6 any any\nipv6\
+ \ access-list acl6_2\n10 permit ipv6 any any\n"
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+ access_groups:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ direction: in
+
+ - name: acl_2
+ direction: out
+
+ - afi: ipv6
+ acls:
+ - name: acl6_1
+ direction: in
+
+ - name: acl6_2
+ direction: out
+
+ - name: GigabitEthernet0/0/0/1
+ access_groups:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ direction: out
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Update acl_interfaces configuration using merged
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces: &id002
+ config:
+ - name: GigabitEthernet0/0/0/1
+ access_groups:
+ - afi: ipv4
+ acls:
+ - name: acl_2
+ direction: out
+
+ - name: acl_1
+ direction: in
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['update_before'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['update_commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['update_after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Update acl_interfaces configuration using merged (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/overridden.yaml
new file mode 100644
index 00000000..80dac14c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/overridden.yaml
@@ -0,0 +1,63 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acl_interfaces overridden integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Overridde all interface ACL configuration with provided configuration
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+ access_groups:
+ - afi: ipv6
+ acls:
+ - name: acl6_3
+ direction: in
+
+ - name: GigabitEthernet0/0/0/1
+ access_groups:
+ - afi: ipv4
+ acls:
+ - name: acl_2
+ direction: in
+
+ - afi: ipv6
+ acls:
+ - name: acl6_3
+ direction: out
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Overridde all interface ACL configuration with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/parsed.yaml
new file mode 100644
index 00000000..7e091090
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acl_interfaces parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided ACL interfaces configuration to agnostic model
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces:
+ running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['parsed']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/rendered.yaml
new file mode 100644
index 00000000..7d84155f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/rendered.yaml
@@ -0,0 +1,38 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acl_interfaces rendered integration tests on connection={{ ansible_connection }}
+
+- name: Render platform specific commands from task input using rendered state
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ access_groups:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ direction: in
+
+ - name: acl_2
+ direction: out
+
+ - afi: ipv6
+ acls:
+ - name: acl6_1
+ direction: in
+
+ - name: acl6_2
+ direction: out
+
+ - name: GigabitEthernet0/0/0/1
+ access_groups:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ direction: out
+ state: rendered
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/replaced.yaml
new file mode 100644
index 00000000..dc480ce5
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/replaced.yaml
@@ -0,0 +1,51 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acl_interfaces replaced integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Replace device configurations of listed interface with provided configurations
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+ access_groups:
+ - afi: ipv6
+ acls:
+ - name: acl6_3
+ direction: in
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Replace device configurations of listed interfaces with provided configurarions (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/rtt.yaml
new file mode 100644
index 00000000..a87c7df6
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/tests/cli/rtt.yaml
@@ -0,0 +1,95 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acl_interfaces round trip integration tests on connection={{ ansible_connection }}
+
+- block:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+ - name: Populate the device with acls
+ cisco.iosxr.iosxr_config:
+ lines:
+ "ipv4 access-list acl_1\n10 permit ipv4 any any\nipv4 access-list acl_2\n10 permit ipv4 any any\nipv4 access-list acl_3\n10 permit ipv4 any any\nipv6\
+ \ access-list acl6_1\n10 permit ipv6 any any\nipv6 access-list acl6_2\n10 permit ipv6 any any\nipv6 access-list acl6_3\n10 permit ipv6 any any\n"
+
+ - name: Apply the provided configuration (base config)
+ cisco.iosxr.iosxr_acl_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ access_groups:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ direction: in
+
+ - name: acl_2
+ direction: out
+
+ - afi: ipv6
+ acls:
+ - name: acl6_1
+ direction: in
+
+ - name: acl6_2
+ direction: out
+
+ - name: GigabitEthernet0/0/0/1
+ access_groups:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ direction: out
+ state: merged
+
+ - name: Gather interfaces facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - acl_interfaces
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ cisco.iosxr.iosxr_acl_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/1
+ access_groups:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ direction: in
+
+ - name: acl_2
+ direction: out
+
+ - afi: ipv6
+ acls:
+ - name: acl6_1
+ direction: in
+
+ - name: acl6_2
+ direction: out
+
+ - name: GigabitEthernet0/0/0/0
+ access_groups:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ direction: out
+ state: overridden
+
+ - name: Assert that changes were applied
+ ansible.builtin.assert:
+ that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Revert back to base configuration using facts round trip
+ register: revert
+ cisco.iosxr.iosxr_acl_interfaces:
+ config: "{{ ansible_facts['network_resources']['acl_interfaces'] }}"
+ state: overridden
+
+ - name: Assert that configuration was reverted
+ ansible.builtin.assert:
+ that: "{{ merged['after'] | symmetric_difference(revert['after']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/vars/main.yaml
new file mode 100644
index 00000000..f5f138d8
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acl_interfaces/vars/main.yaml
@@ -0,0 +1,172 @@
+---
+merged:
+ before:
+ - name: MgmtEth0/RP0/CPU0/0
+ - name: GigabitEthernet0/0/0/0
+ - name: GigabitEthernet0/0/0/1
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - ipv4 access-group acl_1 ingress
+ - ipv4 access-group acl_2 egress
+ - ipv6 access-group acl6_1 ingress
+ - ipv6 access-group acl6_2 egress
+ - interface GigabitEthernet0/0/0/1
+ - ipv4 access-group acl_1 egress
+ update_commands:
+ - interface GigabitEthernet0/0/0/1
+ - ipv4 access-group acl_2 egress
+ - ipv4 access-group acl_1 ingress
+ after:
+ - name: MgmtEth0/RP0/CPU0/0
+ - name: GigabitEthernet0/0/0/0
+ access_groups:
+ - acls:
+ - name: acl_1
+ direction: in
+ - name: acl_2
+ direction: out
+ afi: ipv4
+ - acls:
+ - name: acl6_1
+ direction: in
+ - name: acl6_2
+ direction: out
+ afi: ipv6
+ - name: GigabitEthernet0/0/0/1
+ access_groups:
+ - acls:
+ - name: acl_1
+ direction: out
+ afi: ipv4
+ update_before:
+ - name: MgmtEth0/RP0/CPU0/0
+ - access_groups:
+ - acls:
+ - direction: in
+ name: acl_1
+ - direction: out
+ name: acl_2
+ afi: ipv4
+ - acls:
+ - direction: in
+ name: acl6_1
+ - direction: out
+ name: acl6_2
+ afi: ipv6
+ name: GigabitEthernet0/0/0/0
+ - access_groups:
+ - acls:
+ - direction: out
+ name: acl_1
+ afi: ipv4
+ name: GigabitEthernet0/0/0/1
+ update_after:
+ - name: MgmtEth0/RP0/CPU0/0
+ - access_groups:
+ - acls:
+ - direction: in
+ name: acl_1
+ - direction: out
+ name: acl_2
+ afi: ipv4
+ - acls:
+ - direction: in
+ name: acl6_1
+ - direction: out
+ name: acl6_2
+ afi: ipv6
+ name: GigabitEthernet0/0/0/0
+ - access_groups:
+ - acls:
+ - direction: in
+ name: acl_1
+ - direction: out
+ name: acl_2
+ afi: ipv4
+ name: GigabitEthernet0/0/0/1
+replaced:
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - no ipv4 access-group acl_1 ingress
+ - no ipv4 access-group acl_2 egress
+ - no ipv6 access-group acl6_2 egress
+ - ipv6 access-group acl6_3 ingress
+ after:
+ - name: MgmtEth0/RP0/CPU0/0
+ - name: GigabitEthernet0/0/0/0
+ access_groups:
+ - afi: ipv6
+ acls:
+ - name: acl6_3
+ direction: in
+ - name: GigabitEthernet0/0/0/1
+ access_groups:
+ - acls:
+ - name: acl_1
+ direction: out
+ afi: ipv4
+overridden:
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - no ipv4 access-group acl_1 ingress
+ - no ipv4 access-group acl_2 egress
+ - no ipv6 access-group acl6_2 egress
+ - ipv6 access-group acl6_3 ingress
+ - interface GigabitEthernet0/0/0/1
+ - no ipv4 access-group acl_1 egress
+ - ipv4 access-group acl_2 ingress
+ - ipv6 access-group acl6_3 egress
+ after:
+ - name: MgmtEth0/RP0/CPU0/0
+ - name: GigabitEthernet0/0/0/0
+ access_groups:
+ - afi: ipv6
+ acls:
+ - name: acl6_3
+ direction: in
+ - name: GigabitEthernet0/0/0/1
+ access_groups:
+ - acls:
+ - name: acl_2
+ direction: in
+ afi: ipv4
+ - acls:
+ - name: acl6_3
+ direction: out
+ afi: ipv6
+deleted:
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - no ipv4 access-group acl_1 ingress
+ - no ipv4 access-group acl_2 egress
+ - no ipv6 access-group acl6_1 ingress
+ - no ipv6 access-group acl6_2 egress
+ - interface GigabitEthernet0/0/0/1
+ - no ipv4 access-group acl_1 egress
+ after:
+ - name: MgmtEth0/RP0/CPU0/0
+ - name: GigabitEthernet0/0/0/0
+ - name: GigabitEthernet0/0/0/1
+round_trip:
+ after:
+ - name: MgmtEth0/RP0/CPU0/0
+ - access_groups:
+ - acls:
+ - direction: out
+ name: acl_1
+ afi: ipv4
+ name: GigabitEthernet0/0/0/0
+ - access_groups:
+ - acls:
+ - direction: in
+ name: acl_1
+ - direction: out
+ name: acl_2
+ afi: ipv4
+ - acls:
+ - direction: in
+ name: acl6_1
+ - direction: out
+ name: acl6_2
+ afi: ipv6
+ name: GigabitEthernet0/0/0/1
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/_populate_config.yaml
new file mode 100644
index 00000000..423b8f2b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/_populate_config.yaml
@@ -0,0 +1,10 @@
+---
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ lines:
+ "ipv6 access-list acl6_1\n10 deny tcp 2001:db8:1234::/48 range ftp telnet\
+ \ any syn ttl range 180 250 authen routing log\n20 permit icmpv6 any any router-advertisement\
+ \ precedence network destopts\nipv4 access-list acl_1\n16 remark TEST_ACL_1_REMARK\n\
+ 21 permit tcp host 192.0.2.10 range pop3 121 198.51.100.0 0.0.0.15 rst\n23\
+ \ deny icmp any 198.51.100.0 0.0.0.15 reassembly-timeout dscp lt af12\nipv4\
+ \ access-list acl_2\n10 remark TEST_ACL_2_REMARK"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..2585c995
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/_remove_config.yaml
@@ -0,0 +1,9 @@
+---
+- name: Remove acls
+ vars:
+ lines:
+ "no ipv4 access-list acl_1\nno ipv4 access-list acl_2\nno ipv4 access-list acl_3\nno ipv4 access-list acl_3\nno ipv6 access-list acl6_1\nno ipv6 access-list\
+ \ acl6_2\nno ipv6 access-list acl6_3\n"
+ ignore_errors: true
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/deleted.yaml
new file mode 100644
index 00000000..2c7c5ab4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/deleted.yaml
@@ -0,0 +1,87 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_lag_interfaces deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete a single ACL
+ register: result
+ cisco.iosxr.iosxr_acls: &id001
+ config:
+ - afi: ipv6
+ acls:
+ - name: acl6_1
+ state: deleted
+
+ - ansible.builtin.assert:
+ that:
+ - '"no ipv6 access-list acl6_1" in result.commands'
+ - result.commands|length == 1
+
+ - name: Delete a single ACL (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acls: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert: &id003
+ that:
+ - result.changed == false
+ - result.commands|length == 0
+
+ - name: Delete all acls under one AFI
+ register: result
+ cisco.iosxr.iosxr_acls: &id002
+ config:
+ - afi: ipv4
+ state: deleted
+
+ - ansible.builtin.assert:
+ that:
+ - '"no ipv4 access-list acl_1" in result.commands'
+ - '"no ipv4 access-list acl_2" in result.commands'
+ - result.commands|length == 2
+
+ - name: Delete all acls under one AFI (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acls: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert: *id003
+ - ansible.builtin.include_tasks: _populate_config.yaml
+
+ - name: Delete all acls from the device
+ register: result
+ cisco.iosxr.iosxr_acls: &id004
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Delete all acls from the device (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acls: *id004
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands|length == 0
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..ac6fa61b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acls empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_acls:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_acls:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_acls:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_acls:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_acls:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/fixtures/parsed.cfg
new file mode 100644
index 00000000..f1da89bb
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/fixtures/parsed.cfg
@@ -0,0 +1,8 @@
+ipv4 access-list acl_1
+ 10 remark TEST_ACL_2_REMARK
+ipv4 access-list acl_2
+ 11 deny tcp 2001:db8:1234::/48 range ftp telnet any syn ttl range 180 250 authen routing log
+ 21 permit icmpv6 any any router-advertisement precedence network packet-length eq 576 destopts
+ipv6 access-list acl6_1
+ 10 deny tcp 2001:db8:1234::/48 range ftp telnet any syn ttl range 180 250 routing authen log
+ 20 permit icmpv6 any any router-advertisement precedence network packet-length eq 576 destopts
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/gathered.yaml
new file mode 100644
index 00000000..7abdcc24
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/gathered.yaml
@@ -0,0 +1,19 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acls gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Gather ACL interfaces facts using gathered state
+ register: result
+ cisco.iosxr.iosxr_acls:
+ state: gathered
+
+ - name: Assert that facts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['after'] | symmetric_difference(result['gathered']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/merged.yaml
new file mode 100644
index 00000000..d1bfdfc0
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/merged.yaml
@@ -0,0 +1,165 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acls merged integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_acls: &id001
+ config:
+ - afi: ipv6
+ acls:
+ - name: acl6_1
+ aces:
+ - sequence: 10
+ grant: deny
+ protocol: tcp
+ source:
+ prefix: 2001:db8:1234::/48
+ port_protocol:
+ range:
+ start: ftp
+ end: telnet
+ destination:
+ any: true
+ protocol_options:
+ tcp:
+ syn: true
+ ttl:
+ range:
+ start: 180
+ end: 250
+ routing: true
+ authen: true
+ log: true
+
+ - sequence: 20
+ grant: permit
+ protocol: icmpv6
+ source:
+ any: true
+ destination:
+ any: true
+ protocol_options:
+ icmpv6:
+ router_advertisement: true
+ precedence: network
+ destopts: true
+
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ aces:
+ - sequence: 16
+ remark: TEST_ACL_1_REMARK
+
+ - sequence: 21
+ grant: permit
+ protocol: tcp
+ source:
+ host: 192.0.2.10
+ port_protocol:
+ range:
+ start: pop3
+ end: 121
+ destination:
+ address: 198.51.100.0
+ wildcard_bits: 0.0.0.15
+ protocol_options:
+ tcp:
+ rst: true
+
+ - sequence: 23
+ grant: deny
+ protocol: icmp
+ source:
+ any: true
+ destination:
+ prefix: 198.51.100.0/28
+ protocol_options:
+ icmp:
+ reassembly_timeout: true
+ dscp:
+ lt: af12
+
+ - name: acl_2
+ aces:
+ - sequence: 10
+ remark: TEST_ACL_2_REMARK
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acls: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Update existing aces
+ register: result
+ cisco.iosxr.iosxr_acls: &id002
+ config:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ aces:
+ - sequence: 21
+ source:
+ prefix: 198.51.100.32/28
+ port_protocol:
+ range:
+ start: pop3
+ end: 121
+ protocol_options:
+ tcp:
+ syn: true
+
+ - sequence: 23
+ protocol_options:
+ icmp:
+ router_advertisement: true
+ dscp:
+ eq: af23
+ state: merged
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - '"ipv4 access-list acl_1" in result.commands'
+ - '"21 permit tcp 198.51.100.32 0.0.0.15 range pop3 121 198.51.100.0 0.0.0.15 syn" in result.commands'
+ - '"23 deny icmp any 198.51.100.0 0.0.0.15 router-advertisement dscp eq af23" in result.commands'
+ - result.commands|length == 3
+
+ - name: Update existing aces (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acls: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/overridden.yaml
new file mode 100644
index 00000000..c73c1ff5
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/overridden.yaml
@@ -0,0 +1,66 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acls overridden integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Overridde all acls configuration with provided configuration
+ register: result
+ cisco.iosxr.iosxr_acls: &id001
+ config:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ aces:
+ - sequence: 10
+ grant: permit
+ source:
+ any: true
+ destination:
+ any: true
+ protocol: tcp
+
+ - name: acl_2
+ aces:
+ - sequence: 20
+ grant: permit
+ source:
+ any: true
+ destination:
+ any: true
+ protocol: igmp
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Overridde all interface lag interface configuration with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acls: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/parsed.yaml
new file mode 100644
index 00000000..ce3bbfe4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acls parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided ACL configuration to agnostic model
+ register: result
+ cisco.iosxr.iosxr_acls:
+ running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - "{{ parsed | symmetric_difference(result['parsed']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/rendered.yaml
new file mode 100644
index 00000000..559de6c0
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/rendered.yaml
@@ -0,0 +1,93 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acls rendered integration tests on connection={{ ansible_connection }}
+
+- name: Render platform specific commands from task input using rendered state
+ register: result
+ cisco.iosxr.iosxr_acls:
+ config:
+ - afi: ipv6
+ acls:
+ - name: acl6_1
+ aces:
+ - sequence: 10
+ grant: deny
+ protocol: tcp
+ source:
+ prefix: 2001:db8:1234::/48
+ port_protocol:
+ range:
+ start: ftp
+ end: telnet
+ destination:
+ any: true
+ protocol_options:
+ tcp:
+ syn: true
+ ttl:
+ range:
+ start: 180
+ end: 250
+ routing: true
+ authen: true
+ log: true
+
+ - sequence: 20
+ grant: permit
+ protocol: icmpv6
+ source:
+ any: true
+ destination:
+ any: true
+ protocol_options:
+ icmpv6:
+ router_advertisement: true
+ precedence: network
+ destopts: true
+
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ aces:
+ - sequence: 16
+ remark: TEST_ACL_1_REMARK
+
+ - sequence: 21
+ grant: permit
+ protocol: tcp
+ source:
+ host: 192.0.2.10
+ port_protocol:
+ range:
+ start: pop3
+ end: 121
+ destination:
+ address: 198.51.100.0
+ wildcard_bits: 0.0.0.15
+ protocol_options:
+ tcp:
+ rst: true
+
+ - sequence: 23
+ grant: deny
+ protocol: icmp
+ source:
+ any: true
+ destination:
+ prefix: 198.51.100.0/28
+ protocol_options:
+ icmp:
+ reassembly_timeout: true
+ dscp:
+ lt: af12
+
+ - name: acl_2
+ aces:
+ - sequence: 10
+ remark: TEST_ACL_2_REMARK
+ state: rendered
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/replaced.yaml
new file mode 100644
index 00000000..14c1137a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/replaced.yaml
@@ -0,0 +1,66 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acl_interfaces replaced integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replace device configurations of listed ACL with provided configurations
+ register: result
+ cisco.iosxr.iosxr_acls: &id001
+ config:
+ - afi: ipv4
+ acls:
+ - name: acl_2
+ aces:
+ - sequence: 11
+ grant: permit
+ protocol: igmp
+ source:
+ host: 198.51.100.130
+ destination:
+ any: true
+ ttl:
+ eq: 100
+
+ - sequence: 12
+ grant: deny
+ source:
+ any: true
+ destination:
+ any: true
+ protocol: icmp
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Replace device configurations of listed interfaces with provided configurarions (idempotent)
+ register: result
+ cisco.iosxr.iosxr_acls: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/rtt.yaml
new file mode 100644
index 00000000..34e09675
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/tests/cli/rtt.yaml
@@ -0,0 +1,84 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_acls round trip integration tests on connection={{ ansible_connection }}
+
+- block:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+ - name: Apply the provided configuration (base config)
+ register: base_config
+ cisco.iosxr.iosxr_acls:
+ config:
+ - afi: ipv4
+ acls:
+ - name: acl_2
+ aces:
+ - sequence: 11
+ grant: permit
+ protocol: igmp
+ source:
+ host: 198.51.100.130
+ destination:
+ any: true
+ ttl:
+ eq: 100
+
+ - sequence: 12
+ grant: deny
+ source:
+ any: true
+ destination:
+ any: true
+ protocol: icmp
+ state: merged
+
+ - name: Gather interfaces facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - acls
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ cisco.iosxr.iosxr_acls:
+ config:
+ - afi: ipv4
+ acls:
+ - name: acl_1
+ aces:
+ - sequence: 10
+ grant: permit
+ source:
+ any: true
+ destination:
+ any: true
+ protocol: tcp
+
+ - name: acl_2
+ aces:
+ - sequence: 20
+ grant: permit
+ source:
+ any: true
+ destination:
+ any: true
+ protocol: igmp
+ state: overridden
+
+ - name: Assert that changes were applied
+ ansible.builtin.assert:
+ that: "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Revert back to base configuration using facts round trip
+ register: revert
+ cisco.iosxr.iosxr_acls:
+ config: "{{ ansible_facts['network_resources']['acls'] }}"
+ state: overridden
+
+ - name: Assert that configuration was reverted
+ ansible.builtin.assert:
+ that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/vars/main.yaml
new file mode 100644
index 00000000..41e4b0fc
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_acls/vars/main.yaml
@@ -0,0 +1,317 @@
+---
+merged:
+ before: []
+ commands:
+ - ipv6 access-list acl6_1
+ - 10 deny tcp 2001:db8:1234::/48 range ftp telnet any syn ttl range 180 250 authen
+ routing log
+ - 20 permit icmpv6 any any router-advertisement precedence network destopts
+ - ipv4 access-list acl_1
+ - 16 remark TEST_ACL_1_REMARK
+ - 21 permit tcp host 192.0.2.10 range pop3 121 198.51.100.0 0.0.0.15 rst
+ - 23 deny icmp any 198.51.100.0 0.0.0.15 reassembly-timeout dscp lt af12
+ - ipv4 access-list acl_2
+ - 10 remark TEST_ACL_2_REMARK
+ after:
+ - acls:
+ - aces:
+ - remark: TEST_ACL_1_REMARK
+ sequence: 16
+ - destination:
+ address: 198.51.100.0
+ wildcard_bits: 0.0.0.15
+ grant: permit
+ protocol: tcp
+ protocol_options:
+ tcp:
+ rst: true
+ sequence: 21
+ source:
+ host: 192.0.2.10
+ port_protocol:
+ range:
+ end: "121"
+ start: pop3
+ - destination:
+ address: 198.51.100.0
+ wildcard_bits: 0.0.0.15
+ dscp:
+ lt: af12
+ grant: deny
+ protocol: icmp
+ protocol_options:
+ icmp:
+ reassembly_timeout: true
+ sequence: 23
+ source:
+ any: true
+ name: acl_1
+ - aces:
+ - remark: TEST_ACL_2_REMARK
+ sequence: 10
+ name: acl_2
+ afi: ipv4
+ - acls:
+ - aces:
+ - authen: true
+ destination:
+ any: true
+ grant: deny
+ log: true
+ protocol: tcp
+ protocol_options:
+ tcp:
+ syn: true
+ routing: true
+ sequence: 10
+ source:
+ port_protocol:
+ range:
+ end: telnet
+ start: ftp
+ prefix: 2001:db8:1234::/48
+ ttl:
+ range:
+ end: 250
+ start: 180
+ - destination:
+ any: true
+ destopts: true
+ grant: permit
+ precedence: network
+ protocol: icmpv6
+ protocol_options:
+ icmpv6:
+ router_advertisement: true
+ sequence: 20
+ source:
+ any: true
+ name: acl6_1
+ afi: ipv6
+replaced:
+ commands:
+ - ipv4 access-list acl_2
+ - no 10
+ - 11 permit igmp host 198.51.100.130 any ttl eq 100
+ - 12 deny icmp any any
+ after:
+ - acls:
+ - aces:
+ - remark: TEST_ACL_1_REMARK
+ sequence: 16
+ - destination:
+ address: 198.51.100.0
+ wildcard_bits: 0.0.0.15
+ grant: permit
+ protocol: tcp
+ protocol_options:
+ tcp:
+ rst: true
+ sequence: 21
+ source:
+ host: 192.0.2.10
+ port_protocol:
+ range:
+ end: "121"
+ start: pop3
+ - destination:
+ address: 198.51.100.0
+ wildcard_bits: 0.0.0.15
+ dscp:
+ lt: af12
+ grant: deny
+ protocol: icmp
+ protocol_options:
+ icmp:
+ reassembly_timeout: true
+ sequence: 23
+ source:
+ any: true
+ name: acl_1
+ - aces:
+ - destination:
+ any: true
+ grant: permit
+ protocol: igmp
+ sequence: 11
+ source:
+ host: 198.51.100.130
+ ttl:
+ eq: 100
+ - destination:
+ any: true
+ grant: deny
+ protocol: icmp
+ sequence: 12
+ source:
+ any: true
+ name: acl_2
+ afi: ipv4
+ - acls:
+ - aces:
+ - authen: true
+ destination:
+ any: true
+ grant: deny
+ log: true
+ protocol: tcp
+ protocol_options:
+ tcp:
+ syn: true
+ routing: true
+ sequence: 10
+ source:
+ port_protocol:
+ range:
+ end: telnet
+ start: ftp
+ prefix: 2001:db8:1234::/48
+ ttl:
+ range:
+ end: 250
+ start: 180
+ - destination:
+ any: true
+ destopts: true
+ grant: permit
+ precedence: network
+ protocol: icmpv6
+ protocol_options:
+ icmpv6:
+ router_advertisement: true
+ sequence: 20
+ source:
+ any: true
+ name: acl6_1
+ afi: ipv6
+overridden:
+ commands:
+ - no ipv6 access-list acl6_1
+ - ipv4 access-list acl_1
+ - no 16
+ - no 21
+ - no 23
+ - 10 permit tcp any any
+ - ipv4 access-list acl_2
+ - no 10
+ - 20 permit igmp any any
+ after:
+ - acls:
+ - aces:
+ - destination:
+ any: true
+ grant: permit
+ protocol: tcp
+ sequence: 10
+ source:
+ any: true
+ name: acl_1
+ - aces:
+ - destination:
+ any: true
+ grant: permit
+ protocol: igmp
+ sequence: 20
+ source:
+ any: true
+ name: acl_2
+ afi: ipv4
+deleted:
+ commands:
+ - no ipv4 access-list acl_1
+ - no ipv4 access-list acl_2
+ - no ipv6 access-list acl6_1
+ after: []
+parsed:
+ - acls:
+ - aces:
+ - remark: TEST_ACL_2_REMARK
+ sequence: 10
+ name: acl_1
+ - aces:
+ - authen: true
+ destination:
+ any: true
+ grant: deny
+ log: true
+ protocol: tcp
+ protocol_options:
+ tcp:
+ syn: true
+ routing: true
+ sequence: 11
+ source:
+ port_protocol:
+ range:
+ end: telnet
+ start: ftp
+ prefix: 2001:db8:1234::/48
+ ttl:
+ range:
+ end: 250
+ start: 180
+ - destination:
+ any: true
+ destopts: true
+ grant: permit
+ packet_length:
+ eq: 576
+ precedence: network
+ protocol: icmpv6
+ protocol_options:
+ icmpv6:
+ router_advertisement: true
+ sequence: 21
+ source:
+ any: true
+ name: acl_2
+ afi: ipv4
+ - acls:
+ - aces:
+ - authen: true
+ destination:
+ any: true
+ grant: deny
+ log: true
+ protocol: tcp
+ protocol_options:
+ tcp:
+ syn: true
+ routing: true
+ sequence: 10
+ source:
+ port_protocol:
+ range:
+ end: telnet
+ start: ftp
+ prefix: 2001:db8:1234::/48
+ ttl:
+ range:
+ end: 250
+ start: 180
+ - destination:
+ any: true
+ destopts: true
+ grant: permit
+ packet_length:
+ eq: 576
+ precedence: network
+ protocol: icmpv6
+ protocol_options:
+ icmpv6:
+ router_advertisement: true
+ sequence: 20
+ source:
+ any: true
+ name: acl6_1
+ afi: ipv6
+round_trip:
+ after:
+ - members:
+ - member: GigabitEthernet0/0/0/8
+ mode: passive
+ - member: GigabitEthernet0/0/0/9
+ mode: active
+ name: Bundle-Ether10
+ - mode: active
+ name: Bundle-Ether11
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/defaults/main.yaml
new file mode 100644
index 00000000..9ef5ba51
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/meta/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/meta/main.yaml
new file mode 100644
index 00000000..be631e5d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_iosxr_tests
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tasks/cli.yaml
new file mode 100644
index 00000000..59a889b4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tasks/cli.yaml
@@ -0,0 +1,20 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/cli"
+ patterns: "{{ testcase }}.yaml"
+ 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
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tasks/main.yaml
new file mode 100644
index 00000000..419a6cde
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tasks/main.yaml
@@ -0,0 +1,6 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+
+- name: Include the netconf tasks
+ ansible.builtin.include_tasks: netconf.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tasks/netconf.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tasks/netconf.yaml
new file mode 100644
index 00000000..8ff2ae68
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tasks/netconf.yaml
@@ -0,0 +1,20 @@
+---
+- name: Collect all netconf test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/netconf"
+ patterns: "{{ testcase }}.yaml"
+ 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 cases (connection=ansible.netcommon.netconf)
+ ansible.builtin.include_tasks: "{{ test_case_to_run }}"
+ vars:
+ ansible_connection: ansible.netcommon.netconf
+ with_items: "{{ test_items }}"
+ loop_control:
+ loop_var: test_case_to_run
+ tags:
+ - netconf
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/cli/basic-login.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/cli/basic-login.yaml
new file mode 100644
index 00000000..6a15c6b6
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/cli/basic-login.yaml
@@ -0,0 +1,37 @@
+---
+- name: Pause for 1 min
+ ansible.builtin.pause:
+ minutes: 1
+
+- name: Setup - remove login
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ state: absent
+
+- name: Set login
+ register: result
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ text: "@this is my login banner\nthat has a multiline\nstring\n@"
+ state: present
+
+- ansible.builtin.debug:
+ msg: "{{ result }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'this is my login banner' in result.commands[0]"
+ - "'that has a multiline' in result.commands[0]"
+
+- name: Set login again (idempotent)
+ register: result
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ text: "@this is my login banner\nthat has a multiline\nstring\n@"
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands | length == 0
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/cli/basic-motd.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/cli/basic-motd.yaml
new file mode 100644
index 00000000..3117ad79
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/cli/basic-motd.yaml
@@ -0,0 +1,37 @@
+---
+- name: Pause for 1 min
+ ansible.builtin.pause:
+ minutes: 1
+
+- name: Setup - remove MOTD
+ cisco.iosxr.iosxr_banner:
+ banner: motd
+ state: absent
+
+- name: Set MOTD
+ register: result
+ cisco.iosxr.iosxr_banner:
+ banner: motd
+ text: "@this is my motd banner\nthat has a multiline\nstring\n@"
+ state: present
+
+- ansible.builtin.debug:
+ msg: "{{ result }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'this is my motd banner' in result.commands[0]"
+ - "'that has a multiline' in result.commands[0]"
+
+- name: Set MOTD again (idempotent)
+ register: result
+ cisco.iosxr.iosxr_banner:
+ banner: motd
+ text: "@this is my motd banner\nthat has a multiline\nstring\n@"
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands | length == 0
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/cli/basic-no-login.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/cli/basic-no-login.yaml
new file mode 100644
index 00000000..ce30de3f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/cli/basic-no-login.yaml
@@ -0,0 +1,35 @@
+---
+- name: Pause for 1 min
+ ansible.builtin.pause:
+ minutes: 1
+
+- name: Setup
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ text: "@Junk login banner\nover multiple lines\n@"
+ state: present
+
+- name: Remove login
+ register: result
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ state: absent
+
+- ansible.builtin.debug:
+ msg: "{{ result }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'no banner login' in result.commands[0]"
+
+- name: Remove login (idempotent)
+ register: result
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands | length == 0
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/netconf/basic-login.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/netconf/basic-login.yaml
new file mode 100644
index 00000000..f1262c45
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/netconf/basic-login.yaml
@@ -0,0 +1,37 @@
+---
+- name: Sleep for 30 seconds and continue with play
+ ansible.builtin.wait_for:
+ timeout: 30
+
+- name: Setup - remove login
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ state: absent
+
+- name: Set login
+ register: result
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ text: "@this is my login banner\nthat has a multiline\nstring\n@"
+ state: present
+
+- ansible.builtin.debug:
+ msg: "{{ result }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'this is my login banner' in result.xml"
+ - "'that has a multiline' in result.xml"
+
+- name: Set login again (idempotent)
+ register: result
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ text: "@this is my login banner\nthat has a multiline\nstring\n@"
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.xml | length == 0
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/netconf/basic-motd.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/netconf/basic-motd.yaml
new file mode 100644
index 00000000..6fe84dea
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/netconf/basic-motd.yaml
@@ -0,0 +1,37 @@
+---
+- name: Sleep for 30 seconds and continue with play
+ ansible.builtin.wait_for:
+ timeout: 30
+
+- name: Setup - remove MOTD
+ cisco.iosxr.iosxr_banner:
+ banner: motd
+ state: absent
+
+- name: Set MOTD
+ register: result
+ cisco.iosxr.iosxr_banner:
+ banner: motd
+ text: "@this is my motd banner\nthat has a multiline\nstring\n@"
+ state: present
+
+- ansible.builtin.debug:
+ msg: "{{ result }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'this is my motd banner' in result.xml"
+ - "'that has a multiline' in result.xml"
+
+- name: Set MOTD again (idempotent)
+ register: result
+ cisco.iosxr.iosxr_banner:
+ banner: motd
+ text: "@this is my motd banner\nthat has a multiline\nstring\n@"
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.xml | length == 0
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/netconf/basic-no-login.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/netconf/basic-no-login.yaml
new file mode 100644
index 00000000..9c2d06ed
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_banner/tests/netconf/basic-no-login.yaml
@@ -0,0 +1,34 @@
+---
+- name: Sleep for 30 seconds and continue with play
+ ansible.builtin.wait_for:
+ timeout: 30
+
+- name: Setup
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ text: "@Junk login banner\nover multiple lines\n@"
+ state: present
+
+- name: Remove login
+ register: result
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ state: absent
+- ansible.builtin.debug:
+ msg: "{{ result }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '''xc:operation="delete"'' in result.xml'
+
+- name: Remove login (idempotent)
+ register: result
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.xml | length == 0
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/defaults/main.yaml
new file mode 100644
index 00000000..9ef5ba51
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/meta/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/meta/main.yaml
new file mode 100644
index 00000000..be631e5d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_iosxr_tests
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/tasks/cli.yaml
new file mode 100644
index 00000000..29e7f60c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/tasks/cli.yaml
@@ -0,0 +1,19 @@
+---
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/tests/cli/basic.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/tests/cli/basic.yaml
new file mode 100644
index 00000000..608a4400
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp/tests/cli/basic.yaml
@@ -0,0 +1,239 @@
+---
+- ansible.builtin.debug: msg="START iosxr cli/iosxr_bgp.yaml on connection={{ ansible_connection }}"
+
+- name: Check ios-xr version
+ register: facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset: default
+
+- block:
+ - name: Clear existing BGP configuration
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp:
+ operation: delete
+
+ - name: Configure BGP with as 64496 and a router-id
+ register: result
+ cisco.iosxr.iosxr_bgp: &id001
+ operation: merge
+ config:
+ bgp_as: 64496
+ router_id: 192.0.2.2
+
+ - ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'router bgp 64496' in result.commands"
+ - "'bgp router-id 192.0.2.2' in result.commands"
+
+ - name: Configure BGP with as 64496 and a router-id (idempotent)
+ register: result
+ cisco.iosxr.iosxr_bgp: *id001
+ - ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+ - name: Configure BGP neighbors
+ register: result
+ cisco.iosxr.iosxr_bgp: &id002
+ operation: merge
+ config:
+ bgp_as: 64496
+ neighbors:
+ - neighbor: 192.0.2.10
+ remote_as: 64496
+ description: IBGP_NBR_1
+ advertisement_interval: 120
+ timers:
+ keepalive: 300
+ holdtime: 360
+
+ - neighbor: 192.0.2.15
+ remote_as: 64496
+ description: IBGP_NBR_2
+ tcp_mss: 1500
+
+ - ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'router bgp 64496' in result.commands"
+ - "'neighbor 192.0.2.10' in result.commands"
+ - "'remote-as 64496' in result.commands"
+ - "'description IBGP_NBR_1' in result.commands"
+ - "'timers 300 360' in result.commands"
+ - "'advertisement-interval 120' in result.commands"
+ - "'neighbor 192.0.2.15' in result.commands"
+ - "'remote-as 64496' in result.commands"
+ - "'description IBGP_NBR_2' in result.commands"
+ - "'tcp mss 1500' in result.commands"
+
+ - name: Configure BGP neighbors (idempotent)
+ register: result
+ cisco.iosxr.iosxr_bgp: *id002
+ - ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+ - name: Configure BGP neighbors with operation replace
+ register: result
+ cisco.iosxr.iosxr_bgp: &id003
+ operation: replace
+ config:
+ bgp_as: 64496
+ neighbors:
+ - neighbor: 192.0.2.15
+ remote_as: 64496
+ description: IBGP_NBR_2
+ tcp_mss: 1500
+
+ - neighbor: 203.0.113.10
+ remote_as: 64511
+ description: EBGP_NBR_1
+
+ - ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'neighbor 203.0.113.10' in result.commands"
+ - "'remote-as 64511' in result.commands"
+ - "'description EBGP_NBR_1' in result.commands"
+ - "'no neighbor 192.0.2.10' in result.commands"
+
+ - name: Configure BGP neighbors with operation replace (idempotent)
+ register: result
+ cisco.iosxr.iosxr_bgp: *id003
+ - ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+ - name: Create route-policy as prerequisite for BGP configuration
+ register: result
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no route-policy RMAP_1
+ - route-policy RMAP_1
+ - exit
+
+ - name: Configure networks under address family
+ register: result
+ cisco.iosxr.iosxr_bgp: &id004
+ operation: merge
+ config:
+ bgp_as: 64496
+ address_family:
+ - afi: ipv4
+ networks:
+ - prefix: 198.51.100.48
+ masklen: 28
+ route_map: RMAP_1
+
+ - prefix: 192.0.2.64
+ masklen: 27
+
+ - prefix: 203.0.113.160
+ masklen: 27
+
+ - afi: ipv4
+ safi: multicast
+ networks:
+ - prefix: 198.51.100.64
+ masklen: 28
+
+ - ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'router bgp 64496' in result.commands"
+ - "'address-family ipv4 unicast' in result.commands"
+ - "'network 198.51.100.48/28 route-policy RMAP_1' in result.commands"
+ - "'network 192.0.2.64/27' in result.commands"
+ - "'network 203.0.113.160/27' in result.commands"
+ - "'address-family ipv4 multicast' in result.commands"
+ - "'network 198.51.100.64/28' in result.commands"
+
+ - name: Configure networks under address family (idempotent)
+ register: result
+ cisco.iosxr.iosxr_bgp: *id004
+ - ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+ - name: Configure networks under address family with operation replace
+ register: result
+ cisco.iosxr.iosxr_bgp: &id005
+ operation: replace
+ config:
+ bgp_as: 64496
+ address_family:
+ - afi: ipv4
+ safi: unicast
+ networks:
+ - prefix: 198.51.100.80
+ masklen: 28
+
+ - prefix: 192.0.2.64
+ masklen: 27
+
+ - prefix: 203.0.113.192
+ masklen: 27
+
+ - afi: ipv4
+ safi: multicast
+ networks:
+ - prefix: 198.51.100.64
+ masklen: 28
+
+ - ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"router bgp 64496" in result.commands'
+ - '"address-family ipv4 unicast" in result.commands'
+ - '"network 198.51.100.80/28" in result.commands'
+ - '"network 203.0.113.192/27" in result.commands'
+ - '"no network 198.51.100.48/28" in result.commands'
+ - '"no network 203.0.113.160/27" in result.commands'
+
+ - name: Configure networks under address family with operation replace (idempotent)
+ register: result
+ cisco.iosxr.iosxr_bgp: *id005
+ - ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+ - name: Override all the existing BGP configuration
+ register: result
+ cisco.iosxr.iosxr_bgp:
+ operation: override
+ config:
+ bgp_as: 64497
+ router_id: 192.0.2.10
+ log_neighbor_changes: true
+
+ - ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'router bgp 64497' in result.commands"
+ - "'bgp router-id 192.0.2.10' in result.commands"
+ - "'bgp log neighbor changes detail' in result.commands"
+
+ - name: Teardown
+ register: result
+ cisco.iosxr.iosxr_bgp: &id006
+ operation: delete
+
+ - ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'no router bgp 64497' in result.commands"
+
+ - name: Teardown again (idempotent)
+ register: result
+ cisco.iosxr.iosxr_bgp: *id006
+ - ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+ - name: Delete route-policy configures as prerequisite for BGP configuration (teardown)
+ cisco.iosxr.iosxr_config:
+ lines: no route-policy RMAP_1
+ when: facts['ansible_facts']['ansible_net_version'].split('[')[0] == '6.1.3'
+
+- ansible.builtin.debug: msg="END iosxr cli/iosxr_bgp.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/defaults/main.yaml
new file mode 100644
index 00000000..871ea460
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/defaults/main.yaml
@@ -0,0 +1,2 @@
+---
+testcase: "[^_].*"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/meta/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/meta/main.yaml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/meta/main.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tasks/cli.yaml
new file mode 100644
index 00000000..a1b57ab4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tasks/cli.yaml
@@ -0,0 +1,21 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/common"
+ 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
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tasks/main.yaml
new file mode 100644
index 00000000..f75f2f03
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_parsed.cfg
new file mode 100644
index 00000000..7de77196
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_parsed.cfg
@@ -0,0 +1,10 @@
+router bgp 65536
+ address-family ipv4 unicast
+ bgp attribute-download
+ advertise best-external
+ dynamic-med interval 10
+ bgp scan-time 20
+ redistribute application test1 metric 10
+ allocate-label all
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_base_vrf.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_base_vrf.yaml
new file mode 100644
index 00000000..626e0fee
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_base_vrf.yaml
@@ -0,0 +1,15 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "address-family ipv4 unicast"
+ - "address-family vpnv4 unicast"
+ - "bgp router-id 10.0.0.1"
+ - "vrf vrf1"
+ - " rd auto"
+ - "vrf vrf2"
+ - " rd auto"
+ parents: "router bgp 65536"
+
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_config.yaml
new file mode 100644
index 00000000..f83b5aa7
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_config.yaml
@@ -0,0 +1,16 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "address-family ipv4 unicast"
+ - " bgp attribute-download"
+ - " advertise best-external"
+ - " dynamic-med interval 10"
+ - " redistribute connected metric 10"
+ - " redistribute isis test3 metric 4"
+ - " redistribute application test1 metric 10"
+ - " allocate-label all"
+ parents: "router bgp 65536"
+
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_config1.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_config1.yaml
new file mode 100644
index 00000000..f44b0af6
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_config1.yaml
@@ -0,0 +1,17 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "address-family ipv4 unicast"
+ - " bgp attribute-download"
+ - " advertise best-external"
+ - " dynamic-med interval 10"
+ - " redistribute connected metric 10"
+ - " redistribute isis test3 metric 4"
+ - " redistribute application test1 metric 10"
+ - " allocate-label all"
+ - "address-family ipv4 mvpn"
+ parents: "router bgp 65536"
+
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_vrf.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_vrf.yaml
new file mode 100644
index 00000000..71292b54
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_populate_vrf.yaml
@@ -0,0 +1,16 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "vrf vrf1"
+ - " address-family ipv4 unicast"
+ - " redistribute connected metric 10"
+ - " dynamic-med interval 9"
+ - "vrf vrf2"
+ - " address-family ipv4 unicast"
+ - " redistribute connected metric 10"
+ - " dynamic-med interval 10"
+ parents: "router bgp 65536"
+
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_remove_config.yaml
new file mode 100644
index 00000000..812cd1bd
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/_remove_config.yaml
@@ -0,0 +1,8 @@
+---
+- name: Remove pre-existing BGP configurations
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no router bgp 65536
+ ignore_errors: true
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/deleted.yaml
new file mode 100644
index 00000000..90039f6f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/deleted.yaml
@@ -0,0 +1,64 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_address_family deleted integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete given bgp_address_family configuration
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_address_family: &deleted
+ config:
+ state: deleted
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 2
+ - result.changed == true
+ - "'no router bgp 65536' not in result.commands"
+ - result.after == deleted.after
+
+ - name: Idempotency check
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_address_family: *deleted
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 0
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_address_family deleted integration tests with multiple afs connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _populate_base_vrf.yaml
+
+- ansible.builtin.include_tasks: _populate_vrf.yaml
+
+- block:
+ - name: Deleted given bgp_address_family configuration
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_address_family:
+ config:
+ as_number: "65536"
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ vrf: vrf1
+ dynamic_med: 9
+ state: deleted
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 3
+ - result.changed == true
+ - "'no router bgp 65536' not in result.commands"
+ - deleted['vrf']['commands'] == result['commands']
+
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/empty_config.yaml
new file mode 100644
index 00000000..4ab7f8fb
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/empty_config.yaml
@@ -0,0 +1,50 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_bgp_address_family empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp_address_family:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp_address_family:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp_address_family:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp_address_family:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
+
+- ansible.builtin.debug:
+ msg: END nxos_bgp_global empty_config integration tests on connection={{ ansible_connection }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/gathered.yaml
new file mode 100644
index 00000000..81afdcca
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/gathered.yaml
@@ -0,0 +1,31 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_bgp_address_family gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "address-family ipv4 unicast"
+ - " bgp attribute-download"
+ - " advertise best-external"
+ - " dynamic-med interval 10"
+ - " redistribute application test1 metric 10"
+ - " allocate-label all"
+ parents: "router bgp 65536"
+
+ - name: Gathered the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_bgp_address_family:
+ config:
+ state: gathered
+
+ - name: Assert that facts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ gathered['after']['address_family'] | symmetric_difference(result['gathered']['address_family']) |length == 0 }}"
+ - gathered['after']['as_number'] == result['gathered']['as_number']
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/merged.yaml
new file mode 100644
index 00000000..0ffa6e4b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/merged.yaml
@@ -0,0 +1,90 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_address-family merged integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ cisco.iosxr.iosxr_bgp_address_family: &id001
+ config:
+ as_number: "65536"
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ dynamic_med: 10
+ redistribute:
+ - protocol: application
+ id: test1
+ metric: 10
+ bgp:
+ scan_time: 20
+ attribute_download: true
+ advertise_best_external: true
+ allocate_label:
+ all: true
+
+ register: result
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ result['before'] == {} }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['after']
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ cisco.iosxr.iosxr_bgp_address_family: *id001
+ register: result
+
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_address-family merged integration tests for af under vrf connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _populate_base_vrf.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration(vrf)
+ cisco.iosxr.iosxr_bgp_address_family: &id002
+ config:
+ as_number: "65536"
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ vrf: vrf1
+ dynamic_med: 9
+ redistribute:
+ - protocol: connected
+ metric: 10
+
+ register: result
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['vrf']['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ cisco.iosxr.iosxr_bgp_address_family: *id002
+ register: result
+
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+- ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/overridden.yaml
new file mode 100644
index 00000000..482b2859
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/overridden.yaml
@@ -0,0 +1,44 @@
+---
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config1.yaml
+
+- block:
+ - name: Override given bgp_address_family configuration
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_address_family: &overridden
+ config:
+ as_number: "65536"
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ dynamic_med: 4
+ redistribute:
+ - protocol: application
+ id: test1
+ metric: 10
+ - protocol: connected
+ metric: 10
+ - protocol: isis
+ id: test3
+ metric: 4
+ state: overridden
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 7
+ - result.changed == true
+ - "'no router bgp 65536' not in result.commands"
+ - overridden['commands'] == result['commands']
+
+ - name: Idempotency check
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_address_family: *overridden
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 0
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/parsed.yaml
new file mode 100644
index 00000000..2f0d5b5c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_bgp_address_family parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided BGP configuration
+ register: result
+ cisco.iosxr.iosxr_bgp_address_family:
+ running_config: "{{ lookup('file', './_parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['parsed']}}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/rendered.yaml
new file mode 100644
index 00000000..1f412d09
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/rendered.yaml
@@ -0,0 +1,46 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_bgp_global rendered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- name: Render platform specific configuration lines with state rendered (without connecting to the device)
+ cisco.iosxr.iosxr_bgp_address_family:
+ config:
+ as_number: "65536"
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ dynamic_med: 10
+ redistribute:
+ - protocol: application
+ id: test1
+ metric: 10
+ - protocol: connected
+ metric: 10
+ - protocol: isis
+ id: test3
+ metric: 4
+ bgp:
+ scan_time: 20
+ attribute_download: true
+ advertise_best_external: true
+ allocate_label:
+ all: true
+ state: rendered
+ register: result
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - rendered['commands'] == result['rendered']
+
+- name: Gather BGP facts
+ cisco.iosxr.iosxr_bgp_address_family:
+ state: gathered
+ register: result
+
+- name: Ensure that no configuration changes were made
+ ansible.builtin.assert:
+ that:
+ - result.gathered == {}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/replaced.yaml
new file mode 100644
index 00000000..f30405e7
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/tests/common/replaced.yaml
@@ -0,0 +1,86 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_address-family replaced integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config1.yaml
+
+- block:
+ - name: Replaced given bgp_address_family configuration
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_address_family: &replaced
+ config:
+ as_number: "65536"
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ dynamic_med: 4
+ redistribute:
+ - protocol: application
+ id: test1
+ metric: 10
+ - protocol: connected
+ metric: 10
+ - protocol: isis
+ id: test3
+ metric: 4
+ state: replaced
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 6
+ - result.changed == true
+ - "'no router bgp 65536' not in result.commands"
+ - replaced['commands'] == result['commands']
+
+ - name: Idempotency check
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_address_family: *replaced
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 0
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_address-family replaced integration tests(VRF) connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _populate_base_vrf.yaml
+
+- ansible.builtin.include_tasks: _populate_vrf.yaml
+
+- block:
+ - name: Replaced given bgp_address_family configuration
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_address_family: &replaced1
+ config:
+ as_number: "65536"
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ vrf: vrf1
+ dynamic_med: 8
+ state: replaced
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 5
+ - result.changed == true
+ - "'no router bgp 65536' not in result.commands"
+ - replaced['vrf']['commands'] == result['commands']
+
+ - name: Idempotency check
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_address_family: *replaced1
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 0
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/vars/main.yaml
new file mode 100644
index 00000000..1227d06b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_address_family/vars/main.yaml
@@ -0,0 +1,99 @@
+---
+merged:
+ commands:
+ - router bgp 65536
+ - address-family ipv4 unicast
+ - advertise best-external
+ - allocate-label all
+ - bgp attribute-download
+ - bgp scan-time 20
+ - dynamic-med interval 10
+ - redistribute application test1 metric 10
+ after:
+ as_number: "65536"
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ dynamic_med: 10
+ redistribute:
+ - protocol: application
+ id: "test1"
+ metric: 10
+ bgp:
+ scan_time: 20
+ attribute_download: true
+ advertise_best_external: true
+ allocate_label:
+ all: true
+ vrf:
+ commands:
+ - router bgp 65536
+ - vrf vrf1
+ - address-family ipv4 unicast
+ - dynamic-med interval 9
+ - redistribute connected metric 10
+
+deleted:
+ after:
+ as_number: "65536"
+ vrf:
+ commands:
+ - router bgp 65536
+ - vrf vrf1
+ - no address-family ipv4 unicast
+
+overridden:
+ commands:
+ - router bgp 65536
+ - address-family ipv4 unicast
+ - no advertise best-external
+ - no allocate-label all
+ - no bgp attribute-download
+ - dynamic-med interval 4
+ - no address-family ipv4 mvpn
+
+replaced:
+ commands:
+ - router bgp 65536
+ - address-family ipv4 unicast
+ - no advertise best-external
+ - no allocate-label all
+ - no bgp attribute-download
+ - dynamic-med interval 4
+
+ vrf:
+ commands:
+ - router bgp 65536
+ - vrf vrf1
+ - address-family ipv4 unicast
+ - dynamic-med interval 8
+ - no redistribute connected metric 10
+
+rendered:
+ commands:
+ - router bgp 65536
+ - address-family ipv4 unicast
+ - advertise best-external
+ - allocate-label all
+ - bgp attribute-download
+ - bgp scan-time 20
+ - dynamic-med interval 10
+ - redistribute application test1 metric 10
+ - redistribute connected metric 10
+ - redistribute isis test3 metric 4
+gathered:
+ after:
+ as_number: "65536"
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ dynamic_med: 10
+ redistribute:
+ - protocol: application
+ id: "test1"
+ metric: 10
+ bgp:
+ attribute_download: true
+ advertise_best_external: true
+ allocate_label:
+ all: true
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/defaults/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/defaults/main.yml
new file mode 100644
index 00000000..871ea460
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+testcase: "[^_].*"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/meta/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/meta/main.yml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/meta/main.yml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tasks/cli.yaml
new file mode 100644
index 00000000..1b019a5a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tasks/cli.yaml
@@ -0,0 +1,21 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/common"
+ 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)
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+ ansible.builtin.include_tasks: "{{ test_case_to_run }}"
+ with_items: "{{ test_items }}"
+ loop_control:
+ loop_var: test_case_to_run
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tasks/main.yaml
new file mode 100644
index 00000000..f75f2f03
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_parsed.cfg
new file mode 100644
index 00000000..6e19cdb2
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_parsed.cfg
@@ -0,0 +1,19 @@
+router bgp 65536
+ bgp confederation identifier 4
+ bgp router-id 192.0.2.10
+ bgp cluster-id 5
+ default-metric 4
+ socket send-buffer-size 4098
+ bgp bestpath med confed
+ socket receive-buffer-size 514
+ neighbor 192.0.2.11
+ remote-as 65537
+ cluster-id 3
+ !
+ neighbor 192.0.2.14
+ remote-as 65538
+ bfd fast-detect strict-mode
+ bfd multiplier 6
+ bfd minimum-interval 20
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_populate_af.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_populate_af.yml
new file mode 100644
index 00000000..0265308a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_populate_af.yml
@@ -0,0 +1,15 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "bgp cluster-id 5"
+ - "address-family ipv4 unicast"
+ - "bgp router-id 192.0.2.10"
+ - " neighbor 192.0.2.11"
+ - " address-family ipv4 unicast"
+ - " next-hop-self"
+ - " remote-as 65537"
+ parents: "router bgp 65536"
+
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_populate_config.yaml
new file mode 100644
index 00000000..c164070b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_populate_config.yaml
@@ -0,0 +1,23 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "router bgp 65536"
+ - "bgp cluster-id 5"
+ - "bgp router-id 192.0.2.10"
+ - "bgp bestpath med confed"
+ - "bgp confederation identifier 4"
+ - "default-metric 4"
+ - "socket receive-buffer-size 514"
+ - "socket send-buffer-size 4098"
+ - "neighbor 192.0.2.11"
+ - "cluster-id 3"
+ - "remote-as 65537"
+ - "neighbor 192.0.2.14"
+ - "bfd fast-detect strict-mode"
+ - "bfd minimum-interval 20"
+ - "bfd multiplier 6"
+ - "remote-as 65538"
+
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_populate_vrf.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_populate_vrf.yaml
new file mode 100644
index 00000000..73dae4c1
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_populate_vrf.yaml
@@ -0,0 +1,16 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "bgp cluster-id 5"
+ - "address-family ipv4 unicast"
+ - "address-family vpnv4 unicast"
+ - "bgp router-id 192.0.2.10"
+ - " vrf vrf1"
+ - " rd auto"
+ - " address-family ipv4 unicast"
+
+ parents: "router bgp 65536"
+
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_remove_config.yaml
new file mode 100644
index 00000000..812cd1bd
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_remove_config.yaml
@@ -0,0 +1,8 @@
+---
+- name: Remove pre-existing BGP configurations
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no router bgp 65536
+ ignore_errors: true
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_replaced_af.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_replaced_af.yaml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/_replaced_af.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/deleted.yaml
new file mode 100644
index 00000000..f209a31b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/deleted.yaml
@@ -0,0 +1,39 @@
+---
+- ansible.builtin.debug:
+ msg: Start nxos_bgp_global deleted integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete given bgp_global configuration
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_global: &deleted
+ config:
+ as_number: "65536"
+ state: deleted
+
+ - become: true
+ cisco.iosxr.iosxr_facts:
+ gather_network_resources: bgp_global
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 10
+ - result.changed == true
+ - "'no router bgp 65536' not in result.commands"
+ - ansible_facts.network_resources.bgp_global == result.after
+ - result.after == deleted.after
+
+ - name: Idempotency check
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_global: *deleted
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 0
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/deleted_af.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/deleted_af.yaml
new file mode 100644
index 00000000..34a820ba
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/deleted_af.yaml
@@ -0,0 +1,25 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_global deleted_af integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_af.yml
+
+- block:
+ - name: Remove a neighbor having AF configurations (should fail)
+ cisco.iosxr.iosxr_bgp_global:
+ config:
+ as_number: "65536"
+ state: deleted
+ register: result
+ ignore_errors: true
+
+ - name: Assert that the task failed
+ ansible.builtin.assert:
+ that:
+ - result.failed == True
+ - "'Neighbor 192.0.2.11 has address-family configurations.' in result.msg"
+
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/deleted_af_with_vrf.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/deleted_af_with_vrf.yaml
new file mode 100644
index 00000000..30caebe2
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/deleted_af_with_vrf.yaml
@@ -0,0 +1,25 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_global deleted_af integration tests for vrfs connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_vrf.yaml
+
+- block:
+ - name: Remove a neighbor having AF configurations (should fail)
+ cisco.iosxr.iosxr_bgp_global:
+ config:
+ as_number: "65536"
+ state: deleted
+ register: result
+ ignore_errors: true
+
+ - name: Assert that the task failed
+ ansible.builtin.assert:
+ that:
+ - result.failed == True
+ - "'VRF vrf1 has address-family configurations.' in result.msg"
+
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/empty_config.yaml
new file mode 100644
index 00000000..bdd5e071
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/empty_config.yaml
@@ -0,0 +1,50 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_bgp_global empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp_global:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp_global:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp_global:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp_global:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
+
+- ansible.builtin.debug:
+ msg: END nxos_bgp_global empty_config integration tests on connection={{ ansible_connection }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/gathered.yaml
new file mode 100644
index 00000000..dfbc0d53
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/gathered.yaml
@@ -0,0 +1,22 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_bgp_global gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Gathered the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_bgp_global:
+ config:
+ state: gathered
+
+ - name: Assert
+ ansible.builtin.assert:
+ that:
+ - merged.after == result.gathered
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/merged.yaml
new file mode 100644
index 00000000..34f1a62b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/merged.yaml
@@ -0,0 +1,61 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_global merged integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ cisco.iosxr.iosxr_bgp_global: &id001
+ config:
+ as_number: 65536
+ default_metric: 4
+ socket:
+ receive_buffer_size: 514
+ send_buffer_size: 4098
+ bgp:
+ confederation:
+ identifier: 4
+ bestpath:
+ med:
+ confed: true
+ cluster_id: 5
+ router_id: 192.0.2.10
+ neighbors:
+ - neighbor: 192.0.2.11
+ remote_as: 65537
+ cluster_id: 3
+ - neighbor: 192.0.2.14
+ remote_as: 65538
+ bfd:
+ fast_detect:
+ strict_mode: true
+ multiplier: 6
+ minimum_interval: 20
+ register: result
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ result['before'] == {} }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['after']
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ cisco.iosxr.iosxr_bgp_global: *id001
+ register: result
+
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/parsed.yaml
new file mode 100644
index 00000000..7cd8e234
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_bgp_global parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided BGP configuration
+ register: result
+ cisco.iosxr.iosxr_bgp_global:
+ running_config: "{{ lookup('file', './_parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['parsed']
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/purged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/purged.yaml
new file mode 100644
index 00000000..dd3b9591
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/purged.yaml
@@ -0,0 +1,41 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_global purged integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete all BGP configuration from the device
+ cisco.iosxr.iosxr_bgp_global: &id001
+ state: purged
+ register: result
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['before']
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "'no router bgp 65536' in result.commands"
+ - result.commands|length == 1
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - result['after'] == {}
+
+ - name: Delete all BGP configuration from the device (idempotent)
+ register: result
+ cisco.iosxr.iosxr_bgp_global: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/rendered.yaml
new file mode 100644
index 00000000..f45236df
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/rendered.yaml
@@ -0,0 +1,43 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_bgp_global rendered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- name: Render platform specific configuration lines with state rendered (without connecting to the device)
+ cisco.iosxr.iosxr_bgp_global:
+ config:
+ as_number: 65536
+ default_metric: 4
+ socket:
+ receive_buffer_size: 514
+ send_buffer_size: 4098
+ bgp:
+ confederation:
+ identifier: 4
+ bestpath:
+ med:
+ confed: true
+ cluster_id: 5
+ router_id: 192.0.2.10
+ neighbors:
+ - neighbor: 192.0.2.11
+ remote_as: 65537
+ cluster_id: 3
+ state: rendered
+ register: result
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - rendered['commands'] == result['rendered']
+
+- name: Gather BGP facts
+ cisco.iosxr.iosxr_bgp_global:
+ state: gathered
+ register: result
+
+- name: Ensure that no configuration changes were made
+ ansible.builtin.assert:
+ that:
+ - result.gathered == {}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/replaced.yaml
new file mode 100644
index 00000000..b4f98180
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/replaced.yaml
@@ -0,0 +1,64 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_global replaced integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replace BGP configuration with provided configuration
+ cisco.iosxr.iosxr_bgp_global: &id001
+ config:
+ as_number: 65536
+ default_metric: 5
+ socket:
+ receive_buffer_size: 514
+ send_buffer_size: 4098
+ bgp:
+ bestpath:
+ med:
+ confed: true
+ cluster_id: 5
+ router_id: 192.0.2.10
+ neighbors:
+ - neighbor: 192.0.2.13
+ remote_as: 65538
+ bfd:
+ fast_detect:
+ set: true
+ multiplier: 6
+ minimum_interval: 20
+ state: replaced
+ register: result
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - replaced['after'] == result['after']
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['before']
+
+ - name: Replace device configurations of BGP global module (idempotent)
+ register: result
+ cisco.iosxr.iosxr_bgp_global: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - replaced['after'] == result['before']
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/replaced_af.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/replaced_af.yaml
new file mode 100644
index 00000000..6cb3f6fb
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/tests/common/replaced_af.yaml
@@ -0,0 +1,40 @@
+---
+- ansible.builtin.debug:
+ msg: Start nxos_bgp_global deleted_af integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_af.yml
+
+- block:
+ - name: Replace BGP configuration with provided configuration
+ cisco.iosxr.iosxr_bgp_global:
+ config:
+ as_number: 65536
+ default_metric: 5
+ socket:
+ receive_buffer_size: 514
+ send_buffer_size: 4098
+ bgp:
+ bestpath:
+ med:
+ confed: true
+ cluster_id: 5
+ router_id: 192.0.2.10
+ neighbors:
+ - neighbor: 192.0.2.13
+ remote_as: 65538
+ bfd:
+ fast_detect:
+ strict_mode: true
+ multiplier: 6
+ minimum_interval: 20
+ state: replaced
+ register: result
+ ignore_errors: true
+
+ - name: Assert that the task failed
+ ansible.builtin.assert:
+ that:
+ - result.failed == True
+ - "'Neighbor 192.0.2.11 has address-family configurations.' in result.msg"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/vars/main.yaml
new file mode 100644
index 00000000..ef656a41
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_global/vars/main.yaml
@@ -0,0 +1,94 @@
+---
+merged:
+ commands:
+ - router bgp 65536
+ - bgp cluster-id 5
+ - bgp router-id 192.0.2.10
+ - bgp bestpath med confed
+ - bgp confederation identifier 4
+ - default-metric 4
+ - socket receive-buffer-size 514
+ - socket send-buffer-size 4098
+ - neighbor 192.0.2.11
+ - cluster-id 3
+ - remote-as 65537
+ - neighbor 192.0.2.14
+ - bfd fast-detect strict-mode
+ - bfd minimum-interval 20
+ - bfd multiplier 6
+ - remote-as 65538
+ after:
+ as_number: "65536"
+ default_metric: 4
+ socket:
+ receive_buffer_size: 514
+ send_buffer_size: 4098
+ bgp:
+ confederation:
+ identifier: 4
+ bestpath:
+ med:
+ confed: true
+ cluster_id: "5"
+ router_id: "192.0.2.10"
+ neighbors:
+ - neighbor_address: 192.0.2.11
+ remote_as: 65537
+ cluster_id: "3"
+ - neighbor_address: "192.0.2.14"
+ remote_as: 65538
+ bfd:
+ fast_detect:
+ strict_mode: true
+ multiplier: 6
+ minimum_interval: 20
+
+deleted:
+ after:
+ as_number: "65536"
+
+replaced:
+ commands:
+ - router bgp 65536
+ - no bgp confederation identifier 4
+ - default-metric 5
+ - no neighbor 192.0.2.11
+ - no neighbor 192.0.2.14
+ - neighbor 192.0.2.13
+ - bfd fast-detect
+ - bfd minimum-interval 20
+ - bfd multiplier 6
+ - remote-as 65538
+ after:
+ as_number: "65536"
+ default_metric: 5
+ socket:
+ receive_buffer_size: 514
+ send_buffer_size: 4098
+ bgp:
+ bestpath:
+ med:
+ confed: true
+ cluster_id: "5"
+ router_id: "192.0.2.10"
+ neighbors:
+ - neighbor_address: "192.0.2.13"
+ remote_as: 65538
+ bfd:
+ fast_detect:
+ set: true
+ multiplier: 6
+ minimum_interval: 20
+rendered:
+ commands:
+ - router bgp 65536
+ - bgp cluster-id 5
+ - bgp router-id 192.0.2.10
+ - bgp bestpath med confed
+ - bgp confederation identifier 4
+ - default-metric 4
+ - socket receive-buffer-size 514
+ - socket send-buffer-size 4098
+ - neighbor 192.0.2.11
+ - cluster-id 3
+ - remote-as 65537
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/defaults/main.yaml
new file mode 100644
index 00000000..871ea460
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/defaults/main.yaml
@@ -0,0 +1,2 @@
+---
+testcase: "[^_].*"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/meta/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/meta/main.yaml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/meta/main.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tasks/cli.yaml
new file mode 100644
index 00000000..1b019a5a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tasks/cli.yaml
@@ -0,0 +1,21 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/common"
+ 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)
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+ ansible.builtin.include_tasks: "{{ test_case_to_run }}"
+ with_items: "{{ test_items }}"
+ loop_control:
+ loop_var: test_case_to_run
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tasks/main.yaml
new file mode 100644
index 00000000..f75f2f03
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_parsed.cfg
new file mode 100644
index 00000000..4e2b4c71
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_parsed.cfg
@@ -0,0 +1,26 @@
+router bgp 65536
+ address-family ipv4 unicast
+ !
+ neighbor 192.0.2.2
+ remote-as 5
+ address-family ipv4 unicast
+ origin-as validation disable
+ bestpath origin-as allow invalid
+ weight 5
+ send-community-ebgp
+ multipath
+ allowas-in 4
+ maximum-prefix 10 20 restart 10
+ as-override
+ capability orf prefix both
+ send-extended-community-ebgp
+ default-originate
+ next-hop-self
+ send-community-gshut-ebgp
+ soft-reconfiguration inbound always
+ send-multicast-attributes
+ route-policy test1 in
+ route-policy test1 out
+ !
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_base_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_base_config.yaml
new file mode 100644
index 00000000..606bcba7
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_base_config.yaml
@@ -0,0 +1,23 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "address-family ipv4 unicast"
+ - "address-family ipv6 unicast"
+ - "neighbor 192.0.2.2"
+ - " remote-as 65537"
+ parents: "router bgp 65536"
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+
+- name: "Setup route-policy test1 for referance"
+ cisco.iosxr.iosxr_config:
+ commands:
+ - route-policy test1
+ - end-policy
+
+- name: "Setup route-policy test2 for referance"
+ cisco.iosxr.iosxr_config:
+ commands:
+ - route-policy test2
+ - end-policy
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_config.yaml
new file mode 100644
index 00000000..c01eebb0
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_config.yaml
@@ -0,0 +1,27 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "neighbor 192.0.2.2"
+ - " address-family ipv4 unicast"
+ - " origin-as validation disable"
+ - " bestpath origin-as allow invalid"
+ - " weight 5"
+ - " send-community-ebgp"
+ - " multipath"
+ - " allowas-in 4"
+ - " maximum-prefix 10 20 restart 10"
+ - " as-override"
+ - " capability orf prefix both"
+ - " send-extended-community-ebgp"
+ - " default-originate"
+ - " next-hop-self"
+ - " send-community-gshut-ebgp"
+ - " soft-reconfiguration inbound always"
+ - " send-multicast-attributes"
+ - " route-policy test1 in"
+ - " route-policy test1 out"
+ parents: "router bgp 65536"
+
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_vrf_base_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_vrf_base_config.yaml
new file mode 100644
index 00000000..a54158ae
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_vrf_base_config.yaml
@@ -0,0 +1,25 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "bgp router-id 192.0.2.1"
+ - "address-family vpnv4 unicast"
+ - "address-family ipv4 unicast"
+ - "neighbor 192.0.2.2"
+ - " remote-as 65537"
+ - "neighbor 192.0.2.3"
+ - " remote-as 65538"
+ - "vrf vrf1"
+ - " rd auto"
+ - " address-family ipv4 unicast"
+ - " neighbor 192.0.2.4"
+ - " remote-as 65539"
+ - "vrf vrf2"
+ - " rd auto"
+ - " address-family ipv4 unicast"
+ - " neighbor 192.0.2.5"
+ - " remote-as 65540"
+ parents: "router bgp 65536"
+
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_vrf_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_vrf_config.yaml
new file mode 100644
index 00000000..a3fa9d72
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_populate_vrf_config.yaml
@@ -0,0 +1,26 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "neighbor 192.0.2.2"
+ - " address-family ipv4 unicast"
+ - " weight 5"
+ - "neighbor 192.0.2.3"
+ - " address-family ipv4 unicast"
+ - " bestpath origin-as allow invalid"
+ - " weight 4"
+ - "vrf vrf1"
+ - " neighbor 192.0.2.4"
+ - " address-family ipv4 unicast"
+ - " multipath"
+ - " capability orf prefix both"
+ - " default-originate"
+ - "vrf vrf2"
+ - " neighbor 192.0.2.5"
+ - " address-family ipv4 unicast"
+ - " multipath"
+ - " capability orf prefix both"
+ parents: "router bgp 65536"
+
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_remove_config.yaml
new file mode 100644
index 00000000..6954b2d2
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_remove_config.yaml
@@ -0,0 +1,10 @@
+---
+- name: Remove pre-existing BGP configurations
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no router bgp 65536
+ - no route-policy test1
+ - no route-policy test2
+ ignore_errors: true
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_route_policy.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_route_policy.cfg
new file mode 100644
index 00000000..d2352c9b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/_route_policy.cfg
@@ -0,0 +1,6 @@
+route-policy test1
+end-policy
+!
+route-policy test2
+end-policy
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/deleted.yaml
new file mode 100644
index 00000000..3c70df5e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/deleted.yaml
@@ -0,0 +1,71 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_nbr_address_family deleted integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_base_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete given bgp_nbr_address_family configuration
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_neighbor_address_family: &deleted
+ config:
+ state: deleted
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 3
+ - result.changed == true
+ - "'no router bgp 65536' not in result.commands"
+ - result.after == deleted.after
+
+ - name: Idempotency check
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_neighbor_address_family: *deleted
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 0
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_nbr_address_family deleted integration tests (for multipale af) connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_vrf_base_config.yaml
+
+- ansible.builtin.include_tasks: _populate_vrf_config.yaml
+
+- block:
+ - name: Delete only one AF between multiple AF present on device.
+ cisco.iosxr.iosxr_bgp_neighbor_address_family:
+ state: deleted
+ config:
+ as_number: 65536
+ vrfs:
+ - vrf: vrf1
+ neighbors:
+ - neighbor_address: 192.0.2.4
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ weight: 4
+ default_originate:
+ set: true
+ capability_orf_prefix: both
+ register: result
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 4
+ - result.changed == true
+ - "'no router bgp 65536' not in result.commands"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/empty_config.yaml
new file mode 100644
index 00000000..9461281b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/empty_config.yaml
@@ -0,0 +1,50 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_bgp_neighbor_address_family empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp_neighbor_address_family:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp_neighbor_address_family:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp_neighbor_address_family:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_bgp_neighbor_address_family:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
+
+- ansible.builtin.debug:
+ msg: END nxos_bgp_global empty_config integration tests on connection={{ ansible_connection }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/gathered.yaml
new file mode 100644
index 00000000..5edb90e9
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/gathered.yaml
@@ -0,0 +1,24 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_bgp_neighbor_address_family gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_base_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Gathered the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_bgp_neighbor_address_family:
+ config:
+ state: gathered
+
+ - name: Assert
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after']['neighbors'] | symmetric_difference(result['gathered']['neighbors']) |length == 0 }}"
+ - merged['after']['as_number'] == result['gathered']['as_number']
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/merged.yaml
new file mode 100644
index 00000000..59da323f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/merged.yaml
@@ -0,0 +1,138 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_bgp_nbr_address_family merged integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_base_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ cisco.iosxr.iosxr_bgp_neighbor_address_family: &id001
+ config:
+ as_number: 65536
+ neighbors:
+ - neighbor_address: 192.0.2.2
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ multipath: true
+ default_originate:
+ set: true
+ weight: 5
+ capability_orf_prefix: both
+ send_multicast_attributes:
+ set: true
+ soft_reconfiguration:
+ inbound:
+ always: true
+ send_community_gshut_ebgp:
+ set: true
+ route_policy:
+ inbound: test1
+ outbound: test1
+ send_extended_community_ebgp:
+ set: true
+ send_community_ebgp:
+ set: true
+ origin_as:
+ validation:
+ disable: true
+ maximum_prefix:
+ max_limit: 10
+ threshold_value: 20
+ restart: 10
+ next_hop_self:
+ set: true
+ as_override:
+ set: true
+ allowas_in:
+ value: 4
+ bestpath_origin_as_allow_invalid: true
+ register: result
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['after']
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ cisco.iosxr.iosxr_bgp_neighbor_address_family: *id001
+ register: result
+
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_vrf_base_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration(vrf and multiple afs)
+ cisco.iosxr.iosxr_bgp_neighbor_address_family: &id002
+ config:
+ as_number: 65536
+ neighbors:
+ - neighbor_address: 192.0.2.2
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ multipath: true
+ default_originate:
+ set: true
+ weight: 5
+ - neighbor_address: 192.0.2.3
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ multipath: true
+ default_originate:
+ set: true
+ weight: 4
+ vrfs:
+ - vrf: vrf1
+ neighbors:
+ - neighbor_address: 192.0.2.4
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ multipath: true
+ default_originate:
+ set: true
+ capability_orf_prefix: both
+ - vrf: vrf2
+ neighbors:
+ - neighbor_address: 192.0.2.5
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ multipath: true
+ default_originate:
+ set: true
+ capability_orf_prefix: both
+ register: result
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['vrf']['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ cisco.iosxr.iosxr_bgp_neighbor_address_family: *id002
+ register: result
+
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/overridden.yaml
new file mode 100644
index 00000000..86ddac62
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/overridden.yaml
@@ -0,0 +1,45 @@
+---
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_base_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Override given bgp_address_family configuration
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_neighbor_address_family: &overridden
+ config:
+ as_number: 65536
+ neighbors:
+ - neighbor_address: 192.0.2.2
+ address_family:
+ - afi: "ipv6"
+ safi: "unicast"
+ multipath: true
+ default_originate:
+ set: true
+ weight: 5
+ route_policy:
+ inbound: test2
+ outbound: test2
+ state: overridden
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 9
+ - result.changed == true
+ - "'no router bgp 65536' not in result.commands"
+ - overridden['commands'] == result['commands']
+
+ - name: Idempotency check
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_neighbor_address_family: *overridden
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 0
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/parsed.yaml
new file mode 100644
index 00000000..50e6fcef
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_bgp_address_family parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided BGP configuration
+ register: result
+ cisco.iosxr.iosxr_bgp_neighbor_address_family:
+ running_config: "{{ lookup('file', './_parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['parsed']}}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/rendered.yaml
new file mode 100644
index 00000000..851dcf1e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/rendered.yaml
@@ -0,0 +1,54 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_bgp_neighbor_af rendered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_base_config.yaml
+
+- name: Render platform specific configuration lines with state rendered (without connecting to the device)
+ cisco.iosxr.iosxr_bgp_neighbor_address_family:
+ config:
+ as_number: 65536
+ neighbors:
+ - neighbor_address: 192.0.2.2
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ multipath: true
+ default_originate:
+ set: true
+ weight: 5
+ capability_orf_prefix: both
+ send_multicast_attributes:
+ set: true
+ soft_reconfiguration:
+ inbound:
+ always: true
+ send_community_gshut_ebgp:
+ set: true
+ send_extended_community_ebgp:
+ set: true
+ send_community_ebgp:
+ set: true
+ origin_as:
+ validation:
+ disable: true
+ maximum_prefix:
+ max_limit: 10
+ threshold_value: 20
+ restart: 10
+ next_hop_self:
+ set: true
+ as_override:
+ set: true
+ allowas_in:
+ value: 4
+ bestpath_origin_as_allow_invalid: true
+ state: rendered
+ register: result
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - rendered['commands'] == result['rendered']
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/replaced.yaml
new file mode 100644
index 00000000..81b5e50b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/tests/common/replaced.yaml
@@ -0,0 +1,105 @@
+---
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_base_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replaced given bgp_nbr_address_family configuration
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_neighbor_address_family: &replaced
+ config:
+ as_number: 65536
+ neighbors:
+ - neighbor_address: 192.0.2.2
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ multipath: true
+ default_originate:
+ set: true
+ weight: 4
+ capability_orf_prefix: both
+ send_multicast_attributes:
+ set: true
+ soft_reconfiguration:
+ inbound:
+ always: true
+ send_community_gshut_ebgp:
+ set: true
+ send_extended_community_ebgp:
+ set: true
+ send_community_ebgp:
+ set: true
+ maximum_prefix:
+ max_limit: 10
+ threshold_value: 20
+ restart: 10
+ next_hop_self:
+ set: true
+ as_override:
+ set: true
+ allowas_in:
+ value: 4
+ bestpath_origin_as_allow_invalid: true
+ state: replaced
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 7
+ - result.changed == true
+ - "'no router bgp 65536' not in result.commands"
+ - replaced['commands'] == result['commands']
+
+ - name: Idempotency check
+ become: true
+ register: result
+ cisco.iosxr.iosxr_bgp_neighbor_address_family: *replaced
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 0
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_vrf_base_config.yaml
+
+- ansible.builtin.include_tasks: _populate_vrf_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ cisco.iosxr.iosxr_bgp_neighbor_address_family: &id001
+ state: replaced
+ config:
+ as_number: 65536
+ vrfs:
+ - vrf: vrf1
+ neighbors:
+ - neighbor_address: 192.0.2.4
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ weight: 4
+ default_originate:
+ set: true
+ capability_orf_prefix: both
+ register: result
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['vrf']['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ cisco.iosxr.iosxr_bgp_neighbor_address_family: *id001
+ register: result
+
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/vars/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/vars/main.yml
new file mode 100644
index 00000000..0be96b26
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_bgp_neighbor_address_family/vars/main.yml
@@ -0,0 +1,145 @@
+---
+merged:
+ commands:
+ - router bgp 65536
+ - neighbor 192.0.2.2
+ - address-family ipv4 unicast
+ - allowas-in 4
+ - as-override
+ - bestpath origin-as allow invalid
+ - capability orf prefix both
+ - default-originate
+ - maximum-prefix 10 20 restart 10
+ - multipath
+ - next-hop-self
+ - origin-as validation disable
+ - send-community-ebgp
+ - send-community-gshut-ebgp
+ - send-extended-community-ebgp
+ - route-policy test1 in
+ - route-policy test1 out
+ - send-multicast-attributes
+ - soft-reconfiguration inbound always
+ - weight 5
+ vrf:
+ commands:
+ - router bgp 65536
+ - neighbor 192.0.2.2
+ - address-family ipv4 unicast
+ - default-originate
+ - multipath
+ - weight 5
+ - neighbor 192.0.2.3
+ - address-family ipv4 unicast
+ - default-originate
+ - multipath
+ - weight 4
+ - vrf vrf1
+ - neighbor 192.0.2.4
+ - address-family ipv4 unicast
+ - capability orf prefix both
+ - default-originate
+ - multipath
+ - vrf vrf2
+ - neighbor 192.0.2.5
+ - address-family ipv4 unicast
+ - capability orf prefix both
+ - default-originate
+ - multipath
+
+ after:
+ as_number: "65536"
+ neighbors:
+ - neighbor_address: "192.0.2.2"
+ address_family:
+ - afi: "ipv4"
+ safi: "unicast"
+ multipath: true
+ default_originate:
+ set: true
+ weight: 5
+ capability_orf_prefix: "both"
+ send_multicast_attributes:
+ set: true
+ soft_reconfiguration:
+ inbound:
+ always: true
+ send_community_gshut_ebgp:
+ set: true
+ send_extended_community_ebgp:
+ set: true
+ send_community_ebgp:
+ set: true
+ origin_as:
+ validation:
+ disable: true
+ route_policy:
+ inbound: "test1"
+ outbound: "test1"
+ maximum_prefix:
+ max_limit: 10
+ threshold_value: 20
+ restart: 10
+ next_hop_self:
+ set: true
+ as_override:
+ set: true
+ allowas_in:
+ value: 4
+ bestpath_origin_as_allow_invalid: true
+
+deleted:
+ after:
+ as_number: "65536"
+
+overridden:
+ commands:
+ - router bgp 65536
+ - neighbor 192.0.2.2
+ - address-family ipv6 unicast
+ - default-originate
+ - multipath
+ - weight 5
+ - route-policy test2 in
+ - route-policy test2 out
+ - no address-family ipv4 unicast
+
+replaced:
+ commands:
+ - router bgp 65536
+ - neighbor 192.0.2.2
+ - address-family ipv4 unicast
+ - no origin-as validation disable
+ - weight 4
+ - no route-policy test1 in
+ - no route-policy test1 out
+
+ vrf:
+ commands:
+ - router bgp 65536
+ - vrf vrf1
+ - neighbor 192.0.2.4
+ - address-family ipv4 unicast
+ - no multipath
+ - weight 4
+
+rendered:
+ commands:
+ - router bgp 65536
+ - neighbor 192.0.2.2
+ - address-family ipv4 unicast
+ - allowas-in 4
+ - as-override
+ - bestpath origin-as allow invalid
+ - capability orf prefix both
+ - default-originate
+ - maximum-prefix 10 20 restart 10
+ - multipath
+ - next-hop-self
+ - origin-as validation disable
+ - send-community-ebgp
+ - send-community-gshut-ebgp
+ - send-extended-community-ebgp
+ - send-multicast-attributes
+ - soft-reconfiguration inbound always
+ - weight 5
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/defaults/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/defaults/main.yml
new file mode 100644
index 00000000..871ea460
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+testcase: "[^_].*"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/meta/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/meta/main.yml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/meta/main.yml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/tasks/cli.yaml
new file mode 100644
index 00000000..a1b57ab4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/tasks/cli.yaml
@@ -0,0 +1,21 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/common"
+ 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
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/tasks/main.yaml
new file mode 100644
index 00000000..f75f2f03
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/tests/common/commit_conf.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/tests/common/commit_conf.yaml
new file mode 100644
index 00000000..05ddfd8e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/tests/common/commit_conf.yaml
@@ -0,0 +1,33 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_cliconf integration tests on connection={{ ansible_connection }}
+
+- name: Apply interface description
+ register: result
+ cisco.iosxr.iosxr_interfaces:
+ state: merged
+ config:
+ - name: GigabitEthernet0/0/0/2
+ description: TestCommitConfirmed
+
+- name: Do commit confirmed
+ cisco.iosxr.iosxr_command:
+ commands:
+ - commit confirmed
+ when: result["changed"] == true
+
+- name: Sleep for 35 sec.
+ ansible.builtin.wait_for:
+ timeout: 35
+ when: result["changed"] == true
+
+- name: Get interface description
+ register: get_desc
+ iosxr_command:
+ commands:
+ - "show interfaces GigabitEthernet 0/0/0/2 | include Description"
+ ignore_errors: true
+
+- ansible.builtin.assert:
+ that:
+ - "'TestCommitConfirmed' in get_desc.stdout[0]"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/vars/main.yaml
new file mode 100644
index 00000000..8ff6db3c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_cliconf/vars/main.yaml
@@ -0,0 +1,3 @@
+---
+ansible_iosxr_commit_confirmed: true
+ansible_iosxr_commit_confirmed_timeout: 30
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/defaults/main.yaml
new file mode 100644
index 00000000..871ea460
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/defaults/main.yaml
@@ -0,0 +1,2 @@
+---
+testcase: "[^_].*"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/meta/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/meta/main.yml
new file mode 100644
index 00000000..be631e5d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_iosxr_tests
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tasks/cli.yaml
new file mode 100644
index 00000000..fd2202fa
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tasks/cli.yaml
@@ -0,0 +1,21 @@
+---
+- 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
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/bad_operator.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/bad_operator.yaml
new file mode 100644
index 00000000..f5379f00
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/bad_operator.yaml
@@ -0,0 +1,19 @@
+---
+- ansible.builtin.debug: msg="START cli/bad_operator.yaml on connection={{ ansible_connection }}"
+
+- name: Test bad operator
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_command:
+ commands:
+ - show version
+ - show interfaces GigabitEthernet 0/0
+ wait_for:
+ - "result[0] contains 'Description: Foo'"
+
+- ansible.builtin.assert:
+ that:
+ - result.failed == true
+ - result.msg is defined
+
+- ansible.builtin.debug: msg="END cli/bad_operator.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/cli_command.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/cli_command.yaml
new file mode 100644
index 00000000..ec0a2567
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/cli_command.yaml
@@ -0,0 +1,45 @@
+---
+- ansible.builtin.debug:
+ msg: START cli/cli_command.yaml on connection={{ ansible_connection }}
+
+- name: Get output for single command
+ register: result
+ ansible.netcommon.cli_command:
+ command: show version
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.stdout is defined
+
+- name: Send invalid command
+ register: result
+ ignore_errors: true
+ ansible.netcommon.cli_command:
+ command: show foo
+
+- ansible.builtin.assert:
+ that:
+ - result.failed == true
+ - result.msg is defined
+
+- name: Delete configuration file on disk to prevent failure of copy task for duplicate
+ ignore_errors: true
+ ansible.netcommon.cli_command:
+ command: delete harddisk:ansible_tmp.txt
+ prompt: Delete harddisk\:/?ansible_tmp\.txt\[confirm\]
+ answer: ""
+
+- name: Run command with prompt
+ register: result
+ ansible.netcommon.cli_command:
+ command: copy running-config harddisk:ansible_tmp.txt
+ prompt: "Destination file name \\(control-c to abort\\)\\: \\[\\/ansible_tmp.txt\\]\\?"
+ answer: ansible_tmp.txt
+
+- ansible.builtin.assert:
+ that:
+ - result.stdout is defined
+ - "'ansible_tmp' in result.stdout"
+
+- ansible.builtin.debug: msg="END cli/cli_command.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/contains.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/contains.yaml
new file mode 100644
index 00000000..c87e082a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/contains.yaml
@@ -0,0 +1,19 @@
+---
+- ansible.builtin.debug: msg="START cli/contains.yaml on connection={{ ansible_connection }}"
+
+- name: Test contains operator
+ register: result
+ cisco.iosxr.iosxr_command:
+ commands:
+ - show version
+ - show interfaces Loopback 888
+ wait_for:
+ - result[0] contains 'Cisco IOS XR Software'
+ - result[1] contains 'Hardware is Loopback interface'
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.stdout is defined
+
+- ansible.builtin.debug: msg="END cli/contains.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/invalid.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/invalid.yaml
new file mode 100644
index 00000000..3ba25aec
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/invalid.yaml
@@ -0,0 +1,32 @@
+---
+- ansible.builtin.debug: msg="START cli/invalid.yaml on connection={{ ansible_connection }}"
+
+- name: Run invalid command
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_command:
+ commands:
+ command: show foo
+ prompt: fooprompt
+ answer: "yes"
+
+- ansible.builtin.assert:
+ that:
+ - result.failed
+
+- name: Run commands that include invalid command
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_command:
+ commands:
+ - show version
+
+ - command: show foo
+ prompt: fooprompt
+ answer: "yes"
+
+- ansible.builtin.assert:
+ that:
+ - result.failed
+
+- ansible.builtin.debug: msg="END cli/invalid.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/output.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/output.yaml
new file mode 100644
index 00000000..20862223
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/output.yaml
@@ -0,0 +1,28 @@
+---
+- ansible.builtin.debug: msg="START cli/output.yaml on connection={{ ansible_connection }}"
+
+- name: Get output for single command
+ register: result
+ cisco.iosxr.iosxr_command:
+ commands:
+ - show version
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.stdout is defined
+
+- name: Get output for multiple commands
+ register: result
+ cisco.iosxr.iosxr_command:
+ commands:
+ - show version
+ - show interfaces
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.stdout is defined
+ - result.stdout | length == 2
+
+- ansible.builtin.debug: msg="END cli/output.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/prompt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/prompt.yaml
new file mode 100644
index 00000000..09f14686
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/prompt.yaml
@@ -0,0 +1,26 @@
+---
+- ansible.builtin.debug:
+ msg: START cli/prompt.yaml on connection={{ ansible_connection }}
+
+- name: Delete configuration file on disk to prevent failure of copy task for duplicate
+ ignore_errors: true
+ cisco.iosxr.iosxr_command:
+ commands:
+ - command: delete harddisk:ansible_tmp.txt
+ prompt: Delete harddisk\:/?ansible_tmp\.txt\[confirm\]
+ answer: ""
+
+- name: Copy
+ register: result
+ cisco.iosxr.iosxr_command:
+ commands:
+ - command: copy running-config harddisk:ansible_tmp.txt
+ prompt: "Destination file name \\(control-c to abort\\)\\: \\[\\/ansible_tmp.txt\\]\\?"
+ answer: ansible_tmp.txt
+
+- ansible.builtin.assert:
+ that:
+ - result.stdout is defined
+ - "'ansible_tmp' in result.stdout[0]"
+
+- ansible.builtin.debug: msg="END cli/prompt.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/timeout.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/timeout.yaml
new file mode 100644
index 00000000..8e4397b9
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_command/tests/cli/timeout.yaml
@@ -0,0 +1,18 @@
+---
+- ansible.builtin.debug: msg="START cli/timeout.yaml on connection={{ ansible_connection }}"
+
+- name: Test bad condition
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_command:
+ commands:
+ - show version
+ wait_for:
+ - result[0] contains bad_value_string
+
+- ansible.builtin.assert:
+ that:
+ - result.failed == true
+ - result.msg is defined
+
+- ansible.builtin.debug: msg="END cli/timeout.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/defaults/main.yaml
new file mode 100644
index 00000000..9ef5ba51
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/fixtures/config_add_interface.txt b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/fixtures/config_add_interface.txt
new file mode 100644
index 00000000..c63e3f92
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/fixtures/config_add_interface.txt
@@ -0,0 +1,42 @@
+hostname iosxr-7.0.2
+username admin
+ group root-lr
+ group cisco-support
+ secret 10 $6$xWjtz/sPyTaz5z/.$2jQ3Ihs8/qvcTn0MT9IxW3egRWRFYJ6Rgk3Q.K7QYgrke7QE5.tUHLc19qCjnKhdgJlVU6SRrjBaO1HP0HkQx1
+!
+username zuul
+ group root-lr
+ group cisco-support
+ password 7 082C555C0C1E101B13191C053938
+!
+tpa
+ vrf default
+ address-family ipv4
+ update-source dataports MgmtEth0/RP0/CPU0/0
+ !
+ !
+!
+call-home
+ service active
+ contact smart-licensing
+ profile CiscoTAC-1
+ active
+ destination transport-method http
+ !
+!
+interface Loopback888
+ description test for ansible
+ shutdown
+!
+interface MgmtEth0/RP0/CPU0/0
+ ipv4 address dhcp
+!
+interface preconfigure GigabitEthernet0/0/0/3
+ description test-interface-3
+ mtu 256
+ speed 100
+ duplex full
+!
+ssh server v2
+ssh server vrf default
+end
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/fixtures/config_del_interface.txt b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/fixtures/config_del_interface.txt
new file mode 100644
index 00000000..eb006870
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/fixtures/config_del_interface.txt
@@ -0,0 +1,36 @@
+hostname iosxr-7.0.2
+username admin
+ group root-lr
+ group cisco-support
+ secret 10 $6$xWjtz/sPyTaz5z/.$2jQ3Ihs8/qvcTn0MT9IxW3egRWRFYJ6Rgk3Q.K7QYgrke7QE5.tUHLc19qCjnKhdgJlVU6SRrjBaO1HP0HkQx1
+!
+username zuul
+ group root-lr
+ group cisco-support
+ password 7 082C555C0C1E101B13191C053938
+!
+tpa
+ vrf default
+ address-family ipv4
+ update-source dataports MgmtEth0/RP0/CPU0/0
+ !
+ !
+!
+call-home
+ service active
+ contact smart-licensing
+ profile CiscoTAC-1
+ active
+ destination transport-method http
+ !
+!
+interface Loopback888
+ description test for ansible
+ shutdown
+!
+interface MgmtEth0/RP0/CPU0/0
+ ipv4 address dhcp
+!
+ssh server v2
+ssh server vrf default
+end
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/meta/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/meta/main.yml
new file mode 100644
index 00000000..be631e5d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_iosxr_tests
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/cli.yaml
new file mode 100644
index 00000000..59a889b4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/cli.yaml
@@ -0,0 +1,20 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/cli"
+ patterns: "{{ testcase }}.yaml"
+ 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
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/cli_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/cli_config.yaml
new file mode 100644
index 00000000..0b6332e9
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/cli_config.yaml
@@ -0,0 +1,20 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/cli_config"
+ patterns: "{{ testcase }}.yaml"
+ 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
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/main.yaml
new file mode 100644
index 00000000..3bf9ffdf
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/main.yaml
@@ -0,0 +1,10 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+
+- name: Include the cli_config tasks
+ ansible.builtin.include_tasks: cli_config.yaml
+
+- name: Include the redirection task
+ ansible.builtin.include_tasks: redirection.yaml
+ when: ansible_version.full is version('2.10.0', '>=')
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/redirection.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/redirection.yaml
new file mode 100644
index 00000000..bc4b47e2
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tasks/redirection.yaml
@@ -0,0 +1,18 @@
+---
+- name: Collect all redirection CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/redirection"
+ patterns: "{{ testcase }}.yaml"
+ register: shortname_test_cases
+ delegate_to: localhost
+
+- name: Set test_items for redirection
+ ansible.builtin.set_fact: test_items="{{ shortname_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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/change_prefix_set.j2 b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/change_prefix_set.j2
new file mode 100644
index 00000000..3dd5beef
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/change_prefix_set.j2
@@ -0,0 +1,5 @@
+interface Loopback999
+ description this is a test interface for prefix-set
+prefix-set ebpg_filter
+ 192.168.0.0/16 ge 15 le 30
+end-set
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/config.j2 b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/config.j2
new file mode 100644
index 00000000..a1272530
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/config.j2
@@ -0,0 +1,3 @@
+interface Loopback999
+ description this is a test
+ shutdown
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/configuration.j2 b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/configuration.j2
new file mode 100644
index 00000000..73c98879
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/configuration.j2
@@ -0,0 +1,3 @@
+interface Loopback888
+ description test for ansible automation
+ shutdown
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/init_prefix_set.j2 b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/init_prefix_set.j2
new file mode 100644
index 00000000..d1170b02
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/init_prefix_set.j2
@@ -0,0 +1,3 @@
+prefix-set ebpg_filter
+ 192.168.0.0/16 ge 17 le 30
+end-set
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/route_policy.j2 b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/route_policy.j2
new file mode 100644
index 00000000..ecc68e81
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/route_policy.j2
@@ -0,0 +1,121 @@
+router ospf 1
+ area 0
+!
+prefix-set EBGP-PEER-BOGONS
+ 0.0.0.0/0,
+ 0.0.0.0/8 le 32,
+ 10.0.0.0/8 le 32,
+ 127.0.0.0/8 le 32,
+ 169.254.0.0/16 le 32,
+ 172.16.0.0/12 le 32,
+ 192.0.0.0/24 le 32,
+ 192.0.2.0/24 le 32,
+ 192.168.0.0/16 le 32,
+ 198.18.0.0/15 le 32,
+ 224.0.0.0/4 le 32,
+ 240.0.0.0/4 le 32
+end-set
+!
+prefix-set cust-ddos-DDOS
+end-set
+!
+prefix-set cust-no-export
+end-set
+!
+prefix-set acme_DC_Internal
+ 137.1.0.0/16,
+ 137.1.16.0/24,
+ 137.1.18.0/24,
+ 137.1.20.0/24,
+ 137.1.22.0/24,
+ 137.1.23.0/24,
+ 137.1.24.0/24,
+ 137.1.29.0/24,
+ 137.1.30.0/24,
+ 137.1.31.0/24,
+ 137.1.32.0/21,
+ 137.1.40.0/22,
+ 209.1.0.0/16
+end-set
+!
+as-path-set EBGP-PEER-AS16509-403-PERMIT-PATHS
+ ios-regex '^11164_8075_',
+ ios-regex '^11164_16509$',
+ ios-regex '^1116_16509_[0-9]+$',
+ ios-regex '^8075_',
+ ios-regex '^16509$',
+ ios-regex '^16509_[0-9]+$'
+end-set
+!
+community-set cust-announce
+ 1525:65298,
+ 1525:65436,
+ 1525:65438,
+ 1525:65439,
+ 1525:65498,
+ 1525:65511,
+ 1523:65418,
+ 1523:65436,
+ 1523:65438
+end-set
+!
+community-set cust-no-export
+ 1525:65439,
+ 1525:65511,
+ 1525:65535
+end-set
+!
+
+route-policy POLICY2
+end-policy
+!
+route-policy cust2bgp
+ set origin igp
+ set next-hop 137.1.16.12
+end-policy
+!
+rd-set ebpg-1
+end-set
+!
+rd-set EBGP_INCOMING_RD_SET
+ 172.16.0.0/16:*,
+ 172.17.0.0/16:100,
+ 192:*,
+ 192:100
+end-set
+!
+extcommunity-set rt EBGP_INCOMIG_RT_SET
+ 10:615,
+ 10:6150,
+ 15.15.15.15:15
+end-set
+!
+extcommunity-set rt ebpg-1
+end-set
+!
+route-policy static-to-bgp
+ if destination in cust-no-export then
+ apply cust2bgp
+ set community cust-no-export additive
+ elseif destination in cust-announce then
+ apply cust2bgp
+ set community cust-announce additive
+ elseif destination in cust-announce-backup then
+ apply cust2bgp
+ set local-preference 100
+ set weight 0
+ set community cust-announce additive
+ elseif destination in cust-no-export-backup then
+ apply cust2bgp
+ set local-preference 98
+ set weight 0
+ set community cust-no-export additive
+ else
+ drop
+ endif
+end-policy
+!
+class-map match-any data
+ match precedence ipv4 0 1
+ end-class-map
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/route_policy_change.j2 b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/route_policy_change.j2
new file mode 100644
index 00000000..4f04f384
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/route_policy_change.j2
@@ -0,0 +1,68 @@
+router ospf 1
+ area 0
+!
+prefix-set EBGP-PEER-BOGONS
+ 192.0.2.0/24 le 32,
+ 192.168.0.0/16 le 32,
+ 198.18.0.0/16 le 32,
+ 224.0.0.0/4 le 32,
+ 240.0.0.0/4 le 32
+end-set
+!
+as-path-set EBGP-PEER-AS16509-403-PERMIT-PATHS
+ ios-regex '^11164_8075_',
+ ios-regex '^1164_16509$',
+ ios-regex '^1116_16409_[0-9]+$',
+ ios-regex '^8075_'
+end-set
+!
+community-set cust-announce
+ 1525:65298,
+ 1525:6546,
+ 1525:6438,
+ 1525:65439,
+ 1525:65498
+end-set
+!
+rd-set EBGP_INCOMING_RD_SET
+ 172.16.0.0/16:*,
+ 172.14.0.0/16:100,
+ 192:*,
+ 192:100
+end-set
+!
+extcommunity-set rt EBGP_INCOMIG_RT_SET
+ 10:615,
+ 10:6120,
+ 15.15.15.15:15
+end-set
+!
+route-policy POLICY2
+end-policy
+!
+route-policy static-to-bgp
+ if destination in cust-no-export then
+ apply cust2bgp
+ set community cust-no-export additive
+ elseif destination in cust-announce then
+ apply cust2bgp
+ set community cust-announce additive
+ elseif destination in cust-announce-backup then
+ apply cust2bgp
+ set local-preference 100
+ set weight 23
+ set community cust-announce additive
+ elseif destination in cust-no-export-backup then
+ apply cust2bgp
+ set local-preference 98
+ set weight 0
+ set community cust-no-export additive
+ else
+ drop
+ endif
+end-policy
+!
+class-map match-any data
+ match precedence ipv4 0 1 2
+ end-class-map
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/route_policy_clean.j2 b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/route_policy_clean.j2
new file mode 100644
index 00000000..87152680
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/basic/route_policy_clean.j2
@@ -0,0 +1,32 @@
+no router ospf 1
+!
+no prefix-set EBGP-PEER-BOGONS
+!
+no prefix-set cust-ddos-DDOS
+!
+no prefix-set cust-no-export
+!
+no prefix-set acme_DC_Internal
+!
+no as-path-set EBGP-PEER-AS16509-403-PERMIT-PATHS
+!
+no community-set cust-announce
+!
+no community-set cust-no-export
+!
+no rd-set ebpg-1
+!
+no rd-set EBGP_INCOMING_RD_SET
+!
+no extcommunity-set rt EBGP_INCOMIG_RT_SET
+!
+no extcommunity-set rt ebpg-1
+!
+no route-policy POLICY2
+!
+no route-policy cust2bgp
+!
+no route-policy static-to-bgp
+!
+no class-map match-any data
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/defaults/config.j2 b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/defaults/config.j2
new file mode 100644
index 00000000..92f35da8
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/templates/defaults/config.j2
@@ -0,0 +1,3 @@
+interface Loopback999
+ description this is a test
+ no shutdown
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/backup.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/backup.yaml
new file mode 100644
index 00000000..f33fedff
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/backup.yaml
@@ -0,0 +1,69 @@
+---
+- ansible.builtin.debug: msg="START cli/backup.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no description
+ - no shutdown
+ parents:
+ - interface Loopback999
+ match: none
+
+- name: Configure device with configuration
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/config.j2
+ backup: true
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - result.updates is not defined
+
+- name: Delete configurable backup file path
+ ansible.builtin.file:
+ path: "{{ item }}"
+ state: absent
+ with_items:
+ - "{{ role_path }}/backup_test_dir/"
+ - "{{ role_path }}/backup/backup.cfg"
+
+- name: Take configuration backup in custom filename and directory path
+ become: true
+ register: result
+ cisco.iosxr.iosxr_config:
+ backup: true
+ backup_options:
+ filename: backup.cfg
+ dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Take configuration backup in custom filename
+ become: true
+ register: result
+ cisco.iosxr.iosxr_config:
+ backup: true
+ backup_options:
+ filename: backup.cfg
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Take configuration backup in custom path and default filename
+ become: true
+ register: result
+ cisco.iosxr.iosxr_config:
+ backup: true
+ backup_options:
+ dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- ansible.builtin.debug: msg="END cli/backup.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/comment-too-long.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/comment-too-long.yaml
new file mode 100644
index 00000000..cbb59f6e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/comment-too-long.yaml
@@ -0,0 +1,26 @@
+---
+- ansible.builtin.debug: msg="START cli/comment-too-long.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no description
+ - no shutdown
+ parents:
+ - interface Loopback999
+ match: none
+
+- name: Commit message too long
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ src: basic/config.j2
+ comment: this is a really long message aaaaabbbbbbcdde end-of-message
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.updates is not defined
+ - "'comment argument cannot be more than 60 characters' in result.msg"
+
+- ansible.builtin.debug: msg="END cli/comment-too-long.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/comment.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/comment.yaml
new file mode 100644
index 00000000..dcbbe78a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/comment.yaml
@@ -0,0 +1,76 @@
+---
+- ansible.builtin.debug: msg="START cli/comment.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no description
+ - no shutdown
+ parents:
+ - interface Loopback999
+ match: none
+
+- name: Configure device with comment
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/config.j2
+ comment: this is sensible commit message
+ exclusive: true
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - result.updates is not defined
+
+- name: Check device with configuration
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/config.j2
+ exclusive: true
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.updates is not defined
+
+- name: Assert accurately report configuration failure during pseudo-atomic operation
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ lines:
+ - router bgp 65111
+ - neighbor 10.1.1.1
+ - update-source Loopback0
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.failed == true
+
+- name: Run show configuration failed
+ register: result
+ cisco.iosxr.iosxr_config:
+ lines:
+ - show configuration failed
+
+- ansible.builtin.assert:
+ that:
+ - result.failed == false
+
+- name: Configure device without default comment
+ register: result
+ cisco.iosxr.iosxr_config:
+ lines: hostname iosxr1
+ disable_default_comment: true
+
+- name: Check details of latest commit
+ iosxr_command:
+ commands:
+ - show configuration commit list 1 detail
+ register: result
+
+- ansible.builtin.assert:
+ that:
+ - "'configured by iosxr_config' not in result.stdout[0]"
+
+- ansible.builtin.debug: msg="END cli/comment.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/commit_confirmed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/commit_confirmed.yaml
new file mode 100644
index 00000000..f9d672d2
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/commit_confirmed.yaml
@@ -0,0 +1,35 @@
+---
+- ansible.builtin.debug: msg="START cli/commit_confirmed.yaml on connection={{ ansible_connection }}"
+
+- name: Test commit confirmed functionality
+ vars:
+ ansible_iosxr_commit_confirmed: true
+ ansible_iosxr_commit_confirmed_timeout: 60
+ cisco.iosxr.iosxr_config:
+ lines:
+ - hostname iosxr_commit_confirmed
+
+- name: "Get hostname"
+ vars:
+ ansible_iosxr_commit_confirmed: true
+ register: get_hostname1
+ iosxr_command:
+ commands:
+ - "show running-config hostname"
+ ignore_errors: true
+
+- name: Sleep for 90 secs as rollback to happen.
+ ansible.builtin.wait_for:
+ timeout: 90
+
+- name: "Get hostname"
+ register: get_hostname2
+ iosxr_command:
+ commands:
+ - "show running-config hostname"
+ ignore_errors: true
+
+- ansible.builtin.assert:
+ that:
+ - "'iosxr_commit_confirmed' in get_hostname1.stdout[0]"
+ - "'iosxr_commit_confirmed' not in get_hostname2.stdout[0]"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/commit_label.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/commit_label.yaml
new file mode 100644
index 00000000..f4926bae
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/commit_label.yaml
@@ -0,0 +1,70 @@
+---
+- ansible.builtin.debug: msg="START cli/commit_label.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no description
+ - no shutdown
+ parents:
+ - interface Loopback999
+ match: none
+
+- name: Get a unique and valid label
+ ansible.builtin.set_fact:
+ label: ansible_{{ 1001 | random | to_uuid | truncate(20, true, '_') }}
+
+- name: Configure device with a label and a comment
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/config.j2
+ comment: this is sensible commit message
+ label: "{{ label }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no description
+ - no shutdown
+ parents:
+ - interface Loopback999
+ match: none
+
+- name: Try to commit with old label, fail with a msg that label is alreay used
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ src: basic/config.j2
+ label: "{{ label }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - "'already used' in result.msg"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no description
+ - no shutdown
+ parents:
+ - interface Loopback999
+ match: none
+
+- name: Try to commit with invalid chars($) in label
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ src: basic/config.j2
+ label: ansible_iosxr_config_$
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - "'only contain alphabets' in result.msg"
+
+- ansible.builtin.debug: msg="END cli/commit_label.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/extcommunity_set_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/extcommunity_set_config.yaml
new file mode 100644
index 00000000..225f6b1c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/extcommunity_set_config.yaml
@@ -0,0 +1,26 @@
+---
+- ansible.builtin.debug: msg="START cli/extcommunity_set_config.yaml on connection={{ ansible_connection }}"
+
+- name: Pre-setup cleanup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no extcommunity-set rt test_set
+
+- name: Setup
+ register: result
+ cisco.iosxr.iosxr_config:
+ lines:
+ - 6667:1234
+ - end-set
+ parents: extcommunity-set rt test_set
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Post-setup cleanup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no extcommunity-set rt test_set
+
+- ansible.builtin.debug: msg="END cli/ on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/misplaced_sublevel.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/misplaced_sublevel.yaml
new file mode 100644
index 00000000..23069211
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/misplaced_sublevel.yaml
@@ -0,0 +1,27 @@
+---
+- ansible.builtin.debug: msg="START cli/misplaced_sublevel.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ src: basic/init_prefix_set.j2
+
+- name: Change prefix-set and new command after prefix-set
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/change_prefix_set.j2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Play same configuration again to verify no diff in prefix-set also works
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/change_prefix_set.j2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- ansible.builtin.debug: msg="END cli/misplaced_sublevel.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/prefix_set_remark.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/prefix_set_remark.yaml
new file mode 100644
index 00000000..d6909db1
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/prefix_set_remark.yaml
@@ -0,0 +1,28 @@
+---
+- ansible.builtin.debug: msg="START cli/prefix_set_remark.yaml on connection={{ ansible_connection }}"
+
+- name: Pre-setup cleanup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no prefix-set test_set
+
+- name: Setup
+ register: result
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "## testremark"
+ - 192.168.1.0/20 le 24
+ - end-set
+ parents: prefix-set test_set
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'## testremark' in result.commands"
+
+- name: Post-setup cleanup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no prefix-set test_set
+
+- ansible.builtin.debug: msg="END cli/prefix_set_remark.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/replace_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/replace_config.yaml
new file mode 100644
index 00000000..6cd72dba
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/replace_config.yaml
@@ -0,0 +1,40 @@
+---
+- ansible.builtin.debug: msg="START cli/replace_config.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no interface GigabitEthernet0/0/0/3
+
+- name: Replace configuration (add preconfigured interface)
+ register: result
+ cisco.iosxr.iosxr_config: &id001
+ src: "{{ role_path }}/fixtures/config_add_interface.txt"
+ replace: config
+
+- ansible.builtin.assert:
+ that:
+ - '"load harddisk:/ansible_config.txt" in result.commands'
+
+- name: Replace configuration (add preconfigured interface)(idempotence)
+ register: result
+ cisco.iosxr.iosxr_config: *id001
+- ansible.builtin.assert: &id003
+ that:
+ - result.changed == false
+
+- name: Replace configuration (del preconfigured interface)
+ register: result
+ cisco.iosxr.iosxr_config: &id002
+ src: "{{ role_path }}/fixtures/config_del_interface.txt"
+ replace: config
+
+- ansible.builtin.assert:
+ that:
+ - '"load harddisk:/ansible_config.txt" in result.commands'
+
+- name: Replace configuration (del preconfigured interface)(idempotence)
+ register: result
+ cisco.iosxr.iosxr_config: *id002
+- ansible.builtin.assert: *id003
+- ansible.builtin.debug: msg="END cli/replace_config.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/route_policy.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/route_policy.yaml
new file mode 100644
index 00000000..e5f374be
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/route_policy.yaml
@@ -0,0 +1,53 @@
+---
+- ansible.builtin.debug: msg="START cli/route_policy.yaml on connection={{ ansible_connection }}"
+
+- name: Cleanup
+ cisco.iosxr.iosxr_config:
+ src: basic/route_policy_clean.j2
+
+- name: Config setup route-policy/prefix-set/as-path-set/community-set
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/route_policy.j2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Configure same route-policy/prefix-set ... verify change=0
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/route_policy.j2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Do a change in multi-sublevel route-policy/prefix-set/community-set
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/route_policy_change.j2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Configure same route-policy/prefix-set ... verify change=0
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/route_policy_change.j2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Cleanup
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/route_policy_clean.j2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- ansible.builtin.debug: msg="END cli/route_policy.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/src_basic.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/src_basic.yaml
new file mode 100644
index 00000000..dd79ebe0
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/src_basic.yaml
@@ -0,0 +1,33 @@
+---
+- ansible.builtin.debug: msg="START cli/src_basic.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no description
+ - no shutdown
+ parents:
+ - interface Loopback999
+ match: none
+
+- name: Configure device with configuration
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/config.j2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - result.updates is not defined
+
+- name: Check device with configuration
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/config.j2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.updates is not defined
+
+- ansible.builtin.debug: msg="END cli/src_basic.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/src_invalid.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/src_invalid.yaml
new file mode 100644
index 00000000..4b02dbf3
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/src_invalid.yaml
@@ -0,0 +1,16 @@
+---
+- ansible.builtin.debug: msg="START cli/src_invalid.yaml on connection={{ ansible_connection }}"
+
+- name: Configure with invalid src
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ src: basic/foobar.j2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.failed == true
+ - result.msg == 'path specified in src not found'
+
+- ansible.builtin.debug: msg="END cli/src_invalid.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/src_match_none.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/src_match_none.yaml
new file mode 100644
index 00000000..7794ab37
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/src_match_none.yaml
@@ -0,0 +1,34 @@
+---
+- ansible.builtin.debug: msg="START cli/src_match_none.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no description
+ - no shutdown
+ parents:
+ - interface Loopback999
+ match: none
+
+- name: Configure device with configuration
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/config.j2
+ match: none
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - result.updates is not defined
+
+- name: Check device with configuration
+ register: result
+ cisco.iosxr.iosxr_config:
+ src: basic/config.j2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.updates is not defined
+
+- ansible.builtin.debug: msg="END cli/src_match_none.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel.yaml
new file mode 100644
index 00000000..536db642
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel.yaml
@@ -0,0 +1,43 @@
+---
+- ansible.builtin.debug: msg="START cli/sublevel.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no ipv4 access-list test
+ match: none
+
+- name: Configure sub level command
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 any any log
+ parents:
+ - ipv4 access-list test
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'ipv4 access-list test' in result.commands"
+ - "'10 permit ipv4 any any log' in result.commands"
+
+- name: Configure sub level command idempotent check
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 any any log
+ parents:
+ - ipv4 access-list test
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no ipv4 access-list test
+ match: none
+
+- ansible.builtin.debug: msg="END cli/sublevel.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_block.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_block.yaml
new file mode 100644
index 00000000..2bbb2f6d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_block.yaml
@@ -0,0 +1,59 @@
+---
+- ansible.builtin.debug: msg="START cli/sublevel_block.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 host 192.0.2.1 any log
+ - 20 permit ipv4 host 192.0.2.2 any log
+ - 30 permit ipv4 host 192.0.2.3 any log
+ parents:
+ - ipv4 access-list test
+ before:
+ - no ipv4 access-list test
+ match: none
+
+- name: Configure sub level command using block resplace
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 host 192.0.2.1 any log
+ - 20 permit ipv4 host 192.0.2.2 any log
+ - 30 permit ipv4 host 192.0.2.3 any log
+ - 40 permit ipv4 host 192.0.2.4 any log
+ parents:
+ - ipv4 access-list test
+ replace: block
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'ipv4 access-list test' in result.commands"
+ - "'10 permit ipv4 host 192.0.2.1 any log' in result.commands"
+ - "'20 permit ipv4 host 192.0.2.2 any log' in result.commands"
+ - "'30 permit ipv4 host 192.0.2.3 any log' in result.commands"
+ - "'40 permit ipv4 host 192.0.2.4 any log' in result.commands"
+
+- name: Check sub level command using block replace
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 host 192.0.2.1 any log
+ - 20 permit ipv4 host 192.0.2.2 any log
+ - 30 permit ipv4 host 192.0.2.3 any log
+ - 40 permit ipv4 host 192.0.2.4 any log
+ parents:
+ - ipv4 access-list test
+ replace: block
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no ipv4 access-list test
+ match: none
+
+- ansible.builtin.debug: msg="END cli/sublevel_block.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_exact.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_exact.yaml
new file mode 100644
index 00000000..1413a86b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_exact.yaml
@@ -0,0 +1,63 @@
+---
+- ansible.builtin.debug: msg="START cli/sublevel_exact.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 host 192.0.2.1 any log
+ - 20 permit ipv4 host 192.0.2.2 any log
+ - 30 permit ipv4 host 192.0.2.3 any log
+ - 40 permit ipv4 host 192.0.2.4 any log
+ - 50 permit ipv4 host 192.0.2.5 any log
+ parents:
+ - ipv4 access-list test
+ before:
+ - no ipv4 access-list test
+ match: none
+
+- name: Configure sub level command using exact match
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 host 192.0.2.1 any log
+ - 20 permit ipv4 host 192.0.2.2 any log
+ - 30 permit ipv4 host 192.0.2.3 any log
+ - 40 permit ipv4 host 192.0.2.4 any log
+ parents:
+ - ipv4 access-list test
+ match: exact
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'ipv4 access-list test' in result.commands"
+ - "'10 permit ipv4 host 192.0.2.1 any log' in result.commands"
+ - "'20 permit ipv4 host 192.0.2.2 any log' in result.commands"
+ - "'30 permit ipv4 host 192.0.2.3 any log' in result.commands"
+ - "'40 permit ipv4 host 192.0.2.4 any log' in result.commands"
+ - "'50 permit ipv4 host 192.0.2.5 any log' not in result.commands"
+
+- name: Check sub level command using exact match
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 host 192.0.2.1 any log
+ - 20 permit ipv4 host 192.0.2.2 any log
+ - 30 permit ipv4 host 192.0.2.3 any log
+ - 40 permit ipv4 host 192.0.2.4 any log
+ - 50 permit ipv4 host 192.0.2.5 any log
+ parents:
+ - ipv4 access-list test
+ match: exact
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no ipv4 access-list test
+ match: none
+
+- ansible.builtin.debug: msg="END cli/sublevel_exact.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_strict.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_strict.yaml
new file mode 100644
index 00000000..78ede704
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_strict.yaml
@@ -0,0 +1,65 @@
+---
+- ansible.builtin.debug: msg="START cli/sublevel_strict.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 host 192.0.2.1 any log
+ - 20 permit ipv4 host 192.0.2.3 any log
+ - 30 permit ipv4 host 192.0.2.2 any log
+ - 40 permit ipv4 host 192.0.2.4 any log
+ - 50 permit ipv4 host 192.0.2.5 any log
+ parents:
+ - ipv4 access-list test
+ before:
+ - no ipv4 access-list test
+ match: none
+
+- name: Configure sub level command using strict match
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 host 192.0.2.1 any log
+ - 20 permit ipv4 host 192.0.2.2 any log
+ - 30 permit ipv4 host 192.0.2.3 any log
+ - 40 permit ipv4 host 192.0.2.4 any log
+ parents:
+ - ipv4 access-list test
+ before:
+ - no ipv4 access-list test
+ match: strict
+ replace: block
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'ipv4 access-list test' in result.commands"
+ - "'10 permit ipv4 host 192.0.2.1 any log' in result.commands"
+ - "'20 permit ipv4 host 192.0.2.2 any log' in result.commands"
+ - "'30 permit ipv4 host 192.0.2.3 any log' in result.commands"
+ - "'40 permit ipv4 host 192.0.2.4 any log' in result.commands"
+ - "'50 permit ipv4 host 192.0.2.5 any log' not in result.commands"
+
+- name: Check sub level command using strict match
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 host 192.0.2.1 any log
+ - 20 permit ipv4 host 192.0.2.2 any log
+ - 30 permit ipv4 host 192.0.2.3 any log
+ - 40 permit ipv4 host 192.0.2.4 any log
+ parents:
+ - ipv4 access-list test
+ match: strict
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no ipv4 access-list test
+ match: none
+
+- ansible.builtin.debug: msg="END cli/sublevel_strict.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_strict_mul_parents.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_strict_mul_parents.yaml
new file mode 100644
index 00000000..54d91adb
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/sublevel_strict_mul_parents.yaml
@@ -0,0 +1,73 @@
+---
+- ansible.builtin.debug: msg="START cli/sublevel_strict_mul_parents.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ lines:
+ - class-map match-any c1
+ - match precedence 7
+ - policy-map p1
+ - class c1
+ - set precedence 2
+ before:
+ - no policy-map p1
+ - no class-map match-any c1
+ match: none
+
+- name: Configure sub level command using strict match
+ register: result
+ cisco.iosxr.iosxr_config:
+ lines:
+ - set precedence 5
+ - police rate percent 10
+ parents:
+ - policy-map p1
+ - class c1
+ match: strict
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'set precedence 5' in result.commands"
+ - "'police rate percent 10' in result.commands"
+
+- name: Change sub level command order and configuration with strict match
+ register: result
+ cisco.iosxr.iosxr_config:
+ lines:
+ - police rate percent 10
+ - set precedence 5
+ parents:
+ - policy-map p1
+ - class c1
+ match: strict
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'set precedence 5' in result.commands"
+ - "'police rate percent 10' in result.commands"
+
+- name: Config sub level command with strict match (idempotency)
+ register: result
+ cisco.iosxr.iosxr_config:
+ lines:
+ - set precedence 5
+ - police rate percent 10
+ parents:
+ - policy-map p1
+ - class c1
+ match: strict
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no policy-map p1
+ - no class-map match-any c1
+ match: none
+
+- ansible.builtin.debug: msg="END cli/sublevel_strict_mul_parents.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel.yaml
new file mode 100644
index 00000000..b548d561
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel.yaml
@@ -0,0 +1,37 @@
+---
+- ansible.builtin.debug: msg="START cli/toplevel.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - hostname {{ inventory_hostname_short }}
+ match: none
+
+- name: Configure top level command
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - hostname foo
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'hostname foo' in result.commands"
+
+- name: Configure top level command idempotent check
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - hostname foo
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ commands:
+ - hostname {{ inventory_hostname_short }}
+ match: none
+
+- ansible.builtin.debug: msg="END cli/toplevel.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel_after.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel_after.yaml
new file mode 100644
index 00000000..f41fd461
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel_after.yaml
@@ -0,0 +1,44 @@
+---
+- ansible.builtin.debug: msg="START cli/toplevel_after.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no cdp
+ - hostname {{ inventory_hostname_short }}
+ match: none
+
+- name: Configure top level command with before
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - hostname foo
+ after:
+ - cdp
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'hostname foo' in result.commands"
+ - "'cdp' in result.commands"
+
+- name: Configure top level command with before idempotent check
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - hostname foo
+ after:
+ - no cdp
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no cdp
+ - hostname {{ inventory_hostname_short }}
+ match: none
+
+- ansible.builtin.debug: msg="END cli/toplevel_after.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel_before.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel_before.yaml
new file mode 100644
index 00000000..95ce1fb5
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel_before.yaml
@@ -0,0 +1,44 @@
+---
+- ansible.builtin.debug: msg="START cli/toplevel_before.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no cdp
+ - hostname {{ inventory_hostname_short }}
+ match: none
+
+- name: Configure top level command with before
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - hostname foo
+ before:
+ - cdp
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'hostname foo' in result.commands"
+ - "'cdp' in result.commands"
+
+- name: Configure top level command with before idempotent check
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - hostname foo
+ before:
+ - cdp
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ commands:
+ - no cdp
+ - hostname {{ inventory_hostname_short }}
+ match: none
+
+- ansible.builtin.debug: msg="END cli/toplevel_before.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel_nonidempotent.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel_nonidempotent.yaml
new file mode 100644
index 00000000..498f5f91
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli/toplevel_nonidempotent.yaml
@@ -0,0 +1,42 @@
+---
+- ansible.builtin.debug: msg="START cli/toplevel_nonidempotent.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - hostname {{ inventory_hostname_short }}
+ match: none
+
+- name: Configure top level command
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - banner motd "hello world"
+ - hostname foo
+ match: strict
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'hostname foo' in result.commands"
+ - '''banner motd "hello world"'' in result.commands'
+
+- name: Configure top level command idempotent check
+ register: result
+ cisco.iosxr.iosxr_config:
+ commands:
+ - banner motd "hello world"
+ - hostname foo
+ match: strict
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ commands:
+ - hostname {{ inventory_hostname_short }}
+ match: none
+
+- ansible.builtin.debug: msg="END cli/toplevel_nonidempotent.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli_config/cli_backup.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli_config/cli_backup.yaml
new file mode 100644
index 00000000..acfa2cc3
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli_config/cli_backup.yaml
@@ -0,0 +1,59 @@
+---
+- ansible.builtin.debug: msg="END cli_config/backup.yaml on connection={{ ansible_connection }}"
+
+- name: Delete configurable backup file path
+ ansible.builtin.file:
+ path: "{{ item }}"
+ state: absent
+ with_items:
+ - "{{ role_path }}/backup_test_dir/"
+ - "{{ role_path }}/backup/backup.cfg"
+
+- name: Take configuration backup
+ become: true
+ register: result
+ ansible.netcommon.cli_config:
+ backup: true
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Take configuration backup in custom filename and directory path
+ become: true
+ register: result
+ ansible.netcommon.cli_config:
+ backup: true
+ backup_options:
+ filename: backup.cfg
+ dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Take configuration backup in custom filename
+ become: true
+ register: result
+ ansible.netcommon.cli_config:
+ backup: true
+ backup_options:
+ filename: backup.cfg
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Take configuration backup in custom path and default filename
+ become: true
+ register: result
+ ansible.netcommon.cli_config:
+ backup: true
+ backup_options:
+ dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- ansible.builtin.debug: msg="END cli_config/backup.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli_config/cli_basic.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli_config/cli_basic.yaml
new file mode 100644
index 00000000..18ffd2bc
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/cli_config/cli_basic.yaml
@@ -0,0 +1,28 @@
+---
+- ansible.builtin.debug: msg="START cli_config/cli_basic.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ become: true
+ ansible.netcommon.cli_config: &id002
+ config: "interface Loopback999\n no description\n no shutdown\n"
+
+- name: Configure device with configuration
+ register: result
+ become: true
+ ansible.netcommon.cli_config: &id001
+ config: "{{ lookup('template', 'basic/config.j2') }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Idempotence
+ register: result
+ ansible.netcommon.cli_config: *id001
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ ansible.netcommon.cli_config: *id002
+- ansible.builtin.debug: msg="END cli_config/cli_basic.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/redirection/shortname.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/redirection/shortname.yaml
new file mode 100644
index 00000000..d2eb4d5f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_config/tests/redirection/shortname.yaml
@@ -0,0 +1,27 @@
+---
+- ansible.builtin.debug: msg="START redirection/shortname.yaml on connection={{ ansible_connection }}"
+
+- name: Use src with module alias
+ register: result
+ cisco.iosxr.config:
+ src: basic/configuration.j2
+
+- ansible.builtin.assert:
+ that:
+ # make sure that the template content was read and not the path
+ - result.changed == true
+ - '"description test for ansible automation" in result.diff["prepared"]'
+
+- name: Use module alias to take configuration backup
+ register: result
+ cisco.iosxr.config:
+ backup: true
+ backup_options:
+ filename: backup_with_alias.cfg
+ dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- ansible.builtin.debug: msg="END redirection/shortname.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/defaults/main.yaml
new file mode 100644
index 00000000..9ef5ba51
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/meta/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/meta/main.yml
new file mode 100644
index 00000000..be631e5d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_iosxr_tests
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tasks/cli.yaml
new file mode 100644
index 00000000..59a889b4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tasks/cli.yaml
@@ -0,0 +1,20 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/cli"
+ patterns: "{{ testcase }}.yaml"
+ 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
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/all_facts.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/all_facts.yaml
new file mode 100644
index 00000000..7ba14f28
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/all_facts.yaml
@@ -0,0 +1,33 @@
+---
+- ansible.builtin.debug: msg="START cli/all_facts.yaml on connection={{ ansible_connection }}"
+
+- name: Test getting all facts
+ register: result
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - all
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - "'config' in result.ansible_facts.ansible_net_gather_subset"
+ - "'hardware' in result.ansible_facts.ansible_net_gather_subset"
+ - "'default' in result.ansible_facts.ansible_net_gather_subset"
+ - "'interfaces' in result.ansible_facts.ansible_net_gather_subset"
+ - result.ansible_facts.ansible_net_model == 'IOS-XRv 9000'
+ - result.ansible_facts.ansible_net_filesystems is defined
+
+- name: Collect list of available network resources for iosxr
+ register: result
+ cisco.iosxr.iosxr_facts:
+ available_network_resources: true
+ gather_network_resources: all
+
+- name: Assert that correct available_network_resources returned
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - "{{ result['ansible_facts']['available_network_resources'] | symmetric_difference(result['ansible_facts']['ansible_net_gather_network_resources']) |length\
+ \ == 0 }}"
+
+- ansible.builtin.debug: msg="END cli/all_facts.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/default_facts.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/default_facts.yaml
new file mode 100644
index 00000000..065f07bf
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/default_facts.yaml
@@ -0,0 +1,22 @@
+---
+- ansible.builtin.debug: msg="START cli/default_facts.yaml on connection={{ ansible_connection }}"
+
+- name: Test getting default facts
+ register: result
+ cisco.iosxr.iosxr_facts:
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - "'default' in result.ansible_facts.ansible_net_gather_subset"
+ - "'config' not in result.ansible_facts.ansible_net_gather_subset"
+ - result.ansible_facts.ansible_net_hostname is defined
+ - result.ansible_facts.ansible_net_image is defined
+ - result.ansible_facts.ansible_net_model is defined
+ - result.ansible_facts.ansible_net_python_version is defined
+ - result.ansible_facts.ansible_net_serialnum is defined
+ - result.ansible_facts.ansible_net_system is defined
+ - result.ansible_facts.ansible_net_version is defined
+ - result.ansible_facts.ansible_network_resources == {}
+
+- ansible.builtin.debug: msg="END cli/default.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/invalid_subset.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/invalid_subset.yaml
new file mode 100644
index 00000000..26284ddb
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/invalid_subset.yaml
@@ -0,0 +1,32 @@
+---
+- ansible.builtin.debug: msg="START cli/invalid_subset.yaml on connection={{ ansible_connection }}"
+
+- name: Test invalid subset (foobar)
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - foobar
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.failed == true
+ - result.msg == 'Subset must be one of [config, default, hardware, interfaces], got foobar'
+
+- name: Test subset specified multiple times
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!hardware"
+ - hardware
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.failed == true
+ - result.msg == 'Bad subset'
+ ignore_errors: true
+
+- ansible.builtin.debug: msg="END cli/invalid_subset.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/not_hardware.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/not_hardware.yaml
new file mode 100644
index 00000000..6591a872
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_facts/tests/cli/not_hardware.yaml
@@ -0,0 +1,20 @@
+---
+- ansible.builtin.debug: msg="START cli/not_hardware_facts.yaml on connection={{ ansible_connection }}"
+
+- name: Test not hardware
+ register: result
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!hardware"
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - "'config' in result.ansible_facts.ansible_net_gather_subset"
+ - "'default' in result.ansible_facts.ansible_net_gather_subset"
+ - "'interfaces' in result.ansible_facts.ansible_net_gather_subset"
+ - "'hardware' not in result.ansible_facts.ansible_net_gather_subset"
+ - result.ansible_facts.ansible_net_interfaces | length > 1
+ - result.ansible_facts.ansible_net_filesystems is not defined
+
+- ansible.builtin.debug: msg="END cli/not_hardware_facts.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/defaults/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/defaults/main.yml
new file mode 100644
index 00000000..871ea460
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+testcase: "[^_].*"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/meta/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/meta/main.yml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/meta/main.yml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tasks/cli.yaml
new file mode 100644
index 00000000..a1b57ab4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tasks/cli.yaml
@@ -0,0 +1,21 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/common"
+ 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
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tasks/main.yaml
new file mode 100644
index 00000000..f75f2f03
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/_parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/_parsed.cfg
new file mode 100644
index 00000000..309b8238
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/_parsed.cfg
@@ -0,0 +1 @@
+hostname test
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/_populate_config.yaml
new file mode 100644
index 00000000..c48c578e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/_populate_config.yaml
@@ -0,0 +1,6 @@
+---
+- name: Populate hostname configuration
+ cisco.iosxr.iosxr_hostname:
+ config:
+ hostname: "iosxr1"
+ state: merged
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/_remove_config.yaml
new file mode 100644
index 00000000..62851700
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/_remove_config.yaml
@@ -0,0 +1,5 @@
+---
+- name: Remove hostname configuration
+ cisco.iosxr.iosxr_hostname:
+ config:
+ state: deleted
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/deleted.yaml
new file mode 100644
index 00000000..e3b23dbd
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/deleted.yaml
@@ -0,0 +1,27 @@
+---
+- ansible.builtin.debug:
+ msg: Start Deleted integration state for iosxr_hostname ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Iosxr_hostname deleted - play
+ register: result
+ cisco.iosxr.iosxr_hostname:
+ config:
+ state: deleted
+
+ - name: Iosxr_hostname deleted - assert commands
+ ansible.builtin.assert:
+ that:
+ - deleted['commands'] == result['commands']
+
+ - name: Iosxr_hostname deleted - assert before
+ ansible.builtin.assert:
+ that:
+ - deleted['before'] == result['before']
+
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/empty_config.yaml
new file mode 100644
index 00000000..e76ab5a0
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_hostname empty_config.yaml integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_hostname:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_hostname:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_hostname:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_hostname:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_hostname:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/gathered.yaml
new file mode 100644
index 00000000..1cdd253a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/gathered.yaml
@@ -0,0 +1,20 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_hostname gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Ios_hostname gather - play
+ register: result
+ cisco.iosxr.iosxr_hostname:
+ config:
+ state: gathered
+
+ - name: Iosxr_hostname gather - assert
+ ansible.builtin.assert:
+ that:
+ - gathered['config'] == result['gathered']
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/merged.yaml
new file mode 100644
index 00000000..333eb069
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/merged.yaml
@@ -0,0 +1,33 @@
+---
+- ansible.builtin.debug:
+ msg: START Merged iosxr_hostname state for integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Iosxr_hostname merged - play
+ register: result
+ cisco.iosxr.iosxr_hostname: &id001
+ config:
+ hostname: "iosxr1"
+ state: merged
+
+ - name: Iosxr_hostname merged - assert commands
+ ansible.builtin.assert:
+ that:
+ - merged['commands'] == result['commands']
+
+ - name: Iosxr_hostname merged - assert after
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['after']
+
+ - name: Iosxr_hostname merged - play (idempotent)
+ register: result
+ cisco.iosxr.iosxr_hostname: *id001
+ - name: Iosxr_hostname merged - assert above task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/parsed.yaml
new file mode 100644
index 00000000..cfae6f30
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_hostname parsed integration tests on connection={{ ansible_connection }}
+
+- name: Iosxr_hostname parsed - play
+ register: result
+ cisco.iosxr.iosxr_hostname:
+ running_config: "{{ lookup('file', '_parsed.cfg') }}"
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - parsed['config'] == result['parsed']
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/rendered.yaml
new file mode 100644
index 00000000..11976100
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/tests/common/rendered.yaml
@@ -0,0 +1,16 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_hostname rendered integration tests ansible_connection={{ ansible_connection }}
+
+- block:
+ - name: Iosxr_hostname render - play
+ register: result
+ cisco.iosxr.iosxr_hostname:
+ config:
+ hostname: "test"
+ state: rendered
+
+ - ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.rendered == rendered['commands']
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/vars/main.yaml
new file mode 100644
index 00000000..fce4dc5f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_hostname/vars/main.yaml
@@ -0,0 +1,24 @@
+---
+merged:
+ commands:
+ - hostname iosxr1
+ after:
+ hostname: "iosxr1"
+
+deleted:
+ before:
+ hostname: "iosxr1"
+ commands:
+ - no hostname iosxr1
+
+parsed:
+ config:
+ hostname: "test"
+
+gathered:
+ config:
+ hostname: "iosxr1"
+
+rendered:
+ commands:
+ - hostname test
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/meta/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/meta/main.yaml
new file mode 100644
index 00000000..23d65c7e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/meta/main.yaml
@@ -0,0 +1,2 @@
+---
+dependencies: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_deleted.yaml
new file mode 100644
index 00000000..2ccf6abf
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_deleted.yaml
@@ -0,0 +1,38 @@
+---
+- ansible.builtin.debug:
+ msg: Start Deleted integration state for iosxr_interfaces ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete attributes of all configured interfaces
+ register: result
+ cisco.iosxr.iosxr_interfaces: &id001
+ state: deleted
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Delete attributes of all configured interfaces (idempotent)
+ register: result
+ cisco.iosxr.iosxr_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_overridden.yaml
new file mode 100644
index 00000000..7aa669f1
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_overridden.yaml
@@ -0,0 +1,45 @@
+---
+- ansible.builtin.debug:
+ msg: START Overridden iosxr_interfaces state for integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Override device configuration of all interfaces with provided configuration
+ register: result
+ cisco.iosxr.iosxr_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/1
+ description: Configured and Overridden by Ansible-Network
+ enabled: false
+ duplex: full
+ mtu: 2000
+ speed: 100
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Override device configuration of all interfaces with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_populate_config.yaml
new file mode 100644
index 00000000..4c565b79
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_populate_config.yaml
@@ -0,0 +1,18 @@
+---
+- name: "Populate configuration interface 0/0/0/0"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "description this is interface0"
+ - "mtu 65"
+ - "speed 10"
+ - "no shutdown"
+ parents: "interface GigabitEthernet 0/0/0/0"
+
+- name: "Populate configuration interface 0/0/0/1"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "description this is interface1"
+ - "mtu 65"
+ - "speed 10"
+ - "no shutdown"
+ parents: "interface GigabitEthernet 0/0/0/1"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..1512a4b3
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/_remove_config.yaml
@@ -0,0 +1,17 @@
+---
+- name: Remove configuration
+ vars:
+ lines: "interface loopback888\nno description\nno shutdown\ninterface loopback999\nno description\nno shutdown\n"
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
+
+- name: Remove interfaces from configuration before actual testing
+ loop:
+ - GigabitEthernet 0/0/0/0
+ - GigabitEthernet 0/0/0/1
+ - GigabitEthernet 0/0/0/2
+ - GigabitEthernet 0/0/0/3
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no interface {{ item }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..b8196c47
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_interfaces empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_interfaces:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_interfaces:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_interfaces:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_interfaces:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_interfaces:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/fixtures/parsed.cfg
new file mode 100644
index 00000000..7fe3ef97
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/fixtures/parsed.cfg
@@ -0,0 +1,19 @@
+interface Loopback888
+ description test for ansible
+ shutdown
+!
+interface MgmtEth0/RP0/CPU0/0
+ ipv4 address 10.8.38.70 255.255.255.0
+!
+interface GigabitEthernet0/0/0/0
+ description Configured and Merged by Ansible-Network
+ mtu 110
+ ipv4 address 172.31.1.1 255.255.255.0
+ duplex half
+!
+interface GigabitEthernet0/0/0/3
+ shutdown
+!
+interface GigabitEthernet0/0/0/4
+ shutdown
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/gathered.yaml
new file mode 100644
index 00000000..a10b40a6
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/gathered.yaml
@@ -0,0 +1,38 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_interfaces gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Merge provided configuration with device configuration
+ register: result
+ cisco.iosxr.iosxr_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ description: This interface is Configured and Merged by Ansible-Network
+ mtu: 110
+ enabled: true
+ duplex: half
+
+ - name: GigabitEthernet0/0/0/1
+ description: Configured and Merged by Ansible-Network
+ mtu: 2800
+ enabled: false
+ speed: 100
+ duplex: full
+ state: merged
+
+ - name: Gather interfaces facts using gathered state
+ register: result
+ cisco.iosxr.iosxr_interfaces:
+ state: gathered
+
+ - name: Assert that facts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ gathered['after'] | symmetric_difference(result['gathered']) |length == 0 }}"
+
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/merged.yaml
new file mode 100644
index 00000000..d8de4294
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/merged.yaml
@@ -0,0 +1,99 @@
+---
+- ansible.builtin.debug:
+ msg: START Merged iosxr_interfaces state for integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Merge provided configuration with device configuration
+ register: result
+ cisco.iosxr.iosxr_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+ description: Configured and Merged by Ansible-Network
+ mtu: 110
+ enabled: true
+ duplex: half
+
+ - name: GigabitEthernet0/0/0/1
+ description: Configured and Merged by Ansible-Network
+ mtu: 2800
+ enabled: false
+ speed: 100
+ duplex: full
+ state: merged
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Merge provided configuration with device configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.debug:
+ msg: START Merged interfaces configuration which are not in running config with iosxr_interfaces module on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+- block:
+ - name: Merge provided configuration with device configuration
+ register: result
+ cisco.iosxr.iosxr_interfaces: &id002
+ config:
+ - name: GigabitEthernet0/0/0/2
+ description: Configured and Merged by Ansible-Network
+ mtu: 110
+ enabled: true
+ duplex: half
+
+ - name: GigabitEthernet0/0/0/3
+ description: Configured and Merged by Ansible-Network
+ mtu: 2800
+ enabled: false
+ speed: 100
+ duplex: full
+ state: merged
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['preconfigure']['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['preconfigure']['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['preconfigure']['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Merge provided configuration with device configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_interfaces: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/parsed.yaml
new file mode 100644
index 00000000..0d68c20f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_interfaces parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided interfaces configuration to agnostic model
+ register: result
+ cisco.iosxr.iosxr_interfaces:
+ running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - "{{ parsed['after'] | symmetric_difference(result['parsed']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/rendered.yaml
new file mode 100644
index 00000000..0a5935d2
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/rendered.yaml
@@ -0,0 +1,26 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_interfaces rendered integration tests on connection={{ ansible_connection }}
+
+- name: Render platform specific commands from task input using rendered state
+ register: result
+ cisco.iosxr.iosxr_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ description: Configured and Merged by Ansible-Network
+ mtu: 110
+ enabled: true
+ duplex: half
+
+ - name: GigabitEthernet0/0/0/1
+ description: Configured and Merged by Ansible-Network
+ mtu: 2800
+ enabled: false
+ speed: 100
+ duplex: full
+ state: rendered
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - "{{ rendered['commands'] | symmetric_difference(result['rendered']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/replaced.yaml
new file mode 100644
index 00000000..c49fcd8b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/tests/cli/replaced.yaml
@@ -0,0 +1,46 @@
+---
+- ansible.builtin.debug:
+ msg: START Replaced iosxr_interfaces state for integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replaces device configuration of listed interfaces with provided configuration
+ register: result
+ cisco.iosxr.iosxr_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+ description: Configured and Replaced by Ansible-Network
+ mtu: 110
+
+ - name: GigabitEthernet0/0/0/1
+ description: Configured and Replaced by Ansible-Network
+ speed: 100
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Replaces device configuration of listed interfaces with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/vars/main.yaml
new file mode 100644
index 00000000..c4bb4fda
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_interfaces/vars/main.yaml
@@ -0,0 +1,231 @@
+---
+merged:
+ before:
+ - enabled: true
+ name: Loopback888
+ - enabled: true
+ name: Loopback999
+ - description: this is interface0
+ enabled: true
+ mtu: 65
+ name: GigabitEthernet0/0/0/0
+ speed: 10
+ - description: this is interface1
+ enabled: true
+ mtu: 65
+ name: GigabitEthernet0/0/0/1
+ speed: 10
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - description Configured and Merged by Ansible-Network
+ - mtu 110
+ - duplex half
+ - interface GigabitEthernet0/0/0/1
+ - description Configured and Merged by Ansible-Network
+ - mtu 2800
+ - speed 100
+ - duplex full
+ - shutdown
+ after:
+ - enabled: true
+ name: Loopback888
+ - enabled: true
+ name: Loopback999
+ - description: Configured and Merged by Ansible-Network
+ duplex: half
+ enabled: true
+ mtu: 110
+ name: GigabitEthernet0/0/0/0
+ speed: 10
+ - description: Configured and Merged by Ansible-Network
+ duplex: full
+ enabled: false
+ mtu: 2800
+ name: GigabitEthernet0/0/0/1
+ speed: 100
+ preconfigure:
+ before:
+ - enabled: true
+ name: Loopback888
+ - enabled: true
+ name: Loopback999
+ commands:
+ - interface GigabitEthernet0/0/0/2
+ - description Configured and Merged by Ansible-Network
+ - mtu 110
+ - duplex half
+ - no shutdown
+ - interface GigabitEthernet0/0/0/3
+ - description Configured and Merged by Ansible-Network
+ - mtu 2800
+ - speed 100
+ - duplex full
+ - shutdown
+ after:
+ - enabled: true
+ name: Loopback888
+ - enabled: true
+ name: Loopback999
+ - description: Configured and Merged by Ansible-Network
+ duplex: half
+ enabled: true
+ mtu: 110
+ name: GigabitEthernet0/0/0/2
+ - description: Configured and Merged by Ansible-Network
+ duplex: full
+ enabled: false
+ mtu: 2800
+ speed: 100
+ name: GigabitEthernet0/0/0/3
+
+parsed:
+ after:
+ - description: test for ansible
+ enabled: false
+ name: Loopback888
+ - description: Configured and Merged by Ansible-Network
+ duplex: half
+ enabled: true
+ mtu: 110
+ name: GigabitEthernet0/0/0/0
+ - enabled: false
+ name: GigabitEthernet0/0/0/3
+ - enabled: false
+ name: GigabitEthernet0/0/0/4
+replaced:
+ before:
+ - enabled: true
+ name: Loopback888
+ - enabled: true
+ name: Loopback999
+ - description: this is interface0
+ enabled: true
+ mtu: 65
+ name: GigabitEthernet0/0/0/0
+ speed: 10
+ - description: this is interface1
+ enabled: true
+ mtu: 65
+ name: GigabitEthernet0/0/0/1
+ speed: 10
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - no speed
+ - description Configured and Replaced by Ansible-Network
+ - mtu 110
+ - interface GigabitEthernet0/0/0/1
+ - no mtu
+ - description Configured and Replaced by Ansible-Network
+ - speed 100
+ after:
+ - enabled: true
+ name: Loopback888
+ - enabled: true
+ name: Loopback999
+ - description: Configured and Replaced by Ansible-Network
+ enabled: true
+ mtu: 110
+ name: GigabitEthernet0/0/0/0
+ - description: Configured and Replaced by Ansible-Network
+ enabled: true
+ name: GigabitEthernet0/0/0/1
+ speed: 100
+rendered:
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - description Configured and Merged by Ansible-Network
+ - mtu 110
+ - duplex half
+ - no shutdown
+ - interface GigabitEthernet0/0/0/1
+ - description Configured and Merged by Ansible-Network
+ - mtu 2800
+ - speed 100
+ - duplex full
+ - shutdown
+overridden:
+ before:
+ - enabled: true
+ name: Loopback888
+ - enabled: true
+ name: Loopback999
+ - description: this is interface0
+ enabled: true
+ mtu: 65
+ name: GigabitEthernet0/0/0/0
+ speed: 10
+ - description: this is interface1
+ enabled: true
+ mtu: 65
+ name: GigabitEthernet0/0/0/1
+ speed: 10
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - no description
+ - no speed
+ - no mtu
+ - interface GigabitEthernet0/0/0/1
+ - description Configured and Overridden by Ansible-Network
+ - mtu 2000
+ - duplex full
+ - speed 100
+ - shutdown
+ after:
+ - enabled: true
+ name: Loopback888
+ - enabled: true
+ name: Loopback999
+ - description: Configured and Overridden by Ansible-Network
+ duplex: full
+ enabled: false
+ mtu: 2000
+ name: GigabitEthernet0/0/0/1
+ speed: 100
+gathered:
+ after:
+ - enabled: true
+ name: Loopback888
+ - enabled: true
+ name: Loopback999
+ - description: This interface is Configured and Merged by Ansible-Network
+ duplex: half
+ enabled: true
+ mtu: 110
+ name: GigabitEthernet0/0/0/0
+ speed: 10
+ - description: Configured and Merged by Ansible-Network
+ duplex: full
+ enabled: false
+ mtu: 2800
+ name: GigabitEthernet0/0/0/1
+ speed: 100
+deleted:
+ before:
+ - enabled: true
+ name: Loopback888
+ - enabled: true
+ name: Loopback999
+ - description: this is interface0
+ enabled: true
+ mtu: 65
+ name: GigabitEthernet0/0/0/0
+ speed: 10
+ - description: this is interface1
+ enabled: true
+ mtu: 65
+ name: GigabitEthernet0/0/0/1
+ speed: 10
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - no description
+ - no speed
+ - no mtu
+ - interface GigabitEthernet0/0/0/1
+ - no description
+ - no speed
+ - no mtu
+ after:
+ - enabled: true
+ name: Loopback888
+ - enabled: true
+ name: Loopback999
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/meta/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/meta/main.yaml
new file mode 100644
index 00000000..23d65c7e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/meta/main.yaml
@@ -0,0 +1,2 @@
+---
+dependencies: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/_populate_config.yaml
new file mode 100644
index 00000000..6eb91262
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/_populate_config.yaml
@@ -0,0 +1,8 @@
+---
+- name: Populate configuration
+ vars:
+ lines:
+ "interface GigabitEthernet 0/0/0/1\nl2transport l2protocol cpsv tunnel\nl2transport propagate remote-status\ninterface GigabitEthernet 0/0/0/4\nl2transport\
+ \ l2protocol cpsv tunnel\ninterface GigabitEthernet 0/0/0/3.900\nencapsulation dot1q 40 second-dot1q 60\n"
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..5b96e4a7
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/_remove_config.yaml
@@ -0,0 +1,8 @@
+---
+- name: Remove configuration
+ vars:
+ lines:
+ "interface GigabitEthernet 0/0/0/1\nno l2transport\nno interface GigabitEthernet 0/0/0/2\nno interface GigabitEthernet 0/0/0/3\nno interface GigabitEthernet\
+ \ 0/0/0/3.900\nno interface GigabitEthernet 0/0/0/4\n"
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/deleted.yaml
new file mode 100644
index 00000000..3d8b1c7f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/deleted.yaml
@@ -0,0 +1,38 @@
+---
+- ansible.builtin.debug:
+ msg: Start Deleted integration state for ios_l2_interfaces ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete layer 2 interfaces attributes of all configured interfaces
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces: &id001
+ state: deleted
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Delete layer 2 interfaces attributes of all configured interfaces (idempotent)
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..6acdd781
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_l2_interfaces empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_l2_interfaces:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_l2_interfaces:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_l2_interfaces:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_l2_interfaces:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_l2_interfaces:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/fixtures/parsed.cfg
new file mode 100644
index 00000000..8fb1ec66
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/fixtures/parsed.cfg
@@ -0,0 +1,16 @@
+interface Loopback888
+ description test for ansible
+ shutdown
+!
+interface MgmtEth0/RP0/CPU0/0
+ ipv4 address 10.8.38.70 255.255.255.0
+!
+interface GigabitEthernet0/0/0/1
+ l2transport
+ l2protocol cpsv tunnel
+ propagate remote-status
+ !
+!
+interface GigabitEthernet0/0/0/3.900
+ encapsulation dot1q 20 second-dot1q 40
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/gathered.yaml
new file mode 100644
index 00000000..4231d516
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/gathered.yaml
@@ -0,0 +1,35 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_l2_interfaces gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/1
+ l2transport: true
+ l2protocol:
+ - cpsv: tunnel
+ propagate: true
+
+ - name: GigabitEthernet0/0/0/3.900
+ encapsulation:
+ dot1q: 20
+ second_dot1q: 40
+
+ - name: GigabitEthernet0/0/0/4
+ state: merged
+
+ - name: Gather layer 2 interfaces facts using gathered state
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces:
+ state: gathered
+
+ - name: Assert that facts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['after'] | symmetric_difference(result['gathered']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/merged.yaml
new file mode 100644
index 00000000..e4a051fd
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/merged.yaml
@@ -0,0 +1,46 @@
+---
+- ansible.builtin.debug:
+ msg: START Merged ios_l2_interfaces state for integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge provided layer 2 configuration with device configuration
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/1
+ l2transport: true
+ l2protocol:
+ - cpsv: tunnel
+ propagate: true
+ - name: GigabitEthernet0/0/0/3.900
+ encapsulation:
+ dot1q: 20
+ second_dot1q: 40
+ state: merged
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Merge provided layer 2 configuration with device configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/overridden.yaml
new file mode 100644
index 00000000..8f347161
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/overridden.yaml
@@ -0,0 +1,47 @@
+---
+- ansible.builtin.debug:
+ msg: START Overridden ios_l2_interfaces state for integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Override device layer 2 configuration of all interfaces with provided configuration
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/4
+ l2transport: true
+ l2protocol:
+ - cpsv: tunnel
+ - name: GigabitEthernet0/0/0/3.900
+ encapsulation:
+ dot1q: 20
+ second_dot1q: 40
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Override device layer 2 configuration of all interfaces with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/parsed.yaml
new file mode 100644
index 00000000..82c06b18
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_l2_interfaces parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided layer 2 interfaces configuration to agnostic model
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces:
+ running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['parsed']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/rendered.yaml
new file mode 100644
index 00000000..5d5eafc9
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/rendered.yaml
@@ -0,0 +1,24 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_l2_interfaces rendered integration tests on connection={{ ansible_connection }}
+
+- name: Render platform specific commands from task input using rendered state
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/1
+ l2transport: true
+ l2protocol:
+ - cpsv: tunnel
+ propagate: true
+ - name: GigabitEthernet0/0/0/3.900
+ encapsulation:
+ dot1q: 20
+ second_dot1q: 40
+ - name: GigabitEthernet0/0/0/4
+ state: rendered
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/replaced.yaml
new file mode 100644
index 00000000..dfae20d5
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/tests/cli/replaced.yaml
@@ -0,0 +1,43 @@
+---
+- ansible.builtin.debug:
+ msg: START Replaced ios_l2_interfaces state for integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replaces device layer 2 configuration of listed interfaces with provided configuration
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/1
+ l2transport: true
+ l2protocol:
+ - cpsv: drop
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Replaces device layer 2 configuration of listed interfaces with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/vars/main.yaml
new file mode 100644
index 00000000..54c7ef62
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l2_interfaces/vars/main.yaml
@@ -0,0 +1,107 @@
+---
+merged:
+ before: []
+ commands:
+ - interface GigabitEthernet0/0/0/1
+ - l2transport l2protocol cpsv tunnel
+ - l2transport propagate remote-status
+ - interface GigabitEthernet0/0/0/3.900
+ - encapsulation dot1q 20 second-dot1q 40
+ after:
+ - l2protocol:
+ - cpsv: tunnel
+ l2transport: true
+ name: GigabitEthernet0/0/0/1
+ propagate: true
+ - name: GigabitEthernet0/0/0/3.900
+ encapsulation:
+ dot1q: 20
+ second_dot1q: 40
+
+replaced:
+ before:
+ - l2protocol:
+ - cpsv: tunnel
+ l2transport: true
+ name: GigabitEthernet0/0/0/1
+ propagate: true
+ - name: GigabitEthernet0/0/0/3.900
+ encapsulation:
+ dot1q: 40
+ second_dot1q: 60
+ - l2protocol:
+ - cpsv: tunnel
+ l2transport: true
+ name: GigabitEthernet0/0/0/4
+ commands:
+ - interface GigabitEthernet0/0/0/1
+ - no l2transport
+ - l2transport l2protocol cpsv drop
+ after:
+ - l2protocol:
+ - cpsv: drop
+ l2transport: true
+ name: GigabitEthernet0/0/0/1
+ - name: GigabitEthernet0/0/0/3.900
+ encapsulation:
+ dot1q: 40
+ second_dot1q: 60
+ - l2protocol:
+ - cpsv: tunnel
+ l2transport: true
+ name: GigabitEthernet0/0/0/4
+
+overridden:
+ before:
+ - l2protocol:
+ - cpsv: tunnel
+ l2transport: true
+ name: GigabitEthernet0/0/0/1
+ propagate: true
+ - name: GigabitEthernet0/0/0/3.900
+ encapsulation:
+ dot1q: 40
+ second_dot1q: 60
+ - l2protocol:
+ - cpsv: tunnel
+ l2transport: true
+ name: GigabitEthernet0/0/0/4
+ commands:
+ - interface GigabitEthernet0/0/0/1
+ - no l2transport
+ - interface GigabitEthernet0/0/0/3.900
+ - encapsulation dot1q 20 second-dot1q 40
+ after:
+ - name: GigabitEthernet0/0/0/3.900
+ encapsulation:
+ dot1q: 20
+ second_dot1q: 40
+ - l2protocol:
+ - cpsv: tunnel
+ l2transport: true
+ name: GigabitEthernet0/0/0/4
+deleted:
+ before:
+ - l2protocol:
+ - cpsv: tunnel
+ l2transport: true
+ name: GigabitEthernet0/0/0/1
+ propagate: true
+ - name: GigabitEthernet0/0/0/3.900
+ encapsulation:
+ dot1q: 40
+ second_dot1q: 60
+ - l2protocol:
+ - cpsv: tunnel
+ l2transport: true
+ name: GigabitEthernet0/0/0/4
+ commands:
+ - interface GigabitEthernet0/0/0/1
+ - no l2transport
+ - interface GigabitEthernet0/0/0/3.900
+ - no encapsulation dot1q
+ - interface GigabitEthernet0/0/0/4
+ - no l2transport
+ after:
+ - name: GigabitEthernet0/0/0/3.900
+ - name: GigabitEthernet0/0/0/4
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/meta/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/meta/main.yaml
new file mode 100644
index 00000000..23d65c7e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/meta/main.yaml
@@ -0,0 +1,2 @@
+---
+dependencies: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/_populate_config.yaml
new file mode 100644
index 00000000..a8dff61c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/_populate_config.yaml
@@ -0,0 +1,8 @@
+---
+- name: Populate configuration
+ vars:
+ lines:
+ "interface GigabitEthernet 0/0/0/0\nipv4 address 198.51.100.1 255.255.255.0\nipv6 address 2001:db8::/32\ninterface GigabitEthernet 0/0/0/1\nipv4 address\
+ \ 192.0.2.1 255.255.255.0\nipv4 address 192.0.2.2 255.255.255.0 secondary\n"
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..3813ccce
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/_remove_config.yaml
@@ -0,0 +1,6 @@
+---
+- name: Remove configuration
+ vars:
+ lines: "interface GigabitEthernet 0/0/0/0\nno ipv4 address\nno ipv6 address\ninterface GigabitEthernet 0/0/0/1\nno ipv4 address\nno ipv6 address\n"
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/deleted.yaml
new file mode 100644
index 00000000..b8562c85
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/deleted.yaml
@@ -0,0 +1,42 @@
+---
+- ansible.builtin.debug:
+ msg: Start Deleted integration state for iosxr_l3_interfaces ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete attributes of all configured interfaces
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+
+ - name: GigabitEthernet0/0/0/1
+ state: deleted
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Delete attributes of all configured interfaces (idempotent)
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..de3925d7
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_l3_interfaces empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_l3_interfaces:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_l3_interfaces:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_l3_interfaces:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_l3_interfaces:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_l3_interfaces:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/fixtures/parsed.cfg
new file mode 100644
index 00000000..38b5adde
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/fixtures/parsed.cfg
@@ -0,0 +1,31 @@
+interface Loopback888
+ description test for ansible
+ shutdown
+!
+interface MgmtEth0/RP0/CPU0/0
+ ipv4 address 10.8.38.70 255.255.255.0
+!
+interface GigabitEthernet0/0/0/0
+ description Configured and Merged by Ansible-Network
+ mtu 66
+ ipv4 address 192.0.2.1 255.255.255.0
+ ipv4 address 192.0.2.2 255.255.255.0 secondary
+ ipv6 address 2001:db8:0:3::/64
+ duplex half
+!
+interface GigabitEthernet0/0/0/1
+ description Configured and Merged by Ansible-Network
+ mtu 66
+ speed 100
+ duplex full
+ dot1q native vlan 10
+ l2transport
+ l2protocol cdp forward
+ l2protocol pvst tunnel
+ propagate remote-status
+ !
+!
+interface GigabitEthernet0/0/0/3
+ ipv4 address 192.0.22.1 255.255.255.0
+ ipv4 address 192.0.23.1 255.255.255.0
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/gathered.yaml
new file mode 100644
index 00000000..abd09c02
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/gathered.yaml
@@ -0,0 +1,35 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_l3_interfaces gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Gather the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ ipv4:
+ - address: 198.51.100.1/24
+
+ - name: GigabitEthernet0/0/0/1
+ ipv6:
+ - address: 2001:db8:0:3::/64
+ ipv4:
+ - address: 192.0.2.1/24
+
+ - address: 192.0.2.2/24
+ secondary: true
+ state: merged
+
+ - name: Gather layer 3 interfaces facts using gathered state
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces:
+ state: gathered
+
+ - name: Assert that facts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['after'] | symmetric_difference(result['gathered']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/merged.yaml
new file mode 100644
index 00000000..6660b9af
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/merged.yaml
@@ -0,0 +1,49 @@
+---
+- ansible.builtin.debug:
+ msg: START Merged iosxr_l3_interfaces state for integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge provided configuration with device configuration
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+ ipv4:
+ - address: 198.51.100.1/24
+
+ - name: GigabitEthernet0/0/0/1
+ ipv6:
+ - address: 2001:db8:0:3::/64
+ ipv4:
+ - address: 192.0.2.1/24
+
+ - address: 192.0.2.2/24
+ secondary: true
+ state: merged
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Merge provided configuration with device configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/overridden.yaml
new file mode 100644
index 00000000..ded36a39
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/overridden.yaml
@@ -0,0 +1,44 @@
+---
+- ansible.builtin.debug:
+ msg: START Overridden iosxr_l3_interfaces state for integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Override device configuration of all interfaces with provided configuration
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/1
+ ipv4:
+ - address: 198.51.102.1/24
+ ipv6:
+ - address: 2001:db8:1::/64
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Override device configuration of all interfaces with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/parsed.yaml
new file mode 100644
index 00000000..cb558916
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_l3_interfaces parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided layer 3 interfaces configuration to agnostic model
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces:
+ running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - "{{ parsed['after'] | symmetric_difference(result['parsed']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/rendered.yaml
new file mode 100644
index 00000000..76498b9b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/rendered.yaml
@@ -0,0 +1,26 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_l3_interfaces rendered integration tests on connection={{ ansible_connection }}
+
+- name: Render platform specific commands from task input using rendered state
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ ipv4:
+ - address: 198.51.100.1/24
+
+ - name: GigabitEthernet0/0/0/1
+ ipv6:
+ - address: 2001:db8:0:3::/64
+ ipv4:
+ - address: 192.0.2.1/24
+
+ - address: 192.0.2.2/24
+ secondary: true
+ state: rendered
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - "{{ rendered['commands'] | symmetric_difference(result['rendered']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/replaced.yaml
new file mode 100644
index 00000000..10a77a3c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/replaced.yaml
@@ -0,0 +1,45 @@
+---
+- ansible.builtin.debug:
+ msg: START Replaced iosxr_l3_interfaces state for integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replaces device configuration of listed interfaces with provided configuration
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+ ipv4:
+ - address: 203.0.113.27/24
+
+ - address: 203.0.114.1/24
+ secondary: true
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) | length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Replaces device configuration of listed interfaces with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/rtt.yaml
new file mode 100644
index 00000000..c90984a8
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/tests/cli/rtt.yaml
@@ -0,0 +1,39 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_l3_interfaces round trip integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Round trip test by applying the provided configuration (base config)
+ register: base_config
+ cisco.iosxr.iosxr_l3_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ ipv4:
+ - address: 198.51.100.1/24
+
+ - name: GigabitEthernet0/0/0/1
+ ipv6:
+ - address: 2001:db8:0:3::/64
+ ipv4:
+ - address: 192.0.2.1/24
+
+ - secondary: true
+ address: 192.0.2.2/24
+ state: merged
+
+ - name: Gather interfaces facts
+ register: l3facts_config
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - default
+ gather_network_resources:
+ - l3_interfaces
+
+ - name: Apply configuration from l3_interfaces facts generated (idempotent)
+ cisco.iosxr.iosxr_l3_interfaces:
+ config: "{{ l3facts_config['ansible_facts']['ansible_network_resources']['l3_interfaces'] }}"
+ state: merged
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/vars/main.yaml
new file mode 100644
index 00000000..c144276d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_l3_interfaces/vars/main.yaml
@@ -0,0 +1,133 @@
+---
+merged:
+ before:
+ - name: Loopback888
+ - name: Loopback999
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - ipv4 address 198.51.100.1 255.255.255.0
+ - interface GigabitEthernet0/0/0/1
+ - ipv4 address 192.0.2.2 255.255.255.0 secondary
+ - ipv4 address 192.0.2.1 255.255.255.0
+ - ipv6 address 2001:db8:0:3::/64
+ after:
+ - name: Loopback888
+ - name: Loopback999
+ - ipv4:
+ - address: 198.51.100.1 255.255.255.0
+ name: GigabitEthernet0/0/0/0
+ - ipv4:
+ - address: 192.0.2.1 255.255.255.0
+ - address: 192.0.2.2 255.255.255.0
+ secondary: true
+ ipv6:
+ - address: 2001:db8:0:3::/64
+ name: GigabitEthernet0/0/0/1
+replaced:
+ before:
+ - name: Loopback888
+ - name: Loopback999
+ - ipv4:
+ - address: 198.51.100.1 255.255.255.0
+ ipv6:
+ - address: 2001:db8::/32
+ name: GigabitEthernet0/0/0/0
+ - ipv4:
+ - address: 192.0.2.1 255.255.255.0
+ - address: 192.0.2.2 255.255.255.0
+ secondary: true
+ name: GigabitEthernet0/0/0/1
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - no ipv6 address
+ - ipv4 address 203.0.113.27 255.255.255.0
+ - ipv4 address 203.0.114.1 255.255.255.0 secondary
+ after:
+ - name: Loopback888
+ - name: Loopback999
+ - ipv4:
+ - address: 203.0.113.27 255.255.255.0
+ - address: 203.0.114.1 255.255.255.0
+ secondary: true
+ name: GigabitEthernet0/0/0/0
+ - ipv4:
+ - address: 192.0.2.1 255.255.255.0
+ - address: 192.0.2.2 255.255.255.0
+ secondary: true
+ name: GigabitEthernet0/0/0/1
+overridden:
+ before:
+ - name: Loopback888
+ - name: Loopback999
+ - ipv4:
+ - address: 198.51.100.1 255.255.255.0
+ ipv6:
+ - address: 2001:db8::/32
+ name: GigabitEthernet0/0/0/0
+ - ipv4:
+ - address: 192.0.2.1 255.255.255.0
+ - address: 192.0.2.2 255.255.255.0
+ secondary: true
+ name: GigabitEthernet0/0/0/1
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - no ipv4 address
+ - no ipv6 address
+ - interface GigabitEthernet0/0/0/1
+ - no ipv4 address
+ - ipv4 address 198.51.102.1 255.255.255.0
+ - ipv6 address 2001:db8:1::/64
+ after:
+ - name: Loopback888
+ - name: Loopback999
+ - ipv4:
+ - address: 198.51.102.1 255.255.255.0
+ ipv6:
+ - address: 2001:db8:1::/64
+ name: GigabitEthernet0/0/0/1
+rendered:
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - ipv4 address 198.51.100.1 255.255.255.0
+ - interface GigabitEthernet0/0/0/1
+ - ipv4 address 192.0.2.2 255.255.255.0 secondary
+ - ipv4 address 192.0.2.1 255.255.255.0
+ - ipv6 address 2001:db8:0:3::/64
+parsed:
+ after:
+ - name: Loopback888
+ - ipv6:
+ - address: 2001:db8:0:3::/64
+ ipv4:
+ - address: 192.0.2.1 255.255.255.0
+ - address: 192.0.2.2 255.255.255.0
+ secondary: true
+ name: GigabitEthernet0/0/0/0
+ - name: GigabitEthernet0/0/0/1
+ - ipv4:
+ - address: 192.0.22.1 255.255.255.0
+ - address: 192.0.23.1 255.255.255.0
+ name: GigabitEthernet0/0/0/3
+deleted:
+ before:
+ - name: Loopback888
+ - name: Loopback999
+ - ipv4:
+ - address: 198.51.100.1 255.255.255.0
+ ipv6:
+ - address: 2001:db8::/32
+ name: GigabitEthernet0/0/0/0
+ - ipv4:
+ - address: 192.0.2.1 255.255.255.0
+ - address: 192.0.2.2 255.255.255.0
+ secondary: true
+ name: GigabitEthernet0/0/0/1
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - no ipv4 address
+ - no ipv6 address
+ - interface GigabitEthernet0/0/0/1
+ - no ipv4 address
+ after:
+ - name: Loopback888
+ - name: Loopback999
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/_populate.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/_populate.yaml
new file mode 100644
index 00000000..12f38f4c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/_populate.yaml
@@ -0,0 +1,6 @@
+---
+- name: Setup
+ vars:
+ lines: "lacp system priority 12\nlacp system mac 00c1.4c00.bd16\n"
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..24c2846f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/_remove_config.yaml
@@ -0,0 +1,6 @@
+---
+- name: Remove configuration
+ vars:
+ lines: "no lacp system priority\nno lacp system mac\n"
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/deleted.yaml
new file mode 100644
index 00000000..c48f5018
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/deleted.yaml
@@ -0,0 +1,43 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_lacp deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Delete lacp attributes
+ register: result
+ cisco.iosxr.iosxr_lacp: &id001
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ populate == result['before'] }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] == result['after'] }}"
+
+ - name: Delete attributes of given interfaces (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lacp: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] == result['before'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..ce135f73
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/empty_config.yaml
@@ -0,0 +1,47 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lacp:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lacp:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lacp:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lacp:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/fixtures/parsed.cfg
new file mode 100644
index 00000000..5b16c0e8
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/fixtures/parsed.cfg
@@ -0,0 +1,2 @@
+lacp system mac 00c1.4c00.bd15
+lacp system priority 11
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/gathered.yaml
new file mode 100644
index 00000000..2cfb94cf
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/gathered.yaml
@@ -0,0 +1,27 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Gather the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_lacp:
+ config:
+ system:
+ priority: 11
+ mac:
+ address: 00c1.4c00.bd15
+ state: merged
+
+ - name: Gather lacp facts using gathered state
+ register: result
+ cisco.iosxr.iosxr_lacp:
+ state: gathered
+
+ - name: Assert that facts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['after'] == result['gathered'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/merged.yaml
new file mode 100644
index 00000000..1632c6a6
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/merged.yaml
@@ -0,0 +1,45 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp merged integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_lacp: &id001
+ config:
+ system:
+ priority: 11
+ mac:
+ address: 00c1.4c00.bd15
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['before'] == result['before'] }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['after'] }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lacp: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['before']}}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/parsed.yaml
new file mode 100644
index 00000000..b3b6fd59
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided lacp configuration to agnostic model
+ register: result
+ cisco.iosxr.iosxr_lacp:
+ running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - "{{ parsed['after'] == result['parsed'] }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/rendered.yaml
new file mode 100644
index 00000000..01e90962
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/rendered.yaml
@@ -0,0 +1,18 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp rendered integration tests on connection={{ ansible_connection }}
+
+- name: Render platform specific commands from task input using rendered state
+ register: result
+ cisco.iosxr.iosxr_lacp:
+ config:
+ system:
+ priority: 11
+ mac:
+ address: 00c1.4c00.bd15
+ state: rendered
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - "{{ rendered['commands'] | symmetric_difference(result['rendered']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/replaced.yaml
new file mode 100644
index 00000000..b03d542f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/replaced.yaml
@@ -0,0 +1,46 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp replaced integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Replace lacp configuration with provided configurations
+ register: result
+ cisco.iosxr.iosxr_lacp: &id001
+ config:
+ system:
+ priority: 11
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ populate == result['before'] }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] == result['after'] }}"
+
+ - name: Replace device configurations of listed interfaces with provided configurarions (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lacp: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] == result['before'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/rtt.yaml
new file mode 100644
index 00000000..24e9ce68
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/tests/cli/rtt.yaml
@@ -0,0 +1,50 @@
+---
+- ansible.builtin.debug:
+ msg: START isoxr_lacp round trip integration tests on connection={{ ansible_connection }}
+
+- block:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+ - name: Apply the provided configuration (base config)
+ register: base_config
+ cisco.iosxr.iosxr_lacp:
+ config:
+ system:
+ priority: 15
+ mac:
+ address: 00c1.4c00.bd16
+ state: merged
+
+ - name: Gather interfaces facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - lacp
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ cisco.iosxr.iosxr_lacp:
+ config:
+ system:
+ priority: 10
+ mac:
+ address: 00c1.4c00.bd10
+ state: merged
+
+ - name: Assert that changes were applied
+ ansible.builtin.assert:
+ that: "{{ round_trip['after'] == result['after'] }}"
+
+ - name: Revert back to base configuration using facts round trip
+ register: revert
+ cisco.iosxr.iosxr_lacp:
+ config: "{{ ansible_facts['network_resources']['lacp'] }}"
+ state: replaced
+
+ - name: Assert that configuration was reverted
+ ansible.builtin.assert:
+ that: "{{ base_config['after'] == revert['after'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/vars/main.yaml
new file mode 100644
index 00000000..dc7a5246
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp/vars/main.yaml
@@ -0,0 +1,44 @@
+---
+merged:
+ before: {}
+ commands:
+ - lacp system priority 11
+ - lacp system mac 00c1.4c00.bd15
+ after:
+ system:
+ priority: 11
+ mac:
+ address: 00c1.4c00.bd15
+populate:
+ system:
+ priority: 12
+ mac:
+ address: 00c1.4c00.bd16
+replaced:
+ commands:
+ - no lacp system mac
+ - lacp system priority 11
+ after:
+ system:
+ priority: 11
+rendered:
+ commands:
+ - lacp system priority 11
+ - lacp system mac 00c1.4c00.bd15
+parsed:
+ after:
+ system:
+ priority: 11
+ mac:
+ address: 00c1.4c00.bd15
+deleted:
+ commands:
+ - no lacp system priority
+ - no lacp system mac
+ after: {}
+round_trip:
+ after:
+ system:
+ priority: 10
+ mac:
+ address: 00c1.4c00.bd10
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/_populate.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/_populate.yaml
new file mode 100644
index 00000000..298d9ad1
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/_populate.yaml
@@ -0,0 +1,26 @@
+---
+- name: Setup bundle-ether10
+ cisco.iosxr.iosxr_config:
+ lines:
+ - lacp churn logging actor
+ - lacp switchover suppress-flaps 500
+ - lacp collector-max-delay 100
+ parents: interface Bundle-Ether10
+
+- name: Setup bundle-ether11
+ cisco.iosxr.iosxr_config:
+ lines:
+ - lacp system mac 00c2.4c00.bd15
+ parents: interface Bundle-Ether11
+
+- name: Setup gige0
+ cisco.iosxr.iosxr_config:
+ lines:
+ - lacp period 100
+ parents: interface GigabitEthernet0/0/0/0
+
+- name: Setup gige1
+ cisco.iosxr.iosxr_config:
+ lines:
+ - lacp period 200
+ parents: interface GigabitEthernet0/0/0/1
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..72892ae2
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/_remove_config.yaml
@@ -0,0 +1,27 @@
+---
+- name: Remove bundles
+ vars:
+ lines: "no interface Bundle-Ether10\nno interface Bundle-Ether11\nno interface Bundle-Ether12\n"
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
+
+- name: Remove lacp interface configuration
+ loop:
+ - 0/0/0/0
+ - 0/0/0/1
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no lacp period
+ - shutdown
+ parents: interface GigabitEthernet{{ item }}
+
+- name: Remove unwanted interfaces from configuration
+ loop:
+ - 0/0/0/2
+ - 0/0/0/3
+ - 0/0/0/4
+ - 0/0/0/5
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no interface GigabitEthernet{{ item }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/deleted.yaml
new file mode 100644
index 00000000..916884d4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/deleted.yaml
@@ -0,0 +1,44 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_lacp_interfaces deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Delete lacp attributes of all interfaces
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces: &id001
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ populate | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Delete lacp attributes of all interfaces (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands|length == 0
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..5e5794d9
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp_interfaces empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lacp_interfaces:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lacp_interfaces:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lacp_interfaces:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lacp_interfaces:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lacp_interfaces:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/fixtures/parsed.cfg
new file mode 100644
index 00000000..8e061b47
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/fixtures/parsed.cfg
@@ -0,0 +1,14 @@
+interface Bundle-Ether10
+ lacp churn logging actor
+ lacp switchover suppress-flaps 500
+ lacp collector-max-delay 100
+!
+interface Bundle-Ether11
+ lacp system mac 00c2.4c00.bd15
+!
+interface MgmtEth0/RP0/CPU0/0
+ ipv4 address 192.0.2.11 255.255.255.0
+!
+interface GigabitEthernet0/0/0/1
+ lacp period 200
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/gathered.yaml
new file mode 100644
index 00000000..527c3c0d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/gathered.yaml
@@ -0,0 +1,34 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp_interfaces gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces:
+ config:
+ - name: Bundle-Ether10
+ churn_logging: actor
+ collector_max_delay: 100
+ switchover_suppress_flaps: 500
+
+ - name: Bundle-Ether11
+ system:
+ mac: 00c2.4c00.bd15
+
+ - name: GigabitEthernet0/0/0/1
+ period: 100
+ state: merged
+
+ - name: Gather interfaces facts using gathered state
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces:
+ state: gathered
+
+ - name: Assert that facts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['after'] | symmetric_difference(result['gathered']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/merged.yaml
new file mode 100644
index 00000000..4ca41988
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/merged.yaml
@@ -0,0 +1,53 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp_interfaces merged integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces: &id001
+ config:
+ - name: Bundle-Ether10
+ churn_logging: actor
+ collector_max_delay: 100
+ switchover_suppress_flaps: 500
+
+ - name: Bundle-Ether11
+ system:
+ mac: 00c2.4c00.bd15
+
+ - name: GigabitEthernet0/0/0/1
+ period: 100
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/overridden.yaml
new file mode 100644
index 00000000..4dbe5b30
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/overridden.yaml
@@ -0,0 +1,52 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp_interfaces overridden integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Overridde all interface lacp configuration with provided configuration
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces: &id001
+ config:
+ - name: Bundle-Ether12
+ churn_logging: both
+ collector_max_delay: 100
+ switchover_suppress_flaps: 500
+
+ - name: GigabitEthernet0/0/0/1
+ period: 300
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ populate | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Overridde all interface lacp configuration with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/parsed.yaml
new file mode 100644
index 00000000..2f040447
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp_interfaces parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided lacp configuration to agnostic model
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces:
+ running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - "{{ parsed['after'] == result['parsed'] }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/rendered.yaml
new file mode 100644
index 00000000..11517fc9
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/rendered.yaml
@@ -0,0 +1,25 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp_interfaces rendered integration tests on connection={{ ansible_connection }}
+
+- name: Render platform specific commands from task input using rendered state
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces:
+ config:
+ - name: Bundle-Ether10
+ churn_logging: actor
+ collector_max_delay: 100
+ switchover_suppress_flaps: 500
+
+ - name: Bundle-Ether11
+ system:
+ mac: 00c2.4c00.bd15
+
+ - name: GigabitEthernet0/0/0/1
+ period: 200
+ state: rendered
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - "{{ rendered['commands'] | symmetric_difference(result['rendered']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/replaced.yaml
new file mode 100644
index 00000000..e1c68093
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/replaced.yaml
@@ -0,0 +1,50 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lacp_interfaces replaced integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Replace device configurations of listed interfaces with provided configurations
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces: &id001
+ config:
+ - name: Bundle-Ether10
+ churn_logging: partner
+
+ - name: GigabitEthernet0/0/0/1
+ period: 300
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ populate | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Replace device configurations of listed interfaces with provided configurarions (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/rtt.yaml
new file mode 100644
index 00000000..fe7a1726
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/tests/cli/rtt.yaml
@@ -0,0 +1,59 @@
+---
+- ansible.builtin.debug:
+ msg: START isoxr_lacp_interfaces round trip integration tests on connection={{ ansible_connection }}
+
+- block:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+ - name: Apply the provided configuration (base config)
+ register: base_config
+ cisco.iosxr.iosxr_lacp_interfaces:
+ config:
+ - name: Bundle-Ether10
+ churn_logging: actor
+ collector_max_delay: 200
+
+ - name: Bundle-Ether11
+ period: 100
+
+ - name: GigabitEthernet0/0/0/0
+ period: 200
+ state: merged
+
+ - name: Gather interfaces facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - lacp_interfaces
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ cisco.iosxr.iosxr_lacp_interfaces:
+ config:
+ - name: Bundle-Ether10
+ churn_logging: partner
+
+ - name: Bundle-Ether11
+ period: 200
+
+ - name: GigabitEthernet0/0/0/0
+ period: 300
+ state: overridden
+
+ - name: Assert that changes were applied
+ ansible.builtin.assert:
+ that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Revert back to base configuration using facts round trip
+ register: revert
+ cisco.iosxr.iosxr_lacp_interfaces:
+ config: "{{ ansible_facts['network_resources']['lacp_interfaces'] }}"
+ state: overridden
+
+ - name: Assert that configuration was reverted
+ ansible.builtin.assert:
+ that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/vars/main.yaml
new file mode 100644
index 00000000..1f1f5cf9
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lacp_interfaces/vars/main.yaml
@@ -0,0 +1,130 @@
+---
+merged:
+ before:
+ - name: GigabitEthernet0/0/0/0
+ - name: GigabitEthernet0/0/0/1
+ commands:
+ - interface Bundle-Ether10
+ - lacp churn logging actor
+ - lacp switchover suppress-flaps 500
+ - lacp collector-max-delay 100
+ - interface Bundle-Ether11
+ - lacp system mac 00c2.4c00.bd15
+ - interface GigabitEthernet0/0/0/1
+ - lacp period 100
+ after:
+ - name: Bundle-Ether10
+ churn_logging: actor
+ switchover_suppress_flaps: 500
+ collector_max_delay: 100
+ - name: Bundle-Ether11
+ system:
+ mac: 00c2.4c00.bd15
+ - name: GigabitEthernet0/0/0/0
+ - name: GigabitEthernet0/0/0/1
+ period: 100
+populate:
+ - name: Bundle-Ether10
+ churn_logging: actor
+ switchover_suppress_flaps: 500
+ collector_max_delay: 100
+ - name: Bundle-Ether11
+ system:
+ mac: 00c2.4c00.bd15
+ - name: GigabitEthernet0/0/0/0
+ period: 100
+ - name: GigabitEthernet0/0/0/1
+ period: 200
+replaced:
+ commands:
+ - interface Bundle-Ether10
+ - no lacp switchover suppress-flaps 500
+ - no lacp collector-max-delay 100
+ - lacp churn logging partner
+ - interface GigabitEthernet0/0/0/1
+ - lacp period 300
+ after:
+ - name: Bundle-Ether10
+ churn_logging: partner
+ - name: Bundle-Ether11
+ system:
+ mac: 00c2.4c00.bd15
+ - name: GigabitEthernet0/0/0/0
+ period: 100
+ - name: GigabitEthernet0/0/0/1
+ period: 300
+overridden:
+ commands:
+ - interface Bundle-Ether10
+ - no lacp switchover suppress-flaps 500
+ - no lacp collector-max-delay 100
+ - no lacp churn logging actor
+ - interface Bundle-Ether11
+ - no lacp system mac 00c2.4c00.bd15
+ - interface GigabitEthernet0/0/0/0
+ - no lacp period 100
+ - interface Bundle-Ether12
+ - lacp churn logging both
+ - lacp collector-max-delay 100
+ - lacp switchover suppress-flaps 500
+ - interface GigabitEthernet0/0/0/1
+ - lacp period 300
+ after:
+ - name: Bundle-Ether10
+ - name: Bundle-Ether11
+ - name: Bundle-Ether12
+ churn_logging: both
+ collector_max_delay: 100
+ switchover_suppress_flaps: 500
+ - name: GigabitEthernet0/0/0/0
+ - name: GigabitEthernet0/0/0/1
+ period: 300
+deleted:
+ commands:
+ - interface Bundle-Ether10
+ - no lacp switchover suppress-flaps 500
+ - no lacp collector-max-delay 100
+ - no lacp churn logging actor
+ - interface Bundle-Ether11
+ - no lacp system mac 00c2.4c00.bd15
+ - interface GigabitEthernet0/0/0/0
+ - no lacp period 100
+ - interface GigabitEthernet0/0/0/1
+ - no lacp period 200
+ after:
+ - name: Bundle-Ether10
+ - name: Bundle-Ether11
+ - name: GigabitEthernet0/0/0/0
+ - name: GigabitEthernet0/0/0/1
+round_trip:
+ after:
+ - name: Bundle-Ether10
+ churn_logging: partner
+ - name: Bundle-Ether11
+ period: 200
+ - name: GigabitEthernet0/0/0/0
+ period: 300
+ - name: GigabitEthernet0/0/0/1
+parsed:
+ after:
+ - name: Bundle-Ether10
+ churn_logging: actor
+ collector_max_delay: 100
+ switchover_suppress_flaps: 500
+
+ - name: Bundle-Ether11
+ system:
+ mac: 00c2.4c00.bd15
+
+ - name: GigabitEthernet0/0/0/1
+ period: 200
+rendered:
+ commands:
+ - "interface Bundle-Ether10"
+ - "lacp churn logging actor"
+ - "lacp switchover suppress-flaps 500"
+ - "lacp collector-max-delay 100"
+ - "interface Bundle-Ether11"
+ - "lacp system mac 00c2.4c00.bd15"
+ - "interface GigabitEthernet0/0/0/1"
+ - "lacp period 200"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/_populate_config.yaml
new file mode 100644
index 00000000..489bc2e5
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/_populate_config.yaml
@@ -0,0 +1,25 @@
+---
+- name: Setup
+ cisco.iosxr.iosxr_lag_interfaces:
+ config:
+ - name: Bundle-Ether10
+ mode: active
+ members:
+ - member: GigabitEthernet0/0/0/0
+ mode: inherit
+
+ - member: GigabitEthernet0/0/0/1
+ mode: passive
+ links:
+ max_active: 10
+ min_active: 2
+
+ - name: Bundle-Ether11
+ mode: active
+ members:
+ - member: GigabitEthernet0/0/0/8
+ mode: passive
+
+ - member: GigabitEthernet0/0/0/9
+ mode: passive
+ state: merged
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..f862a29c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/_remove_config.yaml
@@ -0,0 +1,31 @@
+---
+- name: Remove bundles
+ vars:
+ lines: "no interface Bundle-Ether10\nno interface Bundle-Ether11\nno interface Bundle-Ether12\n"
+ ignore_errors: true
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
+
+- name: Remove lag interface configuration
+ loop:
+ - 0/0/0/0
+ - 0/0/0/1
+ - 0/0/0/2
+ - 0/0/0/8
+ - 0/0/0/9
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no bundle id
+ - shutdown
+ parents: interface GigabitEthernet{{ item }}
+
+- name: Remove unwanted interfaces from configuration
+ loop:
+ - 0/0/0/2
+ - 0/0/0/8
+ - 0/0/0/9
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no interface GigabitEthernet{{ item }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/deleted.yaml
new file mode 100644
index 00000000..549c6ccf
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/deleted.yaml
@@ -0,0 +1,44 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_lag_interfaces deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete lag interfaces configuration
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces: &id001
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Delete lacp attributes of all interfaces (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands|length == 0
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..0d9505d7
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lag_interfaces empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lag_interfaces:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lag_interfaces:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lag_interfaces:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lag_interfaces:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lag_interfaces:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/fixtures/parsed.cfg
new file mode 100644
index 00000000..74fe481d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/fixtures/parsed.cfg
@@ -0,0 +1,30 @@
+interface Bundle-Ether10
+ lacp mode active
+ bundle maximum-active links 5
+ bundle minimum-active links 2
+!
+interface Bundle-Ether12
+!
+interface Loopback888
+ description test for ansible
+ shutdown
+!
+interface MgmtEth0/RP0/CPU0/0
+ ipv4 address 192.0.2.11 255.255.255.0
+!
+interface GigabitEthernet0/0/0/1
+ description 'GigabitEthernet - 1"
+ bundle id 10 mode inherit
+!
+interface GigabitEthernet0/0/0/2
+ description "GigabitEthernet - 2"
+ bundle id 12 mode passive
+!
+interface GigabitEthernet0/0/0/3
+ description "GigabitEthernet - 3"
+ bundle id 10 mode inherit
+!
+interface GigabitEthernet0/0/0/4
+ description "GigabitEthernet - 4"
+ bundle id 12 mode passive
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/gathered.yaml
new file mode 100644
index 00000000..353162c0
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/gathered.yaml
@@ -0,0 +1,43 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lag_interfaces gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Gather the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces:
+ config:
+ - name: Bundle-Ether10
+ mode: active
+ members:
+ - member: GigabitEthernet0/0/0/0
+ mode: inherit
+
+ - member: GigabitEthernet0/0/0/1
+ mode: passive
+ links:
+ max_active: 10
+ min_active: 2
+
+ - name: Bundle-Ether11
+ mode: active
+ members:
+ - member: GigabitEthernet0/0/0/8
+ mode: passive
+
+ - member: GigabitEthernet0/0/0/9
+ mode: passive
+ state: merged
+
+ - name: Gather lacp facts using gathered state
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces:
+ state: gathered
+
+ - name: Assert that facts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['after'] == result['gathered'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/merged.yaml
new file mode 100644
index 00000000..5191b38a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/merged.yaml
@@ -0,0 +1,62 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lag_interfaces merged integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces: &id001
+ config:
+ - name: Bundle-Ether10
+ mode: active
+ members:
+ - member: GigabitEthernet0/0/0/0
+ mode: inherit
+
+ - member: GigabitEthernet0/0/0/1
+ mode: passive
+ links:
+ max_active: 10
+ min_active: 2
+
+ - name: Bundle-Ether11
+ mode: active
+ members:
+ - member: GigabitEthernet0/0/0/8
+ mode: passive
+
+ - member: GigabitEthernet0/0/0/9
+ mode: passive
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/overridden.yaml
new file mode 100644
index 00000000..77c5ea02
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/overridden.yaml
@@ -0,0 +1,56 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lag_interfaces overridden integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Overridde all lag interface configuration with provided configuration
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces: &id001
+ config:
+ - name: Bundle-Ether11
+ mode: active
+ members:
+ - member: GigabitEthernet0/0/0/0
+ mode: active
+
+ - member: GigabitEthernet0/0/0/1
+ mode: active
+ links:
+ max_active: 10
+ min_active: 5
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Overridde all interface lag interface configuration with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/parsed.yaml
new file mode 100644
index 00000000..f410f64a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lag_interfaces parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided lag interfaces configuration to agnostic model
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces:
+ running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - "{{ parsed['after'] == result['parsed'] }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/rendered.yaml
new file mode 100644
index 00000000..185014b4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/rendered.yaml
@@ -0,0 +1,31 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lag_interfaces rendered integration tests on connection={{ ansible_connection }}
+
+- name: Render platform specific commands from task input using rendered state
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces:
+ config:
+ - name: Bundle-Ether10
+ members:
+ - member: GigabitEthernet0/0/0/1
+ mode: inherit
+ - member: GigabitEthernet0/0/0/3
+ mode: inherit
+ mode: active
+ links:
+ max_active: 5
+ min_active: 2
+
+ - name: Bundle-Ether12
+ members:
+ - member: GigabitEthernet0/0/0/2
+ mode: passive
+ - member: GigabitEthernet0/0/0/4
+ mode: passive
+ state: rendered
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - rendered['commands'].sort() == result['rendered'].sort()
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/replaced.yaml
new file mode 100644
index 00000000..90d78cc5
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/replaced.yaml
@@ -0,0 +1,53 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lag_interfaces replaced integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replace device configurations of listed interfaces with provided configurations
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces: &id001
+ config:
+ - name: Bundle-Ether10
+ mode: passive
+ members:
+ - member: GigabitEthernet0/0/0/0
+ mode: passive
+
+ - name: Bundle-Ether12
+ mode: active
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Replace device configurations of listed interfaces with provided configurarions (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/rtt.yaml
new file mode 100644
index 00000000..e80c283d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/tests/cli/rtt.yaml
@@ -0,0 +1,63 @@
+---
+- ansible.builtin.debug:
+ msg: START isoxr_lag_interfaces round trip integration tests on connection={{ ansible_connection }}
+
+- block:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+ - name: Apply the provided configuration (base config)
+ register: base_config
+ cisco.iosxr.iosxr_lag_interfaces:
+ config:
+ - name: Bundle-Ether10
+ mode: active
+ members:
+ - member: GigabitEthernet0/0/0/1
+ mode: passive
+ links:
+ max_active: 10
+ min_active: 2
+
+ - name: Bundle-Ether11
+ mode: passive
+ state: merged
+
+ - name: Gather interfaces facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - lag_interfaces
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ cisco.iosxr.iosxr_lag_interfaces:
+ config:
+ - name: Bundle-Ether10
+ members:
+ - member: GigabitEthernet0/0/0/9
+ mode: active
+
+ - member: GigabitEthernet0/0/0/8
+ mode: passive
+
+ - name: Bundle-Ether11
+ mode: active
+ state: overridden
+
+ - name: Assert that changes were applied
+ ansible.builtin.assert:
+ that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Revert back to base configuration using facts round trip
+ register: revert
+ cisco.iosxr.iosxr_lag_interfaces:
+ config: "{{ ansible_facts['network_resources']['lag_interfaces'] }}"
+ state: overridden
+
+ - name: Assert that configuration was reverted
+ ansible.builtin.assert:
+ that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/vars/main.yaml
new file mode 100644
index 00000000..b2b14a0c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lag_interfaces/vars/main.yaml
@@ -0,0 +1,168 @@
+---
+merged:
+ before: []
+ commands:
+ - interface Bundle-Ether10
+ - bundle minimum-active links 2
+ - bundle maximum-active links 10
+ - lacp mode active
+ - interface GigabitEthernet0/0/0/1
+ - bundle id 10 mode passive
+ - interface GigabitEthernet0/0/0/0
+ - bundle id 10 mode inherit
+ - interface Bundle-Ether11
+ - lacp mode active
+ - interface GigabitEthernet0/0/0/8
+ - bundle id 11 mode passive
+ - interface GigabitEthernet0/0/0/9
+ - bundle id 11 mode passive
+ after:
+ - name: Bundle-Ether10
+ links:
+ max_active: 10
+ min_active: 2
+ members:
+ - member: GigabitEthernet0/0/0/0
+ mode: inherit
+ - member: GigabitEthernet0/0/0/1
+ mode: passive
+ mode: active
+ - name: Bundle-Ether11
+ mode: active
+ members:
+ - member: GigabitEthernet0/0/0/8
+ mode: passive
+ - member: GigabitEthernet0/0/0/9
+ mode: passive
+replaced:
+ commands:
+ - interface Bundle-Ether10
+ - no bundle maximum-active links 10
+ - no bundle minimum-active links 2
+ - lacp mode passive
+ - interface GigabitEthernet0/0/0/1
+ - no bundle id
+ - interface GigabitEthernet0/0/0/0
+ - bundle id 10 mode passive
+ - interface Bundle-Ether12
+ - lacp mode active
+ after:
+ - members:
+ - member: GigabitEthernet0/0/0/0
+ mode: passive
+ mode: passive
+ name: Bundle-Ether10
+ - members:
+ - member: GigabitEthernet0/0/0/8
+ mode: passive
+ - member: GigabitEthernet0/0/0/9
+ mode: passive
+ mode: active
+ name: Bundle-Ether11
+ - mode: active
+ name: Bundle-Ether12
+overridden:
+ commands:
+ - interface Bundle-Ether10
+ - no bundle maximum-active links 10
+ - no bundle minimum-active links 2
+ - no lacp mode active
+ - interface GigabitEthernet0/0/0/0
+ - no bundle id
+ - interface GigabitEthernet0/0/0/1
+ - no bundle id
+ - interface Bundle-Ether11
+ - bundle minimum-active links 5
+ - bundle maximum-active links 10
+ - interface GigabitEthernet0/0/0/8
+ - no bundle id
+ - interface GigabitEthernet0/0/0/9
+ - no bundle id
+ - interface GigabitEthernet0/0/0/0
+ - bundle id 11 mode active
+ - interface GigabitEthernet0/0/0/1
+ - bundle id 11 mode active
+ after:
+ - name: Bundle-Ether10
+ - links:
+ max_active: 10
+ min_active: 5
+ members:
+ - member: GigabitEthernet0/0/0/0
+ mode: active
+ - member: GigabitEthernet0/0/0/1
+ mode: active
+ mode: active
+ name: Bundle-Ether11
+deleted:
+ commands:
+ - interface Bundle-Ether10
+ - no bundle maximum-active links 10
+ - no bundle minimum-active links 2
+ - no lacp mode active
+ - interface GigabitEthernet0/0/0/0
+ - no bundle id
+ - interface GigabitEthernet0/0/0/1
+ - no bundle id
+ - interface Bundle-Ether11
+ - no lacp mode active
+ - interface GigabitEthernet0/0/0/8
+ - no bundle id
+ - interface GigabitEthernet0/0/0/9
+ - no bundle id
+ after:
+ - name: Bundle-Ether10
+ - name: Bundle-Ether11
+round_trip:
+ after:
+ - members:
+ - member: GigabitEthernet0/0/0/8
+ mode: passive
+ - member: GigabitEthernet0/0/0/9
+ mode: active
+ name: Bundle-Ether10
+ - mode: active
+ name: Bundle-Ether11
+rendered:
+ commands:
+ - "interface Bundle-Ether10"
+ - "lacp mode active"
+ - "bundle maximum-active links 5"
+ - "bundle minimum-active links 2"
+ - "interface Bundle-Ether12"
+ - "interface Loopback888"
+ - "description test for ansible"
+ - "shutdown"
+ - "interface MgmtEth0/RP0/CPU0/0"
+ - "ipv4 address 192.0.2.11 255.255.255.0"
+ - "interface GigabitEthernet0/0/0/1"
+ - "description 'GigabitEthernet - 1'"
+ - "bundle id 10 mode inherit"
+ - "interface GigabitEthernet0/0/0/2"
+ - "description 'GigabitEthernet - 2'"
+ - "bundle id 12 mode passive"
+ - "interface GigabitEthernet0/0/0/3"
+ - "description 'GigabitEthernet - 3'"
+ - "bundle id 10 mode inherit"
+ - "interface GigabitEthernet0/0/0/4"
+ - "description 'GigabitEthernet - 4'"
+ - "bundle id 12 mode passive"
+parsed:
+ after:
+ - name: Bundle-Ether10
+ members:
+ - member: GigabitEthernet0/0/0/1
+ mode: inherit
+ - member: GigabitEthernet0/0/0/3
+ mode: inherit
+ mode: active
+ links:
+ max_active: 5
+ min_active: 2
+
+ - name: Bundle-Ether12
+ members:
+ - member: GigabitEthernet0/0/0/2
+ mode: passive
+ - member: GigabitEthernet0/0/0/4
+ mode: passive
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/_populate.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/_populate.yaml
new file mode 100644
index 00000000..e51c60d9
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/_populate.yaml
@@ -0,0 +1,9 @@
+---
+- name: Setup
+ vars:
+ lines:
+ "lldp reinit 2\nlldp holdtime 100\nlldp timer 3000\nlldp subinterfaces\
+ \ enable\nlldp tlv-select system-description disable\nlldp tlv-select management-address\
+ \ disable\n"
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..bf35acd4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/_remove_config.yaml
@@ -0,0 +1,6 @@
+---
+- name: Remove configuration
+ vars:
+ lines: "no lldp\n"
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/deleted.yaml
new file mode 100644
index 00000000..291caf30
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/deleted.yaml
@@ -0,0 +1,43 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_lldp_global deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Delete global lldp attributes
+ register: result
+ cisco.iosxr.iosxr_lldp_global: &id001
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['before'] }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] == result['after'] }}"
+
+ - name: Delete attributes of given interfaces (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lldp_global: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] == result['before'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..e1519c31
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/empty_config.yaml
@@ -0,0 +1,47 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_global empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lldp_global:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lldp_global:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lldp_global:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lldp_global:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/fixtures/parsed.cfg
new file mode 100644
index 00000000..4bd23847
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/fixtures/parsed.cfg
@@ -0,0 +1,10 @@
+lldp
+ timer 3000
+ reinit 2
+ subinterfaces enable
+ holdtime 100
+ tlv-select
+ management-address disable
+ system-description disable
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/gathered.yaml
new file mode 100644
index 00000000..4a2bf6ac
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/gathered.yaml
@@ -0,0 +1,31 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_global gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_lldp_global:
+ config:
+ holdtime: 100
+ reinit: 2
+ timer: 3000
+ subinterfaces: true
+ tlv_select:
+ management_address: false
+ system_description: false
+ state: merged
+
+ - name: Gather interfaces facts using gathered state
+ register: result
+ cisco.iosxr.iosxr_lldp_global:
+ state: gathered
+
+ - name: Assert that facts were correctly generated
+ ansible.builtin.assert:
+ that: merged['after'] == result['gathered']
+
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/merged.yaml
new file mode 100644
index 00000000..2dab5aea
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/merged.yaml
@@ -0,0 +1,48 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_global merged integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_lldp_global: &id001
+ config:
+ holdtime: 100
+ reinit: 2
+ timer: 3000
+ subinterfaces: true
+ tlv_select:
+ management_address: false
+ system_description: false
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['before'] == result['before'] }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['after'] }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lldp_global: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['before']}}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/parsed.yaml
new file mode 100644
index 00000000..e163743e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_global parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided lacp configuration to agnostic model
+ register: result
+ cisco.iosxr.iosxr_lldp_global:
+ running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - "{{ parsed['after'] == result['parsed'] }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/rendered.yaml
new file mode 100644
index 00000000..853637d7
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/rendered.yaml
@@ -0,0 +1,21 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_global rendered integration tests on connection={{ ansible_connection }}
+
+- name: Render platform specific commands from task input using rendered stateion
+ register: result
+ cisco.iosxr.iosxr_lldp_global:
+ config:
+ holdtime: 100
+ reinit: 2
+ timer: 3000
+ subinterfaces: true
+ tlv_select:
+ management_address: false
+ system_description: false
+ state: rendered
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - "{{ rendered['commands'] | symmetric_difference(result['rendered']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/replaced.yaml
new file mode 100644
index 00000000..13a8c5fc
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/replaced.yaml
@@ -0,0 +1,49 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_global replaced integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Replace global lldp configuration with provided configurations
+ register: result
+ cisco.iosxr.iosxr_lldp_global: &id001
+ config:
+ holdtime: 100
+ tlv_select:
+ port_description: false
+ system_description: false
+ management_address: false
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['before'] }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] == result['after'] }}"
+
+ - name: Replace device global lldp configurations with provided configurarions (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lldp_global: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] == result['before'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/rtt.yaml
new file mode 100644
index 00000000..c35715bb
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/tests/cli/rtt.yaml
@@ -0,0 +1,48 @@
+---
+- ansible.builtin.debug:
+ msg: START isoxr_lldp_global round trip integration tests on connection={{ ansible_connection }}
+
+- block:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+ - name: Apply the provided configuration (base config)
+ register: base_config
+ cisco.iosxr.iosxr_lldp_global:
+ config:
+ holdtime: 200
+ timer: 500
+ state: merged
+
+ - name: Gather interfaces facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - lldp_global
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ cisco.iosxr.iosxr_lldp_global:
+ config:
+ holdtime: 200
+ reinit: 4
+ subinterfaces: true
+ timer: 3000
+ state: merged
+
+ - name: Assert that changes were applied
+ ansible.builtin.assert:
+ that: "{{ round_trip['after'] == result['after'] }}"
+
+ - name: Revert back to base configuration using facts round trip
+ register: revert
+ cisco.iosxr.iosxr_lldp_global:
+ config: "{{ ansible_facts['network_resources']['lldp_global'] }}"
+ state: replaced
+
+ - name: Assert that configuration was reverted
+ ansible.builtin.assert:
+ that: "{{ base_config['after'] == revert['after'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/vars/main.yaml
new file mode 100644
index 00000000..8d6f0928
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_global/vars/main.yaml
@@ -0,0 +1,63 @@
+---
+merged:
+ before: {}
+ commands:
+ - lldp reinit 2
+ - lldp holdtime 100
+ - lldp timer 3000
+ - lldp subinterfaces enable
+ - lldp tlv-select system-description disable
+ - lldp tlv-select management-address disable
+ after:
+ holdtime: 100
+ reinit: 2
+ subinterfaces: true
+ timer: 3000
+ tlv_select:
+ management_address: false
+ system_description: false
+replaced:
+ commands:
+ - no lldp reinit 2
+ - no lldp subinterfaces enable
+ - no lldp timer 3000
+ - lldp tlv-select port-description disable
+ after:
+ holdtime: 100
+ tlv_select:
+ management_address: false
+ port_description: false
+ system_description: false
+deleted:
+ commands:
+ - no lldp holdtime 100
+ - no lldp reinit 2
+ - no lldp subinterfaces enable
+ - no lldp timer 3000
+ - no lldp tlv-select management-address disable
+ - no lldp tlv-select system-description disable
+ after: {}
+round_trip:
+ after:
+ holdtime: 200
+ reinit: 4
+ subinterfaces: true
+ timer: 3000
+
+parsed:
+ after:
+ holdtime: 100
+ reinit: 2
+ timer: 3000
+ subinterfaces: true
+ tlv_select:
+ management_address: false
+ system_description: false
+rendered:
+ commands:
+ - "lldp subinterfaces enable"
+ - "lldp holdtime 100"
+ - "lldp reinit 2"
+ - "lldp tlv-select system-description disable"
+ - "lldp tlv-select management-address disable"
+ - "lldp timer 3000"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/_populate.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/_populate.yaml
new file mode 100644
index 00000000..28531216
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/_populate.yaml
@@ -0,0 +1,12 @@
+---
+- name: Setup gige1
+ cisco.iosxr.iosxr_config:
+ lines:
+ - lldp receive disable
+ parents: interface GigabitEthernet0/0/0/1
+
+- name: Setup gige0
+ cisco.iosxr.iosxr_config:
+ lines:
+ - lldp transmit disable
+ parents: interface GigabitEthernet0/0/0/0
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..74ee5b41
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/_remove_config.yaml
@@ -0,0 +1,22 @@
+---
+- name: Remove lldp interface configuration
+ loop:
+ - 0/0/0/0
+ - 0/0/0/1
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no lldp
+ - shutdown
+ parents: interface GigabitEthernet{{ item }}
+
+- name: Remove unwanted interfaces from configuration
+ loop:
+ - 0/0/0/2
+ - 0/0/0/3
+ - 0/0/0/4
+ - 0/0/0/5
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no interface GigabitEthernet{{ item }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/deleted.yaml
new file mode 100644
index 00000000..572fb3f6
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/deleted.yaml
@@ -0,0 +1,44 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_lldp_interfaces deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Delete lldp attributes of all interfaces
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces: &id001
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ populate | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Delete lacp attributes of all interfaces (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands|length == 0
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..94c53a86
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_interfaces empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lldp_interfaces:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lldp_interfaces:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lldp_interfaces:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lldp_interfaces:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_lldp_interfaces:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/fixtures/parsed.cfg
new file mode 100644
index 00000000..8fbe03d5
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/fixtures/parsed.cfg
@@ -0,0 +1,16 @@
+interface TenGigE0/0/0/0
+ ipv4 address 192.0.2.11 255.255.255.192
+!
+interface preconfigure GigabitEthernet0/0/0/1
+ lldp
+ receive disable
+ destination mac-address
+ ieee-nearest-bridge
+ !
+ !
+!
+interface preconfigure GigabitEthernet0/0/0/2
+ lldp
+ transmit disable
+ destination mac-address
+ ieee-nearest-non-tmpr-bridge
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/gathered.yaml
new file mode 100644
index 00000000..ab9d0d0a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/gathered.yaml
@@ -0,0 +1,28 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_interfaces gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ transmit: false
+
+ - name: GigabitEthernet0/0/0/1
+ receive: false
+ state: merged
+
+ - name: Gather interfaces facts using gathered state
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces:
+ state: gathered
+
+ - name: Assert that facts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['after'] | symmetric_difference(result['gathered']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/merged.yaml
new file mode 100644
index 00000000..623bfe5c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/merged.yaml
@@ -0,0 +1,47 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_interfaces merged integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+ transmit: false
+
+ - name: GigabitEthernet0/0/0/1
+ receive: false
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/overridden.yaml
new file mode 100644
index 00000000..0267ab16
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/overridden.yaml
@@ -0,0 +1,47 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_interfaces overridden integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Overridde all interface lldp configuration with provided configuration
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+ transmit: false
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ populate | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Overridde all interface lacp configuration with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/parsed.yaml
new file mode 100644
index 00000000..7362cdbd
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_interfaces parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided lldp interfaces configuration to agnostic model
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces:
+ running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - "{{ parsed['config'] | symmetric_difference(result['parsed']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/rendered.yaml
new file mode 100644
index 00000000..98a47434
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/rendered.yaml
@@ -0,0 +1,24 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_interfaces rendered integration tests on connection={{ ansible_connection }}
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/1
+ destination:
+ mac_address: ieee-nearest-non-tmpr-bridge
+ transmit: false
+
+ - name: GigabitEthernet0/0/0/2
+ destination:
+ mac_address: ieee-nearest-bridge
+ receive: false
+ state: rendered
+
+ - name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - "{{ rendered['commands'] | symmetric_difference(result['rendered']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/replaced.yaml
new file mode 100644
index 00000000..ab789717
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/replaced.yaml
@@ -0,0 +1,47 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_interfaces replaced integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate.yaml
+
+- block:
+ - name: Replace device configurations of listed interfaces with provided configurations
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/1
+ transmit: false
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ populate | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Replace device configurations of listed interfaces with provided configurarions (idempotent)
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/rtt.yaml
new file mode 100644
index 00000000..38d007d9
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/tests/cli/rtt.yaml
@@ -0,0 +1,49 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_lldp_interfaces round trip integration tests on connection={{ ansible_connection }}
+
+- block:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+ - name: Apply the provided configuration (base config)
+ register: base_config
+ cisco.iosxr.iosxr_lldp_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ transmit: false
+ state: merged
+
+ - name: Gather interfaces facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - lldp_interfaces
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ cisco.iosxr.iosxr_lldp_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ receive: false
+
+ - name: GigabitEthernet0/0/0/1
+ transmit: false
+ state: overridden
+
+ - name: Assert that changes were applied
+ ansible.builtin.assert:
+ that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Revert back to base configuration using facts round trip
+ register: revert
+ cisco.iosxr.iosxr_lldp_interfaces:
+ config: "{{ ansible_facts['network_resources']['lldp_interfaces'] }}"
+ state: overridden
+
+ - name: Assert that configuration was reverted
+ ansible.builtin.assert:
+ that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/vars/main.yaml
new file mode 100644
index 00000000..403548b5
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_lldp_interfaces/vars/main.yaml
@@ -0,0 +1,73 @@
+---
+merged:
+ before:
+ - name: GigabitEthernet0/0/0/0
+ - name: GigabitEthernet0/0/0/1
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - lldp transmit disable
+ - interface GigabitEthernet0/0/0/1
+ - lldp receive disable
+ after:
+ - name: GigabitEthernet0/0/0/0
+ transmit: false
+ - name: GigabitEthernet0/0/0/1
+ receive: false
+populate:
+ - name: GigabitEthernet0/0/0/0
+ transmit: false
+ - name: GigabitEthernet0/0/0/1
+ receive: false
+replaced:
+ commands:
+ - interface GigabitEthernet0/0/0/1
+ - no lldp receive disable
+ - lldp transmit disable
+ after:
+ - name: GigabitEthernet0/0/0/0
+ transmit: false
+ - name: GigabitEthernet0/0/0/1
+ transmit: false
+overridden:
+ commands:
+ - interface GigabitEthernet0/0/0/1
+ - no lldp receive disable
+ after:
+ - name: GigabitEthernet0/0/0/0
+ transmit: false
+ - name: GigabitEthernet0/0/0/1
+deleted:
+ commands:
+ - interface GigabitEthernet0/0/0/0
+ - no lldp transmit disable
+ - interface GigabitEthernet0/0/0/1
+ - no lldp receive disable
+ after:
+ - name: GigabitEthernet0/0/0/0
+ - name: GigabitEthernet0/0/0/1
+round_trip:
+ after:
+ - name: GigabitEthernet0/0/0/0
+ receive: false
+ - name: GigabitEthernet0/0/0/1
+ transmit: false
+parsed:
+ config:
+ - name: TenGigE0/0/0/0
+ - name: GigabitEthernet0/0/0/2
+ destination:
+ mac_address: ieee-nearest-non-tmpr-bridge
+ transmit: false
+
+ - name: GigabitEthernet0/0/0/1
+ destination:
+ mac_address: ieee-nearest-bridge
+ receive: false
+rendered:
+ commands:
+ - "interface GigabitEthernet0/0/0/2"
+ - "lldp destination mac-address ieee-nearest-non-tmpr-bridge"
+ - "lldp transmit disable"
+ - "interface GigabitEthernet0/0/0/1"
+ - "lldp receive disable"
+ - "lldp destination mac-address ieee-nearest-bridge"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/defaults/main.yaml
new file mode 100644
index 00000000..9ef5ba51
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/meta/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/meta/main.yaml
new file mode 100644
index 00000000..be631e5d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_iosxr_tests
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tasks/cli.yaml
new file mode 100644
index 00000000..8ae46e43
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tasks/cli.yaml
@@ -0,0 +1,23 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/cli"
+ patterns: "{{ testcase }}.yaml"
+ 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
+ tags:
+ - network_cli
+
+- name: Reset connection
+ ansible.builtin.meta: reset_connection
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tasks/main.yaml
new file mode 100644
index 00000000..419a6cde
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tasks/main.yaml
@@ -0,0 +1,6 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+
+- name: Include the netconf tasks
+ ansible.builtin.include_tasks: netconf.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tasks/netconf.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tasks/netconf.yaml
new file mode 100644
index 00000000..e5f214d1
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tasks/netconf.yaml
@@ -0,0 +1,23 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/netconf"
+ patterns: "{{ testcase }}.yaml"
+ 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.netconf)
+ ansible.builtin.include_tasks: "{{ test_case_to_run }}"
+ vars:
+ ansible_connection: ansible.netcommon.netconf
+ with_items: "{{ test_items }}"
+ loop_control:
+ loop_var: test_case_to_run
+ tags:
+ - netconf
+
+- name: Reset connection
+ ansible.builtin.meta: reset_connection
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tests/cli/basic.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tests/cli/basic.yaml
new file mode 100644
index 00000000..02280f4a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tests/cli/basic.yaml
@@ -0,0 +1,140 @@
+---
+- name: Remove host logging
+ cisco.iosxr.iosxr_logging:
+ dest: host
+ name: 172.16.0.1
+ state: absent
+
+- name: Remove console logging
+ register: result
+ cisco.iosxr.iosxr_logging:
+ dest: console
+ state: absent
+
+- name: Remove buffered logging
+ register: result
+ cisco.iosxr.iosxr_logging:
+ dest: buffered
+ size: 2097155
+ state: absent
+
+- name: Set up syslog host logging
+ register: result
+ cisco.iosxr.iosxr_logging: &id001
+ dest: host
+ name: 172.16.0.1
+ level: errors
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"logging 172.16.0.1 vrf default severity error" in result.commands'
+
+- name: Set up syslog host logging (idempotent)
+ register: result
+ cisco.iosxr.iosxr_logging: *id001
+- ansible.builtin.assert: &id003
+ that:
+ - result.changed == false
+
+- name: Delete/disable syslog host logging
+ register: result
+ cisco.iosxr.iosxr_logging: &id002
+ dest: host
+ name: 172.16.0.1
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"no logging 172.16.0.1 vrf default" in result.commands'
+
+- name: Delete/disable syslog host logging (idempotent)
+ register: result
+ cisco.iosxr.iosxr_logging: *id002
+- ansible.builtin.assert: *id003
+- name: Add console logging with level warning
+ register: result
+ cisco.iosxr.iosxr_logging: &id004
+ dest: console
+ level: warning
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"logging console warning" in result.commands'
+
+- name: Console logging with level warning (idempotent)
+ register: result
+ cisco.iosxr.iosxr_logging: *id004
+- ansible.builtin.assert: *id003
+- name: Remove console logging with level warning
+ register: result
+ cisco.iosxr.iosxr_logging:
+ dest: console
+ level: warning
+ state: absent
+
+- ansible.builtin.assert: &id006
+ that:
+ - result.changed == true
+
+- name: Configure buffered logging size
+ register: result
+ cisco.iosxr.iosxr_logging: &id005
+ dest: buffered
+ size: 4800000
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"logging buffered 4800000" in result.commands'
+
+- name: Configure buffered logging size (idempotence)
+ register: result
+ cisco.iosxr.iosxr_logging: *id005
+- ansible.builtin.assert: *id003
+- name: Remove buffered logging size
+ register: result
+ cisco.iosxr.iosxr_logging:
+ dest: buffered
+ size: 4800000
+ state: absent
+
+- ansible.builtin.assert: *id006
+- name: Change logging parameters using aggregate
+ register: result
+ cisco.iosxr.iosxr_logging:
+ aggregate:
+ - dest: console
+ level: notifications
+
+ - dest: buffered
+ size: 4700000
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"logging buffered 4700000" in result.commands'
+ - '"logging console notifications" in result.commands'
+
+- name: Remove logging parameters using aggregate
+ register: result
+ cisco.iosxr.iosxr_logging:
+ aggregate:
+ - dest: console
+ level: notifications
+
+ - dest: buffered
+ size: 4700000
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"no logging console" in result.commands'
+ - '"no logging buffered" in result.commands'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tests/netconf/basic.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tests/netconf/basic.yaml
new file mode 100644
index 00000000..2bd05e51
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging/tests/netconf/basic.yaml
@@ -0,0 +1,208 @@
+---
+- name: Remove host logging
+ cisco.iosxr.iosxr_logging:
+ dest: host
+ name: 172.16.0.1
+ state: absent
+
+- name: Remove console logging
+ register: result
+ cisco.iosxr.iosxr_logging:
+ dest: console
+ level: warning
+ state: absent
+
+- name: Remove buffered logging
+ register: result
+ cisco.iosxr.iosxr_logging:
+ dest: buffered
+ size: 2097155
+ state: absent
+
+- name: Set up syslog host logging
+ register: result
+ cisco.iosxr.iosxr_logging: &id001
+ dest: host
+ name: 172.16.0.1
+ level: errors
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"172.16.0.1" in result.xml[0]'
+
+- name: Set up syslog host logging (idempotent)
+ register: result
+ cisco.iosxr.iosxr_logging: *id001
+- ansible.builtin.assert: &id003
+ that:
+ - result.changed == false
+
+- name: Delete/disable syslog host logging
+ register: result
+ cisco.iosxr.iosxr_logging: &id002
+ dest: host
+ name: 172.16.0.1
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"172.16.0.1" in result.xml[0]'
+ - '"delete" in result.xml[0]'
+
+- name: Delete/disable syslog host logging (idempotent)
+ register: result
+ cisco.iosxr.iosxr_logging: *id002
+- ansible.builtin.assert: *id003
+- name: Add console logging with level warning
+ register: result
+ cisco.iosxr.iosxr_logging: &id004
+ dest: console
+ level: warning
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"console" in result.xml[0]'
+ - '"warning" in result.xml[0]'
+
+- name: Console logging with level warning (idempotent)
+ register: result
+ cisco.iosxr.iosxr_logging: *id004
+- ansible.builtin.assert: *id003
+- name: Remove console logging with level warning
+ register: result
+ cisco.iosxr.iosxr_logging:
+ dest: console
+ level: warning
+ state: absent
+
+- ansible.builtin.assert: &id006
+ that:
+ - result.changed == true
+
+- name: Configure buffered logging size
+ register: result
+ cisco.iosxr.iosxr_logging: &id005
+ dest: buffered
+ size: 4800000
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"buffered" in result.xml[0]'
+ - '"4800000" in result.xml[0]'
+
+- name: Configure buffered logging size (idempotence)
+ register: result
+ cisco.iosxr.iosxr_logging: *id005
+- ansible.builtin.assert: *id003
+- name: Remove buffered logging size
+ register: result
+ cisco.iosxr.iosxr_logging:
+ dest: buffered
+ size: 4800000
+ state: absent
+
+- ansible.builtin.assert: *id006
+- name: Change logging parameters using aggregate
+ register: result
+ cisco.iosxr.iosxr_logging:
+ aggregate:
+ - dest: console
+ level: notifications
+
+ - dest: buffered
+ size: 4700000
+
+ - dest: monitor
+ level: alerts
+
+ - dest: host
+ name: 10.10.10.1
+ level: errors
+
+ - dest: host
+ name: 10.10.10.2
+
+ - dest: file
+ name: file1
+ size: 2048
+ level: critical
+ path: /file1
+
+ - dest: file
+ name: file2
+ size: 2048
+ path: /file2
+
+ - facility: local3
+
+ - hostnameprefix: host3
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"file1" in result.xml[0]'
+ - '"file2" in result.xml[0]'
+ - '"10.10.10.1" in result.xml[1]'
+ - '"10.10.10.2" in result.xml[1]'
+ - '"notice" in result.xml[2]'
+ - '"alert" in result.xml[3]'
+ - '"4700000" in result.xml[4]'
+ - '"debug" in result.xml[4]'
+ - '"local3" in result.xml[5]'
+ - '"host3" in result.xml[6]'
+
+- name: Remove logging parameters using aggregate
+ register: result
+ cisco.iosxr.iosxr_logging:
+ aggregate:
+ - dest: console
+ level: notifications
+
+ - dest: buffered
+ size: 4700000
+
+ - dest: monitor
+ level: alerts
+
+ - dest: host
+ name: 10.10.10.1
+ level: errors
+
+ - dest: host
+ name: 10.10.10.2
+
+ - dest: file
+ name: file1
+ size: 2048
+ level: critical
+
+ - dest: file
+ name: file2
+ size: 2048
+
+ - facility: local3
+
+ - hostnameprefix: host3
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"file1" in result.xml[0]'
+ - '"file2" in result.xml[0]'
+ - '"10.10.10.1" in result.xml[1]'
+ - '"10.10.10.2" in result.xml[1]'
+ - '"notice" in result.xml[2]'
+ - '"alert" in result.xml[3]'
+ - '"4700000" in result.xml[4]'
+ - '"debug" in result.xml[4]'
+ - '"local3" in result.xml[5]'
+ - '"host3" in result.xml[6]'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/defaults/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/defaults/main.yml
new file mode 100644
index 00000000..871ea460
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+testcase: "[^_].*"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/meta/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/meta/main.yml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/meta/main.yml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tasks/cli.yaml
new file mode 100644
index 00000000..1b019a5a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tasks/cli.yaml
@@ -0,0 +1,21 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/common"
+ 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)
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+ ansible.builtin.include_tasks: "{{ test_case_to_run }}"
+ with_items: "{{ test_items }}"
+ loop_control:
+ loop_var: test_case_to_run
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tasks/main.yaml
new file mode 100644
index 00000000..f75f2f03
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/_parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/_parsed.cfg
new file mode 100644
index 00000000..196fdc6c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/_parsed.cfg
@@ -0,0 +1,19 @@
+logging tls-server test
+ vrf test
+ trustpoint test2
+ tls-hostname test2
+!
+logging file test path test maxfilesize 1024 severity info
+logging ipv4 dscp af11
+logging trap informational
+logging events display-location
+logging monitor errors
+logging buffered 2097152
+logging buffered warnings
+!
+logging 1.1.1.1 vrf default severity critical port default
+!
+logging correlator buffer-size 1024
+logging localfilesize 1024
+logging source-interface GigabitEthernet0/0/0/0 vrf test
+logging hostnameprefix test
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/_populate_config.yaml
new file mode 100644
index 00000000..a124cb62
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/_populate_config.yaml
@@ -0,0 +1,23 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "logging tls-server test"
+ - " vrf test"
+ - " trustpoint test2"
+ - " tls-hostname test2"
+ - "logging file test path test maxfilesize 1024 severity info"
+ - "logging ipv4 dscp af11"
+ - "logging trap informational"
+ - "logging events display-location"
+ - "logging monitor errors"
+ - "logging buffered 2097152"
+ - "logging buffered warnings"
+ - "logging 1.1.1.1 vrf default severity critical port default"
+ - "logging correlator buffer-size 1024"
+ - "logging localfilesize 1024"
+ - "logging source-interface GigabitEthernet0/0/0/0 vrf test"
+ - "logging hostnameprefix test"
+
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/_remove_config.yaml
new file mode 100644
index 00000000..a6ce93fb
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/_remove_config.yaml
@@ -0,0 +1,6 @@
+---
+- name: "Remove logging configuration"
+ cisco.iosxr.iosxr_logging_global:
+ state: deleted
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/deleted.yaml
new file mode 100644
index 00000000..1f477028
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/deleted.yaml
@@ -0,0 +1,36 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_logging_global deleted integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete given logging_global configuration
+ become: true
+ register: result
+ cisco.iosxr.iosxr_logging_global: &deleted
+ state: deleted
+
+ - become: true
+ cisco.iosxr.iosxr_facts:
+ gather_network_resources: logging_global
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 13
+ - result.changed == true
+ - ansible_facts.network_resources.logging_global == result.after
+ - result.after == deleted.after
+
+ - name: Idempotency check
+ become: true
+ register: result
+ cisco.iosxr.iosxr_logging_global: *deleted
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 0
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/empty_config.yaml
new file mode 100644
index 00000000..529e437d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/empty_config.yaml
@@ -0,0 +1,50 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_logging_global empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_logging_global:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_logging_global:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_logging_global:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_logging_global:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
+
+- ansible.builtin.debug:
+ msg: END iosxr_logging_global empty_config integration tests on connection={{ ansible_connection }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/gathered.yaml
new file mode 100644
index 00000000..90ceeead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/gathered.yaml
@@ -0,0 +1,22 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_logging_global gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Gathered the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_logging_global:
+ config:
+ state: gathered
+
+ - name: Assert
+ ansible.builtin.assert:
+ that:
+ - merged.after == result.gathered
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/merged.yaml
new file mode 100644
index 00000000..c39b8564
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/merged.yaml
@@ -0,0 +1,63 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_logging_global merged integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ cisco.iosxr.iosxr_logging_global:
+ config:
+ buffered:
+ size: 2097152
+ severity: warnings
+ correlator:
+ buffer_size: 1024
+ events:
+ display_location: true
+ files:
+ - maxfilesize: 1024
+ name: test
+ path: test
+ severity: info
+ hostnameprefix: test
+ hosts:
+ - host: 1.1.1.1
+ port: default
+ severity: critical
+ vrf: default
+ ipv4:
+ dscp: af11
+ localfilesize: 1024
+ monitor:
+ severity: errors
+ source_interfaces:
+ - interface: GigabitEthernet0/0/0/0
+ vrf: test
+ tls_servers:
+ - name: test
+ tls_hostname: test2
+ trustpoint: test2
+ vrf: test
+ trap:
+ severity: informational
+ state: merged
+
+ register: result
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ result['before'] == {} }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['after']
+
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/overridden.yaml
new file mode 100644
index 00000000..7263cdad
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/overridden.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_logging_global overridden integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Override BGP configuration with provided configuration
+ cisco.iosxr.iosxr_logging_global:
+ config:
+ buffered:
+ severity: errors
+ correlator:
+ buffer_size: 1024
+ files:
+ - maxfilesize: 1024
+ name: test
+ path: test1
+ severity: info
+ hostnameprefix: test1
+ hosts:
+ - host: 1.1.1.3
+ port: default
+ severity: critical
+ vrf: default
+ ipv6:
+ dscp: af11
+ localfilesize: 1024
+ monitor:
+ severity: errors
+ tls_servers:
+ - name: test
+ tls_hostname: test2
+ trustpoint: test
+ vrf: test
+ trap:
+ severity: critical
+ state: overridden
+ register: result
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - replaced['after'] == result['after']
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['before']
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/parsed.yaml
new file mode 100644
index 00000000..3bdf408c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_logging_global parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided BGP configuration
+ register: result
+ cisco.iosxr.iosxr_logging_global:
+ running_config: "{{ lookup('file', './_parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['parsed']
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/rendered.yaml
new file mode 100644
index 00000000..5c3f4567
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/rendered.yaml
@@ -0,0 +1,59 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_logging_global rendered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- name: Render platform specific configuration lines with state rendered (without connecting to the device)
+ cisco.iosxr.iosxr_logging_global:
+ config:
+ buffered:
+ size: 2097152
+ severity: warnings
+ correlator:
+ buffer_size: 1024
+ events:
+ display_location: true
+ files:
+ - maxfilesize: 1024
+ name: test
+ path: test
+ severity: info
+ hostnameprefix: test
+ hosts:
+ - host: 1.1.1.1
+ port: default
+ severity: critical
+ vrf: default
+ ipv4:
+ dscp: af11
+ localfilesize: 1024
+ monitor:
+ severity: errors
+ source_interfaces:
+ - interface: GigabitEthernet0/0/0/0
+ vrf: test
+ tls_servers:
+ - name: test
+ tls_hostname: test2
+ trustpoint: test2
+ vrf: test
+ trap:
+ severity: informational
+ state: rendered
+ register: result
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - merged['commands'] == result['rendered']
+
+- name: Gather BGP facts
+ cisco.iosxr.iosxr_logging_global:
+ state: gathered
+ register: result
+
+- name: Ensure that no configuration changes were made
+ ansible.builtin.assert:
+ that:
+ - result.gathered == {}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/replaced.yaml
new file mode 100644
index 00000000..4b882120
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/tests/common/replaced.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_logging_global replaced integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replace BGP configuration with provided configuration
+ cisco.iosxr.iosxr_logging_global:
+ config:
+ buffered:
+ severity: errors
+ correlator:
+ buffer_size: 1024
+ files:
+ - maxfilesize: 1024
+ name: test
+ path: test1
+ severity: info
+ hostnameprefix: test1
+ hosts:
+ - host: 1.1.1.3
+ port: default
+ severity: critical
+ vrf: default
+ ipv6:
+ dscp: af11
+ localfilesize: 1024
+ monitor:
+ severity: errors
+ tls_servers:
+ - name: test
+ tls_hostname: test2
+ trustpoint: test
+ vrf: test
+ trap:
+ severity: critical
+ state: replaced
+ register: result
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - replaced['after'] == result['after']
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['before']
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/vars/main.yaml
new file mode 100644
index 00000000..0bc3459f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_logging_global/vars/main.yaml
@@ -0,0 +1,98 @@
+---
+merged:
+ commands:
+ - logging buffered 2097152
+ - logging buffered warnings
+ - logging correlator buffer-size 1024
+ - logging events display-location
+ - logging hostnameprefix test
+ - logging ipv4 dscp af11
+ - logging localfilesize 1024
+ - logging monitor errors
+ - logging trap informational
+ - logging 1.1.1.1 vrf default severity critical port default
+ - logging file test path test maxfilesize 1024 severity info
+ - logging source-interface GigabitEthernet0/0/0/0 vrf test
+ - logging tls-server test tls-hostname test2
+ - logging tls-server test trustpoint test2
+ - logging tls-server test vrf test
+ after:
+ buffered:
+ size: 2097152
+ severity: warnings
+ correlator:
+ buffer_size: 1024
+ events:
+ display_location: true
+ files:
+ - maxfilesize: 1024
+ name: test
+ path: test
+ severity: info
+ hostnameprefix: test
+ hosts:
+ - host: 1.1.1.1
+ port: default
+ severity: critical
+ vrf: default
+ ipv4:
+ dscp: af11
+ localfilesize: 1024
+ monitor:
+ severity: errors
+ source_interfaces:
+ - interface: GigabitEthernet0/0/0/0
+ vrf: test
+ tls_servers:
+ - name: test
+ tls_hostname: test2
+ trustpoint: test2
+ vrf: test
+ trap:
+ severity: informational
+
+deleted:
+ after: {}
+
+replaced:
+ commands:
+ - no logging buffered 2097152
+ - no logging events display-location
+ - no logging ipv4 dscp af11
+ - no logging 1.1.1.1 vrf default severity critical port default
+ - no logging source-interface GigabitEthernet0/0/0/0 vrf test
+ - logging buffered errors
+ - logging hostnameprefix test1
+ - logging ipv6 dscp af11
+ - logging trap critical
+ - logging 1.1.1.3 vrf default severity critical port default
+ - logging file test path test1 maxfilesize 1024 severity info
+ - logging tls-server test trustpoint test
+ after:
+ buffered:
+ severity: errors
+ correlator:
+ buffer_size: 1024
+ files:
+ - maxfilesize: 1024
+ name: test
+ path: test1
+ severity: info
+ hostnameprefix: test1
+ hosts:
+ - host: 1.1.1.3
+ port: default
+ severity: critical
+ vrf: default
+ ipv6:
+ dscp: af11
+ localfilesize: 1024
+ monitor:
+ severity: errors
+ tls_servers:
+ - name: test
+ tls_hostname: test2
+ trustpoint: test
+ vrf: test
+ trap:
+ severity: critical
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/defaults/main.yaml
new file mode 100644
index 00000000..9ef5ba51
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/meta/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/meta/main.yaml
new file mode 100644
index 00000000..be631e5d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_iosxr_tests
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/tasks/cli.yaml
new file mode 100644
index 00000000..05e3269d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/tasks/cli.yaml
@@ -0,0 +1,18 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/cli"
+ patterns: "{{ testcase }}.yaml"
+ 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/tests/cli/basic.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/tests/cli/basic.yaml
new file mode 100644
index 00000000..182752f6
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_netconf/tests/cli/basic.yaml
@@ -0,0 +1,65 @@
+---
+- ansible.builtin.debug: msg="START iosxr_netconf cli/basic.yaml on connection={{ ansible_connection }}"
+
+- name: Disable netconf service
+ cisco.iosxr.iosxr_netconf: &id003
+ state: absent
+
+- block:
+ - name: Enable netconf service
+ register: result
+ cisco.iosxr.iosxr_netconf:
+ netconf_port: 830
+ netconf_vrf: default
+ state: present
+
+ - ansible.builtin.assert: &id001
+ that:
+ - result.changed == true
+
+ - name: Check idempotence of enable netconf service
+ register: result
+ cisco.iosxr.iosxr_netconf:
+ netconf_port: 830
+ netconf_vrf: default
+ state: present
+
+ - ansible.builtin.assert: &id002
+ that:
+ - result.changed == false
+
+ - name: Change netconf port
+ register: result
+ cisco.iosxr.iosxr_netconf:
+ netconf_port: 9000
+ state: present
+
+ - ansible.builtin.assert: *id001
+ - name: Check idempotent of change netconf port
+ register: result
+ cisco.iosxr.iosxr_netconf:
+ netconf_port: 9000
+ state: present
+
+ - ansible.builtin.assert: *id002
+ - name: Add netconf VRF
+ register: result
+ cisco.iosxr.iosxr_netconf:
+ netconf_port: 9000
+ netconf_vrf: new_default
+ state: present
+
+ - ansible.builtin.assert: *id001
+ - name: Check idempotent of add netconf VRF
+ register: result
+ cisco.iosxr.iosxr_netconf:
+ netconf_port: 9000
+ netconf_vrf: new_default
+ state: present
+
+ - ansible.builtin.assert: *id002
+ always:
+ - name: Disable netconf service
+ cisco.iosxr.iosxr_netconf: *id003
+
+- ansible.builtin.debug: msg="END iosxr_netconf cli/basic.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/defaults/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/defaults/main.yml
new file mode 100644
index 00000000..871ea460
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+testcase: "[^_].*"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/meta/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/meta/main.yml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/meta/main.yml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tasks/cli.yaml
new file mode 100644
index 00000000..1b019a5a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tasks/cli.yaml
@@ -0,0 +1,21 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/common"
+ 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)
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+ ansible.builtin.include_tasks: "{{ test_case_to_run }}"
+ with_items: "{{ test_items }}"
+ loop_control:
+ loop_var: test_case_to_run
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tasks/main.yaml
new file mode 100644
index 00000000..f75f2f03
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/_parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/_parsed.cfg
new file mode 100644
index 00000000..8caadb07
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/_parsed.cfg
@@ -0,0 +1,29 @@
+ntp
+ max-associations 10
+ interface GigabitEthernet0/0/0/0
+ broadcast client
+ multicast client 224.0.0.8
+ multicast destination 224.0.0.8
+ !
+ authenticate
+ trusted-key 1
+ ipv4 dscp af11
+ ipv6 precedence routine
+ peer vrf siteC 192.0.2.1 iburst
+ server vrf siteD 192.0.2.2 burst
+ drift file apphost
+ drift aging time 0
+ master 1
+ access-group vrf siteA ipv4 peer PeerAcl3
+ access-group vrf siteA ipv4 serve ServeAcl2
+ access-group ipv4 peer PeerAcl1
+ access-group ipv4 serve ServeAcl1
+ access-group ipv4 serve-only ServeOnlyAcl1
+ access-group ipv4 query-only QueryOnlyAcl1
+ source vrf siteE GigabitEthernet0/0/0/0
+ source GigabitEthernet0/0/0/0
+ passive
+ broadcastdelay 1
+ update-calendar
+ log-internal-sync
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/_populate_config.yaml
new file mode 100644
index 00000000..cbf196c4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/_populate_config.yaml
@@ -0,0 +1,34 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "ntp"
+ - " max-associations 10"
+ - " interface GigabitEthernet0/0/0/0"
+ - " broadcast client"
+ - " multicast client 224.0.0.8"
+ - " multicast destination 224.0.0.8"
+ - " authenticate"
+ - " trusted-key 1"
+ - " ipv4 dscp af11"
+ - " ipv6 precedence routine"
+ - " peer vrf siteC 192.0.2.1 iburst"
+ - " server vrf siteD 192.0.2.2 burst"
+ - " drift file apphost"
+ - " drift aging time 0"
+ - " master 1"
+ - " access-group vrf siteA ipv4 peer PeerAcl3"
+ - " access-group vrf siteA ipv4 serve ServeAcl2"
+ - " access-group ipv4 peer PeerAcl1"
+ - " access-group ipv4 serve ServeAcl1"
+ - " access-group ipv4 serve-only ServeOnlyAcl1"
+ - " access-group ipv4 query-only QueryOnlyAcl1"
+ - " source vrf siteE GigabitEthernet0/0/0/0"
+ - " source GigabitEthernet0/0/0/0"
+ - " passive"
+ - " broadcastdelay 1"
+ - " update-calendar"
+ - " log-internal-sync"
+
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/_remove_config.yaml
new file mode 100644
index 00000000..84913e8c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/_remove_config.yaml
@@ -0,0 +1,6 @@
+---
+- name: "Remove ntp global configuration"
+ cisco.iosxr.iosxr_ntp_global:
+ state: deleted
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/deleted.yaml
new file mode 100644
index 00000000..0d5ded6a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/deleted.yaml
@@ -0,0 +1,36 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_ntp_global deleted integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete given ntp_global configuration
+ become: true
+ register: result
+ cisco.iosxr.iosxr_ntp_global: &deleted
+ state: deleted
+
+ - become: true
+ cisco.iosxr.iosxr_facts:
+ gather_network_resources: ntp_global
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 23
+ - result.changed == true
+ - ansible_facts.network_resources.ntp_global == result.after
+ - result.after == deleted.after
+
+ - name: Idempotency check
+ become: true
+ register: result
+ cisco.iosxr.iosxr_ntp_global: *deleted
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 0
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/empty_config.yaml
new file mode 100644
index 00000000..4e380804
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/empty_config.yaml
@@ -0,0 +1,50 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ntp_global empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ntp_global:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ntp_global:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ntp_global:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ntp_global:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
+
+- ansible.builtin.debug:
+ msg: END iosxr_ntp_global empty_config integration tests on connection={{ ansible_connection }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/gathered.yaml
new file mode 100644
index 00000000..8974e694
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/gathered.yaml
@@ -0,0 +1,22 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ntp_global gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Gathered the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_ntp_global:
+ config:
+ state: gathered
+
+ - name: Assert
+ ansible.builtin.assert:
+ that:
+ - merged.after == result.gathered
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/merged.yaml
new file mode 100644
index 00000000..0f13ddbe
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/merged.yaml
@@ -0,0 +1,74 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_ntp_global merged integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ cisco.iosxr.iosxr_ntp_global:
+ config:
+ access_group:
+ ipv4:
+ peer: PeerAcl1
+ query_only: QueryOnlyAcl1
+ serve: ServeAcl1
+ serve_only: ServeOnlyAcl1
+ vrfs:
+ - ipv4:
+ peer: PeerAcl3
+ serve: ServeAcl2
+ name: siteA
+ authenticate: true
+ broadcastdelay: 1
+ drift:
+ aging_time: 0
+ file: apphost
+ interfaces:
+ - name: GigabitEthernet0/0/0/0
+ multicast_client: 224.0.0.8
+ multicast_destination: 224.0.0.8
+ broadcast_client: true
+ ipv4:
+ dscp: af11
+ ipv6:
+ precedence: routine
+ log_internal_sync: true
+ master:
+ stratum: 1
+ max_associations: 10
+ passive: true
+ peers:
+ - iburst: true
+ peer: 192.0.2.1
+ vrf: siteC
+ servers:
+ - burst: true
+ server: 192.0.2.2
+ vrf: siteD
+ source_interface: GigabitEthernet0/0/0/0
+ source_vrfs:
+ - name: GigabitEthernet0/0/0/0
+ vrf: siteE
+ trusted_keys:
+ - key_id: 1
+ update_calendar: true
+
+ register: result
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ result['before'] == {} }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['after']
+
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/overridden.yaml
new file mode 100644
index 00000000..e4fa06dc
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/overridden.yaml
@@ -0,0 +1,76 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_ntp_global overridden integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Override BGP configuration with provided configuration
+ cisco.iosxr.iosxr_ntp_global:
+ state: overridden
+ config:
+ access_group:
+ ipv4:
+ peer: PeerAcl1
+ query_only: QueryOnlyAcl1
+ serve: ServeAcl4
+ serve_only: ServeOnlyAcl1
+ vrfs:
+ - ipv4:
+ peer: PeerAcl3
+ serve: ServeAcl2
+ name: siteA
+ authenticate: true
+ broadcastdelay: 1
+ drift:
+ aging_time: 0
+ file: apphost
+ interfaces:
+ - name: GigabitEthernet0/0/0/1
+ multicast_client: 224.0.0.8
+ multicast_destination: 224.0.0.8
+ broadcast_client: true
+ ipv4:
+ dscp: af12
+ ipv6:
+ precedence: routine
+ log_internal_sync: true
+ master:
+ stratum: 1
+ max_associations: 10
+ passive: true
+ peers:
+ - iburst: true
+ peer: 192.0.2.3
+ vrf: siteC
+ servers:
+ - burst: true
+ server: 192.0.2.2
+ vrf: siteD
+ source_interface: GigabitEthernet0/0/0/1
+ source_vrfs:
+ - name: GigabitEthernet0/0/0/0
+ vrf: siteE
+ trusted_keys:
+ - key_id: 1
+ update_calendar: true
+ register: result
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - replaced['after'] == result['after']
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['before']
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/parsed.yaml
new file mode 100644
index 00000000..4bae4e7d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ntp_global parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided ntp_global configuration
+ register: result
+ cisco.iosxr.iosxr_ntp_global:
+ running_config: "{{ lookup('file', './_parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['parsed']
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/rendered.yaml
new file mode 100644
index 00000000..b77ed565
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/rendered.yaml
@@ -0,0 +1,71 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ntp_global rendered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- name: Render platform specific configuration lines with state rendered (without connecting to the device)
+ cisco.iosxr.iosxr_ntp_global:
+ state: rendered
+ config:
+ access_group:
+ ipv4:
+ peer: PeerAcl1
+ query_only: QueryOnlyAcl1
+ serve: ServeAcl1
+ serve_only: ServeOnlyAcl1
+ vrfs:
+ - ipv4:
+ peer: PeerAcl3
+ serve: ServeAcl2
+ name: siteA
+ authenticate: true
+ broadcastdelay: 1
+ drift:
+ aging_time: 0
+ file: apphost
+ interfaces:
+ - name: GigabitEthernet0/0/0/0
+ multicast_client: 224.0.0.8
+ multicast_destination: 224.0.0.8
+ broadcast_client: true
+ ipv4:
+ dscp: af11
+ ipv6:
+ precedence: routine
+ log_internal_sync: true
+ master:
+ stratum: 1
+ max_associations: 10
+ passive: true
+ peers:
+ - iburst: true
+ peer: 192.0.2.1
+ vrf: siteC
+ servers:
+ - burst: true
+ server: 192.0.2.2
+ vrf: siteD
+ source_interface: GigabitEthernet0/0/0/0
+ source_vrfs:
+ - name: GigabitEthernet0/0/0/0
+ vrf: siteE
+ trusted_keys:
+ - key_id: 1
+ update_calendar: true
+ register: result
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - merged['commands'] == result['rendered']
+
+- name: Gather BGP facts
+ cisco.iosxr.iosxr_ntp_global:
+ state: gathered
+ register: result
+
+- name: Ensure that no configuration changes were made
+ ansible.builtin.assert:
+ that:
+ - result.gathered == {}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/replaced.yaml
new file mode 100644
index 00000000..9703e12d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/tests/common/replaced.yaml
@@ -0,0 +1,79 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_ntp_global replaced integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replace BGP configuration with provided configuration
+ cisco.iosxr.iosxr_ntp_global:
+ state: replaced
+ config:
+ access_group:
+ ipv4:
+ peer: PeerAcl1
+ query_only: QueryOnlyAcl1
+ serve: ServeAcl4
+ serve_only: ServeOnlyAcl1
+ vrfs:
+ - ipv4:
+ peer: PeerAcl3
+ serve: ServeAcl2
+ name: siteA
+ authenticate: true
+ broadcastdelay: 1
+ drift:
+ aging_time: 0
+ file: apphost
+ interfaces:
+ - name: GigabitEthernet0/0/0/1
+ multicast_client: 224.0.0.8
+ multicast_destination: 224.0.0.8
+ broadcast_client: true
+ ipv4:
+ dscp: af12
+ ipv6:
+ precedence: routine
+ log_internal_sync: true
+ master:
+ stratum: 1
+ max_associations: 10
+ passive: true
+ peers:
+ - iburst: true
+ peer: 192.0.2.3
+ vrf: siteC
+ servers:
+ - burst: true
+ server: 192.0.2.2
+ vrf: siteD
+ source_interface: GigabitEthernet0/0/0/1
+ source_vrfs:
+ - name: GigabitEthernet0/0/0/0
+ vrf: siteE
+ trusted_keys:
+ - key_id: 1
+ update_calendar: true
+ register: result
+
+ - ansible.builtin.debug:
+ msg: "{{ replaced['commands'] | symmetric_difference(result['commands']) }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - replaced['after'] == result['after']
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['before']
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/vars/main.yaml
new file mode 100644
index 00000000..0f2919b7
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ntp_global/vars/main.yaml
@@ -0,0 +1,136 @@
+---
+merged:
+ commands:
+ - ntp peer vrf siteC 192.0.2.1 iburst
+ - ntp server vrf siteD 192.0.2.2 burst
+ - ntp trusted-key 1
+ - ntp interface GigabitEthernet0/0/0/0 broadcast client
+ - ntp interface GigabitEthernet0/0/0/0 multicast destination 224.0.0.8
+ - ntp interface GigabitEthernet0/0/0/0 multicast client 224.0.0.8
+ - ntp vrf siteE source GigabitEthernet0/0/0/0
+ - ntp access-group vrf siteA ipv4 serve ServeAcl2
+ - ntp access-group vrf siteA ipv4 peer PeerAcl3
+ - ntp access-group ipv4 peer PeerAcl1
+ - ntp access-group ipv4 serve ServeAcl1
+ - ntp access-group ipv4 serve-only ServeOnlyAcl1
+ - ntp access-group ipv4 query-only QueryOnlyAcl1
+ - ntp authenticate
+ - ntp log-internal-sync
+ - ntp broadcastdelay 1
+ - ntp drift aging time 0
+ - ntp drift file apphost
+ - ntp ipv4 dscp af11
+ - ntp ipv6 precedence routine
+ - ntp max-associations 10
+ - ntp master 1
+ - ntp passive
+ - ntp update-calendar
+ - ntp source GigabitEthernet0/0/0/0
+
+ after:
+ access_group:
+ ipv4:
+ peer: PeerAcl1
+ query_only: QueryOnlyAcl1
+ serve: ServeAcl1
+ serve_only: ServeOnlyAcl1
+ vrfs:
+ - ipv4:
+ peer: PeerAcl3
+ serve: ServeAcl2
+ name: siteA
+ authenticate: true
+ broadcastdelay: 1
+ drift:
+ aging_time: 0
+ file: apphost
+ interfaces:
+ - name: GigabitEthernet0/0/0/0
+ multicast_client: 224.0.0.8
+ multicast_destination: 224.0.0.8
+ broadcast_client: true
+ ipv4:
+ dscp: af11
+ ipv6:
+ precedence: routine
+ log_internal_sync: true
+ master:
+ stratum: 1
+ max_associations: 10
+ passive: true
+ peers:
+ - iburst: true
+ peer: 192.0.2.1
+ vrf: siteC
+ servers:
+ - burst: true
+ server: 192.0.2.2
+ vrf: siteD
+ source_interface: GigabitEthernet0/0/0/0
+ source_vrfs:
+ - name: GigabitEthernet0/0/0/0
+ vrf: siteE
+ trusted_keys:
+ - key_id: 1
+ update_calendar: true
+
+deleted:
+ after: {}
+
+replaced:
+ commands:
+ - no ntp peer vrf siteC 192.0.2.1 iburst
+ - no ntp interface GigabitEthernet0/0/0/0
+ - ntp peer vrf siteC 192.0.2.3 iburst
+ - ntp interface GigabitEthernet0/0/0/1 broadcast client
+ - ntp interface GigabitEthernet0/0/0/1 multicast destination 224.0.0.8
+ - ntp interface GigabitEthernet0/0/0/1 multicast client 224.0.0.8
+ - ntp access-group ipv4 serve ServeAcl4
+ - ntp ipv4 dscp af12
+ - ntp source GigabitEthernet0/0/0/1
+ after:
+ access_group:
+ ipv4:
+ peer: PeerAcl1
+ query_only: QueryOnlyAcl1
+ serve: ServeAcl4
+ serve_only: ServeOnlyAcl1
+ vrfs:
+ - ipv4:
+ peer: PeerAcl3
+ serve: ServeAcl2
+ name: siteA
+ authenticate: true
+ broadcastdelay: 1
+ drift:
+ aging_time: 0
+ file: apphost
+ interfaces:
+ - name: GigabitEthernet0/0/0/1
+ multicast_client: 224.0.0.8
+ multicast_destination: 224.0.0.8
+ broadcast_client: true
+ ipv4:
+ dscp: af12
+ ipv6:
+ precedence: routine
+ log_internal_sync: true
+ master:
+ stratum: 1
+ max_associations: 10
+ passive: true
+ peers:
+ - iburst: true
+ peer: 192.0.2.3
+ vrf: siteC
+ servers:
+ - burst: true
+ server: 192.0.2.2
+ vrf: siteD
+ source_interface: GigabitEthernet0/0/0/1
+ source_vrfs:
+ - name: GigabitEthernet0/0/0/0
+ vrf: siteE
+ trusted_keys:
+ - key_id: 1
+ update_calendar: true
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/fixtures/parsed.cfg
new file mode 100644
index 00000000..b2677113
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/fixtures/parsed.cfg
@@ -0,0 +1,51 @@
+router ospf LAB3
+ area 0.0.0.3
+ interface GigabitEthernet0/0/0/0
+ cost 20
+ authentication message-digest keychain cisco
+ !
+ !
+!
+router ospfv3 10
+ area 11
+ cost 11
+ default-cost 5
+ !
+ area 22
+ default-cost 6
+ !
+!
+router ospfv3 26
+ authentication disable
+!
+router ospfv3 27
+ area 10
+ hello-interval 2
+ !
+!
+router ospfv3 30
+ cost 2
+ priority 1
+ mtu-ignore
+ packet-size 577
+ dead-interval 2
+ retransmit-interval 2
+ demand-circuit
+ hello-interval 1
+ transmit-delay 2
+ router-id 2.2.2.2
+ default-metric 10
+ area 11
+ default-cost 5
+ !
+ area 22
+ default-cost 6
+ !
+!
+router ospfv3 LAB3
+ area 0.0.0.2
+ interface GigabitEthernet0/0/0/0
+ cost 30
+ !
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/_populate_config.yaml
new file mode 100644
index 00000000..aeebcf9e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/_populate_config.yaml
@@ -0,0 +1,23 @@
+---
+- name: Setup (populate OSPF interfaces config)
+ cisco.iosxr.iosxr_ospf_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ type: gigabitethernet
+ address_family:
+ - afi: ipv4
+ processes:
+ - process_id: "LAB3"
+ area:
+ area_id: 0.0.0.3
+ cost: 20
+ authentication:
+ message_digest:
+ keychain: cisco
+ - afi: ipv6
+ processes:
+ - process_id: "LAB3"
+ area:
+ area_id: 0.0.0.2
+ cost: 30
+ state: merged
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..738d377b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/_remove_config.yaml
@@ -0,0 +1,7 @@
+---
+- name: Remove ospfv3 routes
+ vars:
+ lines: "no router ospf LAB3 \n no router ospfv3 LAB3 \n no router ospfv3 LAB \n no router ospf LAB \n no router ospf LAB1 \n no router ospfv3 LAB1 "
+ ignore_errors: true
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/deleted.yaml
new file mode 100644
index 00000000..eeeb90de
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/deleted.yaml
@@ -0,0 +1,74 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_ospf_interfaces deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete single OSPF interface
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+ type: gigabitethernet
+
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Delete a single OSPF process (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces: *id001
+ - ansible.builtin.assert: &id003
+ that:
+ - result.changed == false
+ - result.commands|length == 0
+
+ - ansible.builtin.include_tasks: _populate_config.yaml
+
+ - name: Delete all OSPF processes
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces: &id002
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Delete all OSPF processes (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert: *id003
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] == result['before'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..df23b9bc
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospf_interfaces empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospf_interfaces:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospf_interfaces:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Parsed with empty running_config should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospf_interfaces:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospf_interfaces:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospf_interfaces:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/gathered.yaml
new file mode 100644
index 00000000..a6737e78
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/gathered.yaml
@@ -0,0 +1,20 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospf_interfaces gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Gather OSPF interfaces facts from the device using iosxr_ospf_interfaces module
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces:
+ state: gathered
+
+ - ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['gathered']) | length == 0 }}"
+ - "result.changed == false"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/merged.yaml
new file mode 100644
index 00000000..70fc8c07
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/merged.yaml
@@ -0,0 +1,108 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospf interfaces merged integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+ type: gigabitethernet
+ address_family:
+ - afi: ipv4
+ processes:
+ - process_id: "LAB3"
+ area:
+ area_id: 0.0.0.3
+ cost: 20
+ authentication:
+ message_digest:
+ keychain: cisco
+ - afi: ipv6
+ processes:
+ - process_id: "LAB3"
+ area:
+ area_id: 0.0.0.2
+ cost: 30
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['before'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Update existing configuration using merged
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces: &id002
+ config:
+ - name: GigabitEthernet0/0/0/1
+ type: gigabitethernet
+ address_family:
+ - afi: ipv4
+ processes:
+ - process_id: "LAB3"
+ area:
+ area_id: 0.0.0.1
+ cost: 10
+ authentication:
+ message_digest:
+ keychain: lab1
+ - afi: ipv6
+ processes:
+ - process_id: "LAB3"
+ area:
+ area_id: 0.0.0.4
+ cost: 40
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) | length == 0 }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['update_commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['update_after'] | symmetric_difference(result['after']) | length == 0 }}"
+
+ - name: Update existing OSPF interfaces configuration using merged (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/overridden.yaml
new file mode 100644
index 00000000..8a9dcfe4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/overridden.yaml
@@ -0,0 +1,57 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospf_interfaces overridden integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Overridde all ospf_interfaces configuration with provided configuration
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/1
+ type: gigabitethernet
+ address_family:
+ - afi: ipv4
+ processes:
+ - process_id: "LAB1"
+ area:
+ area_id: 0.0.0.3
+ cost: 10
+ authentication:
+ message_digest:
+ keychain: iosxr
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Overridde all ospf_interfaces configuration with given configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/parsed.yaml
new file mode 100644
index 00000000..598d2d69
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/parsed.yaml
@@ -0,0 +1,15 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospf_interfaces parsed integration tests on connection={{ ansible_connection }}
+
+- block:
+ - name: Use parsed state to convert externally supplied device specific ospf_interfaces commands to structured format
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces:
+ running_config: "{{ lookup('file', '../../fixtures/parsed.cfg') }}"
+ state: parsed
+
+ - ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['parsed']) | length == 0 }}"
+ - "result.changed == false"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/rendered.yaml
new file mode 100644
index 00000000..c573a0e2
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/rendered.yaml
@@ -0,0 +1,46 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospf_interfaces rendered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Use rendered state to convert task input to device specific commands
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ type: gigabitethernet
+ address_family:
+ - afi: ipv4
+ processes:
+ - process_id: "LAB3"
+ area:
+ area_id: 0.0.0.3
+ cost: 20
+ authentication:
+ message_digest:
+ keychain: cisco
+ - afi: ipv6
+ processes:
+ - process_id: "LAB3"
+ area:
+ area_id: 0.0.0.2
+ cost: 30
+ state: rendered
+
+ - ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length==0 }}"
+ - "result.changed == false"
+
+ - name: Gather OSPF interfaces facts from the device and assert that its empty
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces:
+ state: gathered
+
+ - name: Make sure that rendered task actually did not make any changes to the device
+ ansible.builtin.assert:
+ that: "{{ result['gathered'] == [] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/replaced.yaml
new file mode 100644
index 00000000..f8fb5ce4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/replaced.yaml
@@ -0,0 +1,63 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospf_interfaces replaced integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replace device configurations of ospf_interfaces with provided configurations
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces: &id001
+ config:
+ - name: GigabitEthernet0/0/0/0
+ type: gigabitethernet
+ address_family:
+ - afi: ipv4
+ processes:
+ - process_id: "LAB3"
+ area:
+ area_id: 0.0.0.3
+ cost: 30
+ authentication:
+ message_digest:
+ keychain: ciscoiosxr
+ - afi: ipv6
+ processes:
+ - process_id: "LAB3"
+ area:
+ area_id: 0.0.0.2
+ cost: 30
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Replace device configurations of listed vrfs/global entry with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/rtt.yaml
new file mode 100644
index 00000000..8eb6c2da
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/tests/cli/rtt.yaml
@@ -0,0 +1,74 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospf_interfaces round trip integration tests on connection={{ ansible_connection }}
+
+- block:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+ - name: Apply the provided configuration (base config)
+ register: base_config
+ cisco.iosxr.iosxr_ospf_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/0
+ type: gigabitethernet
+ address_family:
+ - afi: ipv4
+ processes:
+ - process_id: "LAB3"
+ area:
+ area_id: 0.0.0.3
+ cost: 20
+ authentication:
+ message_digest:
+ keychain: cisco
+ - afi: ipv6
+ processes:
+ - process_id: "LAB3"
+ area:
+ area_id: 0.0.0.2
+ cost: 30
+ state: merged
+
+ - name: Gather ospf_interfaces facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - ospf_interfaces
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ cisco.iosxr.iosxr_ospf_interfaces:
+ config:
+ - name: GigabitEthernet0/0/0/1
+ type: gigabitethernet
+ address_family:
+ - afi: ipv4
+ processes:
+ - process_id: "LAB1"
+ area:
+ area_id: 0.0.0.3
+ cost: 10
+ authentication:
+ message_digest:
+ keychain: iosxr
+ state: overridden
+
+ - name: Assert that changes were applied
+ ansible.builtin.assert:
+ that:
+ - "{{ round_trip['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Revert back to base configuration using facts round trip
+ register: revert
+ cisco.iosxr.iosxr_ospf_interfaces:
+ config: "{{ ansible_facts['network_resources']['ospf_interfaces'] }}"
+ state: overridden
+
+ - name: Assert that configuration was reverted
+ ansible.builtin.assert:
+ that:
+ - "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/vars/main.yaml
new file mode 100644
index 00000000..95f5e7bf
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospf_interfaces/vars/main.yaml
@@ -0,0 +1,138 @@
+---
+merged:
+ before: []
+ commands:
+ - router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0 cost 20
+ - router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0 authentication message-digest
+ - router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0 authentication message-digest keychain cisco
+ - router ospfv3 LAB3 area 0.0.0.2 interface GigabitEthernet 0/0/0/0 cost 30
+
+ update_commands:
+ - router ospf LAB3 area 0.0.0.1 interface GigabitEthernet 0/0/0/1 cost 10
+ - router ospf LAB3 area 0.0.0.1 interface GigabitEthernet 0/0/0/1 authentication message-digest
+ - router ospf LAB3 area 0.0.0.1 interface GigabitEthernet 0/0/0/1 authentication message-digest keychain lab1
+ - router ospfv3 LAB3 area 0.0.0.4 interface GigabitEthernet 0/0/0/1 cost 40
+ after:
+ - address_family:
+ - afi: ipv4
+ authentication:
+ message_digest:
+ keychain: cisco
+ cost: 20
+ processes:
+ - area:
+ area_id: 0.0.0.3
+ process_id: "LAB3"
+ - afi: ipv6
+ cost: 30
+ processes:
+ - area:
+ area_id: 0.0.0.2
+ process_id: "LAB3"
+ name: GigabitEthernet0/0/0/0
+ type: gigabitethernet
+
+ update_after:
+ - address_family:
+ - afi: ipv4
+ authentication:
+ message_digest:
+ keychain: lab1
+ cost: 10
+ processes:
+ - area:
+ area_id: 0.0.0.1
+ process_id: "LAB3"
+ - afi: ipv6
+ cost: 40
+ processes:
+ - area:
+ area_id: 0.0.0.4
+ process_id: "LAB3"
+ name: GigabitEthernet0/0/0/1
+ type: gigabitethernet
+ - address_family:
+ - afi: ipv4
+ authentication:
+ message_digest:
+ keychain: cisco
+ cost: 20
+ processes:
+ - area:
+ area_id: 0.0.0.3
+ process_id: "LAB3"
+ - afi: ipv6
+ cost: 30
+ processes:
+ - area:
+ area_id: 0.0.0.2
+ process_id: "LAB3"
+ name: GigabitEthernet0/0/0/0
+ type: gigabitethernet
+replaced:
+ commands:
+ - router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0 cost 30
+ - router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0 authentication message-digest
+ - router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0 authentication message-digest keychain ciscoiosxr
+
+ after:
+ - address_family:
+ - afi: ipv4
+ authentication:
+ message_digest:
+ keychain: ciscoiosxr
+ cost: 30
+ processes:
+ - area:
+ area_id: 0.0.0.3
+ process_id: "LAB3"
+ - afi: ipv6
+ cost: 30
+ processes:
+ - area:
+ area_id: 0.0.0.2
+ process_id: "LAB3"
+ name: GigabitEthernet0/0/0/0
+ type: gigabitethernet
+
+overridden:
+ commands:
+ - no router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0
+ - no router ospfv3 LAB3 area 0.0.0.2 interface GigabitEthernet 0/0/0/0
+ - router ospf LAB1 area 0.0.0.3 interface GigabitEthernet 0/0/0/1 cost 10
+ - router ospf LAB1 area 0.0.0.3 interface GigabitEthernet 0/0/0/1 authentication message-digest
+ - router ospf LAB1 area 0.0.0.3 interface GigabitEthernet 0/0/0/1 authentication message-digest keychain iosxr
+
+ after:
+ - address_family:
+ - afi: ipv4
+ authentication:
+ message_digest:
+ keychain: iosxr
+ cost: 10
+ processes:
+ - area:
+ area_id: 0.0.0.3
+ process_id: "LAB1"
+ name: GigabitEthernet0/0/0/1
+ type: gigabitethernet
+deleted:
+ commands:
+ - no router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0
+ - no router ospfv3 LAB3 area 0.0.0.2 interface GigabitEthernet 0/0/0/0
+
+ after: []
+round_trip:
+ after:
+ - name: GigabitEthernet0/0/0/1
+ type: gigabitethernet
+ address_family:
+ - afi: ipv4
+ processes:
+ - process_id: "LAB1"
+ area:
+ area_id: 0.0.0.3
+ cost: 10
+ authentication:
+ message_digest:
+ keychain: iosxr
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/fixtures/parsed.cfg
new file mode 100644
index 00000000..f3861f84
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/fixtures/parsed.cfg
@@ -0,0 +1,42 @@
+Thu Jun 4 12:15:08.448 UTC
+router ospf 10
+ area 11
+ cost 11
+ default-cost 5
+ !
+ area 22
+ default-cost 6
+ !
+!
+router ospf 26
+ authentication message-digest keychain ansible1101pass
+ adjacency stagger 10 20
+!
+router ospf 27
+ area 10
+ hello-interval 2
+ !
+!
+router ospf 30
+ router-id 2.2.2.2
+ summary-in enable
+ external-out disable
+ cost 2
+ packet-size 577
+ passive disable
+ priority 1
+ mtu-ignore enable
+ flood-reduction disable
+ dead-interval 2
+ retransmit-interval 2
+ demand-circuit enable
+ hello-interval 1
+ transmit-delay 2
+ default-metric 10
+ area 11
+ default-cost 5
+ !
+ area 22
+ default-cost 6
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/_populate_config.yaml
new file mode 100644
index 00000000..18322e6e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/_populate_config.yaml
@@ -0,0 +1,46 @@
+---
+- name: Setup (populate ospfv2 routes)
+ cisco.iosxr.iosxr_ospfv2:
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - process_id: 26
+ adjacency_stagger:
+ min_adjacency: 10
+ max_adjacency: 20
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ - process_id: 10
+ areas:
+ - area_id: 11
+ default_cost: 5
+ cost: 11
+ - area_id: 22
+ default_cost: 6
+ - process_id: 30
+ areas:
+ - area_id: 11
+ default_cost: 5
+ - area_id: 22
+ default_cost: 6
+
+ cost: 2
+ default_metric: 10
+ transmit_delay: 2
+ hello_interval: 1
+ dead_interval: 2
+ retransmit_interval: 2
+ packet_size: 577
+ priority: 1
+ router_id: "2.2.2.2"
+ demand_circuit: enable
+ passive: disable
+ summary_in: enable
+ flood_reduction: disable
+ mtu_ignore: enable
+ external_out: disable
+ state: merged
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..db733bcc
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/_remove_config.yaml
@@ -0,0 +1,7 @@
+---
+- name: Remove ospfv2 routes
+ vars:
+ lines: "no router ospf 26\n no router ospf 27\n no router ospf 30\n no router ospf 10\n "
+ ignore_errors: true
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/deleted.yaml
new file mode 100644
index 00000000..9fb7bb8f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/deleted.yaml
@@ -0,0 +1,76 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_ospfv2 deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete single OSPF process network
+ register: result
+ cisco.iosxr.iosxr_ospfv2: &id001
+ config:
+ processes:
+ - process_id: 10
+ - process_id: 26
+ - process_id: 27
+ - process_id: 30
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] == result['before'] }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] == result['after'] }}"
+
+ - name: Delete a single OSPF process (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospfv2: *id001
+ - ansible.builtin.assert: &id003
+ that:
+ - result.changed == false
+ - result.commands|length == 0
+
+ - ansible.builtin.include_tasks: _populate_config.yaml
+
+ - name: Delete all OSPF processes
+ register: result
+ cisco.iosxr.iosxr_ospfv2: &id002
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] == result['before'] }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] == result['after'] }}"
+
+ - name: Delete all OSPF processes (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospfv2: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert: *id003
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] == result['before'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..4464f0cb
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv2 empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospfv2:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospfv2:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Parsed with empty running_config should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospfv2:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospfv2:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospfv2:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/gathered.yaml
new file mode 100644
index 00000000..e2dcdbbf
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/gathered.yaml
@@ -0,0 +1,18 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv2 gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Gather static routes facts from the device using iosxr_ospfv2 module
+ register: result
+ cisco.iosxr.iosxr_ospfv2:
+ state: gathered
+
+ - ansible.builtin.assert:
+ that: "{{ replaced['before'] == result['gathered'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/merged.yaml
new file mode 100644
index 00000000..2554f294
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/merged.yaml
@@ -0,0 +1,124 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv2 merged integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_ospfv2: &id001
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - process_id: 26
+ adjacency_stagger:
+ min_adjacency: 10
+ max_adjacency: 20
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ - process_id: 10
+ areas:
+ - area_id: 11
+ default_cost: 5
+ cost: 11
+ - area_id: 22
+ default_cost: 6
+ - process_id: 30
+ areas:
+ - area_id: 11
+ default_cost: 5
+ - area_id: 22
+ default_cost: 6
+
+ cost: 2
+ default_metric: 10
+ transmit_delay: 2
+ hello_interval: 1
+ dead_interval: 2
+ retransmit_interval: 2
+ packet_size: 577
+ priority: 1
+ router_id: "2.2.2.2"
+ demand_circuit: enable
+ passive: disable
+ summary_in: enable
+ flood_reduction: disable
+ mtu_ignore: enable
+ external_out: disable
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['before'] == result['before'] }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['after'] }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospfv2: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['before'] }}"
+
+ - name: Update existing configuration using merged
+ register: result
+ cisco.iosxr.iosxr_ospfv2: &id002
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - area_id: 30
+ dead_interval: 4
+ - process_id: 26
+ adjacency_stagger:
+ min_adjacency: 11
+ max_adjacency: 21
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['after'] == result['before'] }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['update_commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['update_after'] == result['after'] }}"
+
+ - name: Update existing ospfv2 configuration using merged (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospfv2: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/overridden.yaml
new file mode 100644
index 00000000..61d12c06
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/overridden.yaml
@@ -0,0 +1,60 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv2 overridden integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Overridde all ospfv2 configuration with provided configuration
+ register: result
+ cisco.iosxr.iosxr_ospfv2: &id001
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - area_id: 20
+ cost: 2
+ default_cost: 2
+ - process_id: 26
+ adjacency_stagger:
+ min_adjacency: 10
+ max_adjacency: 20
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] == result['before'] }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] == result['after'] }}"
+
+ - name: Overridde all ospfv2 configuration with given configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospfv2: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] == result['before'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/parsed.yaml
new file mode 100644
index 00000000..cfa8ccc0
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/parsed.yaml
@@ -0,0 +1,13 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv2 parsed integration tests on connection={{ ansible_connection }}
+
+- block:
+ - name: Use parsed state to convert externally supplied device specific ospfv2 routes commands to structured format
+ register: result
+ cisco.iosxr.iosxr_ospfv2:
+ running_config: "{{ lookup('file', '../../fixtures/parsed.cfg') }}"
+ state: parsed
+
+ - ansible.builtin.assert:
+ that: "{{ merged['after'] == result['parsed'] }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/rendered.yaml
new file mode 100644
index 00000000..b521881a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/rendered.yaml
@@ -0,0 +1,67 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv2 rendered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Use rendered state to convert task input to device specific commands
+ register: result
+ cisco.iosxr.iosxr_ospfv2:
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - process_id: 26
+ adjacency_stagger:
+ min_adjacency: 10
+ max_adjacency: 20
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ - process_id: 10
+ areas:
+ - area_id: 11
+ default_cost: 5
+ cost: 11
+ - area_id: 22
+ default_cost: 6
+ - process_id: 30
+ areas:
+ - area_id: 11
+ default_cost: 5
+ - area_id: 22
+ default_cost: 6
+
+ cost: 2
+ default_metric: 10
+ transmit_delay: 2
+ hello_interval: 1
+ dead_interval: 2
+ retransmit_interval: 2
+ packet_size: 577
+ priority: 1
+ router_id: "2.2.2.2"
+ demand_circuit: enable
+ passive: disable
+ summary_in: enable
+ flood_reduction: disable
+ mtu_ignore: enable
+ external_out: disable
+ state: rendered
+
+ - ansible.builtin.assert:
+ that: "{{ merged['commands'] | symmetric_difference(result['rendered']) |length==0 }}"
+
+ - name: Gather static routes facts from the device and assert that its empty
+ register: result
+ cisco.iosxr.iosxr_ospfv2:
+ state: gathered
+
+ - name: Make sure that rendered task actually did not make any changes to the device
+ ansible.builtin.assert:
+ that: "{{ result['gathered'] == {} }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/replaced.yaml
new file mode 100644
index 00000000..d9aad879
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/replaced.yaml
@@ -0,0 +1,60 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv2 replaced integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replace device configurations of ospfv2 routes with provided configurations
+ register: result
+ cisco.iosxr.iosxr_ospfv2: &id001
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - area_id: 20
+ cost: 2
+ default_cost: 2
+ - process_id: 26
+ adjacency_stagger:
+ min_adjacency: 10
+ max_adjacency: 20
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] == result['before'] }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] == result['after'] }}"
+
+ - name: Replace device configurations of listed vrfs/global entry with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospfv2: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] == result['before'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/rtt.yaml
new file mode 100644
index 00000000..009fe56c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/tests/cli/rtt.yaml
@@ -0,0 +1,98 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv2 round trip integration tests on connection={{ ansible_connection }}
+
+- block:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+ - name: Apply the provided configuration (base config)
+ register: base_config
+ cisco.iosxr.iosxr_ospfv2:
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - process_id: 26
+ adjacency_stagger:
+ min_adjacency: 10
+ max_adjacency: 20
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ - process_id: 10
+ areas:
+ - area_id: 11
+ default_cost: 5
+ cost: 11
+ - area_id: 22
+ default_cost: 6
+ - process_id: 30
+ areas:
+ - area_id: 11
+ default_cost: 5
+ - area_id: 22
+ default_cost: 6
+
+ cost: 2
+ default_metric: 10
+ transmit_delay: 2
+ hello_interval: 1
+ dead_interval: 2
+ retransmit_interval: 2
+ packet_size: 577
+ priority: 1
+ router_id: "2.2.2.2"
+ demand_circuit: enable
+ passive: disable
+ summary_in: enable
+ flood_reduction: disable
+ mtu_ignore: enable
+ external_out: disable
+ state: merged
+
+ - name: Gather ospfv2 facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - ospfv2
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ cisco.iosxr.iosxr_ospfv2:
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - area_id: 20
+ cost: 2
+ default_cost: 2
+ - process_id: 26
+ adjacency_stagger:
+ min_adjacency: 10
+ max_adjacency: 20
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ state: overridden
+
+ - name: Assert that changes were applied
+ ansible.builtin.assert:
+ that: "{{ round_trip['after'] == result['after'] }}"
+
+ - name: Revert back to base configuration using facts round trip
+ register: revert
+ cisco.iosxr.iosxr_ospfv2:
+ config: "{{ ansible_facts['network_resources']['ospfv2'] }}"
+ state: overridden
+
+ - name: Assert that configuration was reverted
+ ansible.builtin.assert:
+ that: "{{ base_config['after'] == revert['after'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/vars/main.yaml
new file mode 100644
index 00000000..581b57ce
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv2/vars/main.yaml
@@ -0,0 +1,316 @@
+---
+merged:
+ before: {}
+ commands:
+ - router ospf 10
+ - area 11 default-cost 5
+ - area 11 cost 11
+ - area 22 default-cost 6
+ - router ospf 27
+ - area 10 hello-interval 2
+ - router ospf 26
+ - adjacency stagger 10 20
+ - authentication message-digest keychain ansible1101pass
+ - router ospf 30
+ - cost 2
+ - passive disable
+ - priority 1
+ - flood-reduction disable
+ - default-metric 10
+ - router-id 2.2.2.2
+ - demand-circuit enable
+ - packet-size 577
+ - transmit-delay 2
+ - summary-in enable
+ - external-out disable
+ - dead-interval 2
+ - hello-interval 1
+ - retransmit-interval 2
+ - mtu-ignore enable
+ - area 11 default-cost 5
+ - area 22 default-cost 6
+ update_commands:
+ - router ospf 26
+ - adjacency stagger 11 21
+ - router ospf 27
+ - area 30 dead-interval 4
+ after:
+ processes:
+ - areas:
+ - area_id: "11"
+ cost: 11
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ process_id: "10"
+
+ - adjacency_stagger:
+ max_adjacency: 20
+ min_adjacency: 10
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ process_id: "26"
+ - areas:
+ - area_id: "10"
+ hello_interval: 2
+ process_id: "27"
+ - areas:
+ - area_id: "11"
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ cost: 2
+ dead_interval: 2
+ default_metric: 10
+ demand_circuit: "enable"
+ external_out: "disable"
+ flood_reduction: "disable"
+ hello_interval: 1
+ mtu_ignore: "enable"
+ packet_size: 577
+ passive: "disable"
+ priority: 1
+ process_id: "30"
+ retransmit_interval: 2
+ router_id: "2.2.2.2"
+ summary_in: "enable"
+ transmit_delay: 2
+
+ update_after:
+ processes:
+ - areas:
+ - area_id: "11"
+ cost: 11
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ process_id: "10"
+ - adjacency_stagger:
+ max_adjacency: 21
+ min_adjacency: 11
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ process_id: "26"
+ - areas:
+ - area_id: "10"
+ hello_interval: 2
+ - area_id: "30"
+ dead_interval: 4
+ process_id: "27"
+ - areas:
+ - area_id: "11"
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+
+ cost: 2
+ dead_interval: 2
+ default_metric: 10
+ demand_circuit: "enable"
+ external_out: "disable"
+ flood_reduction: "disable"
+ hello_interval: 1
+ mtu_ignore: "enable"
+ packet_size: 577
+ passive: "disable"
+ priority: 1
+ process_id: "30"
+ retransmit_interval: 2
+ router_id: "2.2.2.2"
+ summary_in: "enable"
+ transmit_delay: 2
+replaced:
+ before:
+ processes:
+ - areas:
+ - area_id: "11"
+ cost: 11
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ process_id: "10"
+ - adjacency_stagger:
+ max_adjacency: 20
+ min_adjacency: 10
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ process_id: "26"
+ - areas:
+ - area_id: "10"
+ hello_interval: 2
+ process_id: "27"
+ - areas:
+ - area_id: "11"
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ cost: 2
+ dead_interval: 2
+ default_metric: 10
+ demand_circuit: "enable"
+ external_out: "disable"
+ flood_reduction: "disable"
+ hello_interval: 1
+ mtu_ignore: "enable"
+ packet_size: 577
+ passive: "disable"
+ priority: 1
+ process_id: "30"
+ retransmit_interval: 2
+ router_id: "2.2.2.2"
+ summary_in: "enable"
+ transmit_delay: 2
+
+ commands:
+ - router ospf 27
+ - area 20 default-cost 2
+ - area 20 cost 2
+
+ after:
+ processes:
+ - areas:
+ - area_id: "11"
+ cost: 11
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ process_id: "10"
+ - adjacency_stagger:
+ max_adjacency: 20
+ min_adjacency: 10
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ process_id: "26"
+ - areas:
+ - area_id: "10"
+ hello_interval: 2
+ - area_id: "20"
+ cost: 2
+ default_cost: 2
+ process_id: "27"
+ - areas:
+ - area_id: "11"
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ cost: 2
+ dead_interval: 2
+ default_metric: 10
+ demand_circuit: "enable"
+ external_out: "disable"
+ flood_reduction: "disable"
+ hello_interval: 1
+ mtu_ignore: "enable"
+ packet_size: 577
+ passive: "disable"
+ priority: 1
+ process_id: "30"
+ retransmit_interval: 2
+ router_id: "2.2.2.2"
+ summary_in: "enable"
+ transmit_delay: 2
+
+overridden:
+ commands:
+ - router ospf 10
+ - no area 11 default-cost 5
+ - no area 11 cost 11
+ - no area 22 default-cost 6
+ - router ospf 30
+ - no cost 2
+ - no passive disable
+ - no priority 1
+ - no flood-reduction disable
+ - no default-metric 10
+ - no router-id 2.2.2.2
+ - no demand-circuit enable
+ - no packet-size 577
+ - no transmit-delay 2
+ - no summary-in enable
+ - no external-out disable
+ - no dead-interval 2
+ - no hello-interval 1
+ - no retransmit-interval 2
+ - no mtu-ignore enable
+ - no area 11 default-cost 5
+ - no area 22 default-cost 6
+ - router ospf 27
+ - area 20 default-cost 2
+ - area 20 cost 2
+ after:
+ processes:
+ - process_id: "10"
+ - adjacency_stagger:
+ max_adjacency: 20
+ min_adjacency: 10
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ process_id: "26"
+ - areas:
+ - area_id: "10"
+ hello_interval: 2
+ - area_id: "20"
+ cost: 2
+ default_cost: 2
+ process_id: "27"
+ - process_id: "30"
+deleted:
+ commands:
+ - router ospf 10
+ - no area 11 default-cost 5
+ - no area 11 cost 11
+ - no area 22 default-cost 6
+ - router ospf 26
+ - no adjacency stagger 10 20
+ - no authentication message-digest keychain ansible1101pass
+ - router ospf 27
+ - no area 10 hello-interval 2
+ - router ospf 30
+ - no cost 2
+ - no passive disable
+ - no priority 1
+ - no flood-reduction disable
+ - no default-metric 10
+ - no router-id 2.2.2.2
+ - no demand-circuit enable
+ - no packet-size 577
+ - no transmit-delay 2
+ - no summary-in enable
+ - no external-out disable
+ - no dead-interval 2
+ - no hello-interval 1
+ - no retransmit-interval 2
+ - no mtu-ignore enable
+ - no area 11 default-cost 5
+ - no area 22 default-cost 6
+
+ after:
+ processes:
+ - process_id: "10"
+ - process_id: "26"
+ - process_id: "27"
+ - process_id: "30"
+round_trip:
+ after:
+ processes:
+ - process_id: "10"
+ - adjacency_stagger:
+ max_adjacency: 20
+ min_adjacency: 10
+ authentication:
+ message_digest:
+ keychain: "ansible1101pass"
+ process_id: "26"
+ - areas:
+ - area_id: "10"
+ hello_interval: 2
+ - area_id: "20"
+ cost: 2
+ default_cost: 2
+ process_id: "27"
+ - process_id: "30"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/fixtures/parsed.cfg
new file mode 100644
index 00000000..f0e69c9e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/fixtures/parsed.cfg
@@ -0,0 +1,36 @@
+router ospfv3 10
+ area 11
+ cost 11
+ default-cost 5
+ !
+ area 22
+ default-cost 6
+ !
+!
+router ospfv3 26
+ authentication disable
+!
+router ospfv3 27
+ area 10
+ hello-interval 2
+ !
+!
+router ospfv3 30
+ router-id 2.2.2.2
+ cost 2
+ packet-size 577
+ priority 1
+ mtu-ignore
+ dead-interval 2
+ retransmit-interval 2
+ demand-circuit
+ hello-interval 1
+ transmit-delay 2
+ default-metric 10
+ area 11
+ default-cost 5
+ !
+ area 22
+ default-cost 6
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/_populate_config.yaml
new file mode 100644
index 00000000..d90dafa4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/_populate_config.yaml
@@ -0,0 +1,38 @@
+---
+- name: Setup (populate ospfv3 routes)
+ cisco.iosxr.iosxr_ospfv3:
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - process_id: 26
+ authentication:
+ disable: true
+ - process_id: 10
+ areas:
+ - area_id: 11
+ default_cost: 5
+ cost: 11
+ - area_id: 22
+ default_cost: 6
+ - process_id: 30
+ areas:
+ - area_id: 11
+ default_cost: 5
+ - area_id: 22
+ default_cost: 6
+
+ cost: 2
+ default_metric: 10
+ transmit_delay: 2
+ hello_interval: 1
+ dead_interval: 2
+ retransmit_interval: 2
+ packet_size: 577
+ priority: 1
+ router_id: "2.2.2.2"
+ demand_circuit: true
+ mtu_ignore: true
+ state: merged
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..580027f6
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/_remove_config.yaml
@@ -0,0 +1,7 @@
+---
+- name: Remove ospfv3 routes
+ vars:
+ lines: "no router ospfv3 26\n no router ospfv3 27\n no router ospfv3 30\n no router ospfv3 10\n "
+ ignore_errors: true
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/deleted.yaml
new file mode 100644
index 00000000..f2652af6
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/deleted.yaml
@@ -0,0 +1,76 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_ospfv3 deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete single OSPF process network
+ register: result
+ cisco.iosxr.iosxr_ospfv3: &id001
+ config:
+ processes:
+ - process_id: 10
+ - process_id: 26
+ - process_id: 27
+ - process_id: 30
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] == result['before'] }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] == result['after'] }}"
+
+ - name: Delete a single OSPF process (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospfv3: *id001
+ - ansible.builtin.assert: &id003
+ that:
+ - result.changed == false
+ - result.commands|length == 0
+
+ - ansible.builtin.include_tasks: _populate_config.yaml
+
+ - name: Delete all OSPF processes
+ register: result
+ cisco.iosxr.iosxr_ospfv3: &id002
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] == result['before'] }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] == result['after'] }}"
+
+ - name: Delete all OSPF processes (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospfv3: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert: *id003
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] == result['before'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..3b56d814
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv3 empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospfv3:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospfv3:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Parsed with empty running_config should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospfv3:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospfv3:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_ospfv3:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/gathered.yaml
new file mode 100644
index 00000000..1feedbb4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/gathered.yaml
@@ -0,0 +1,20 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv3 gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Gather ospfv3 facts from the device using iosxr_ospfv3 module
+ register: result
+ cisco.iosxr.iosxr_ospfv3:
+ state: gathered
+
+ - ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] == result['gathered'] }}"
+ - "result.changed == false"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/merged.yaml
new file mode 100644
index 00000000..827d872f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/merged.yaml
@@ -0,0 +1,112 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv3 merged integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_ospfv3: &id001
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - process_id: 26
+ authentication:
+ disable: true
+ - process_id: 10
+ areas:
+ - area_id: 11
+ default_cost: 5
+ cost: 11
+ - area_id: 22
+ default_cost: 6
+ - process_id: 30
+ areas:
+ - area_id: 11
+ default_cost: 5
+ - area_id: 22
+ default_cost: 6
+
+ cost: 2
+ default_metric: 10
+ transmit_delay: 2
+ hello_interval: 1
+ dead_interval: 2
+ retransmit_interval: 2
+ packet_size: 577
+ priority: 1
+ router_id: "2.2.2.2"
+ demand_circuit: true
+ mtu_ignore: true
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['before'] == result['before'] }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['after'] }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospfv3: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['before'] }}"
+
+ - name: Update existing configuration using merged
+ register: result
+ cisco.iosxr.iosxr_ospfv3: &id002
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - area_id: 30
+ dead_interval: 4
+ - process_id: 26
+ authentication:
+ disable: true
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['after'] == result['before'] }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['update_commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['update_after'] == result['after'] }}"
+
+ - name: Update existing ospfv3 configuration using merged (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospfv3: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/overridden.yaml
new file mode 100644
index 00000000..7f485291
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/overridden.yaml
@@ -0,0 +1,56 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv3 overridden integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Overridde all ospfv3 configuration with provided configuration
+ register: result
+ cisco.iosxr.iosxr_ospfv3: &id001
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - area_id: 20
+ cost: 2
+ default_cost: 2
+ - process_id: 26
+ authentication:
+ disable: true
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] == result['before'] }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] == result['after'] }}"
+
+ - name: Overridde all ospfv3 configuration with given configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospfv3: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] == result['before'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/parsed.yaml
new file mode 100644
index 00000000..c9b0e46b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/parsed.yaml
@@ -0,0 +1,15 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv3 parsed integration tests on connection={{ ansible_connection }}
+
+- block:
+ - name: Use parsed state to convert externally supplied device specific ospfv3 routes commands to structured format
+ register: result
+ cisco.iosxr.iosxr_ospfv3:
+ running_config: "{{ lookup('file', '../../fixtures/parsed.cfg') }}"
+ state: parsed
+
+ - ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] == result['parsed'] }}"
+ - "result.changed == false"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/rendered.yaml
new file mode 100644
index 00000000..c9960da0
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/rendered.yaml
@@ -0,0 +1,63 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv3 rendered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Use rendered state to convert task input to device specific commands
+ register: result
+ cisco.iosxr.iosxr_ospfv3:
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - process_id: 26
+ authentication:
+ disable: true
+ - process_id: 10
+ areas:
+ - area_id: 11
+ default_cost: 5
+ cost: 11
+ - area_id: 22
+ default_cost: 6
+ - process_id: 30
+ areas:
+ - area_id: 11
+ default_cost: 5
+ - area_id: 22
+ default_cost: 6
+
+ cost: 2
+ default_metric: 10
+ transmit_delay: 2
+ hello_interval: 1
+ dead_interval: 2
+ retransmit_interval: 2
+ packet_size: 577
+ priority: 1
+ router_id: "2.2.2.2"
+ demand_circuit: true
+ passive: false
+ flood_reduction: false
+ mtu_ignore: true
+ state: rendered
+
+ - ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length==0 }}"
+ - "result.changed == false"
+
+ - name: Gather ospfv3 facts from the device and assert that its empty
+ register: result
+ cisco.iosxr.iosxr_ospfv3:
+ state: gathered
+
+ - name: Make sure that rendered task actually did not make any changes to the device
+ ansible.builtin.assert:
+ that: "{{ result['gathered'] == {} }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/replaced.yaml
new file mode 100644
index 00000000..4cf49d2b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/replaced.yaml
@@ -0,0 +1,56 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv3 replaced integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replace device configurations of ospfv3 routes with provided configurations
+ register: result
+ cisco.iosxr.iosxr_ospfv3: &id001
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - area_id: 20
+ cost: 2
+ default_cost: 2
+ - process_id: 26
+ authentication:
+ disable: true
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] == result['before'] }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] == result['after'] }}"
+
+ - name: Replace device configurations of listed vrfs/global entry with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_ospfv3: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] == result['before'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/rtt.yaml
new file mode 100644
index 00000000..10b8d399
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/tests/cli/rtt.yaml
@@ -0,0 +1,88 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_ospfv3 round trip integration tests on connection={{ ansible_connection }}
+
+- block:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+ - name: Apply the provided configuration (base config)
+ register: base_config
+ cisco.iosxr.iosxr_ospfv3:
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - process_id: 26
+ authentication:
+ disable: true
+ - process_id: 10
+ areas:
+ - area_id: 11
+ default_cost: 5
+ cost: 11
+ - area_id: 22
+ default_cost: 6
+ - process_id: 30
+ areas:
+ - area_id: 11
+ default_cost: 5
+ - area_id: 22
+ default_cost: 6
+
+ cost: 2
+ default_metric: 10
+ transmit_delay: 2
+ hello_interval: 1
+ dead_interval: 2
+ retransmit_interval: 2
+ packet_size: 577
+ priority: 1
+ router_id: "2.2.2.2"
+ demand_circuit: true
+ passive: false
+ flood_reduction: false
+ mtu_ignore: true
+ state: merged
+
+ - name: Gather ospfv3 facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - ospfv3
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ cisco.iosxr.iosxr_ospfv3:
+ config:
+ processes:
+ - process_id: 27
+ areas:
+ - area_id: 10
+ hello_interval: 2
+ - area_id: 20
+ cost: 2
+ default_cost: 2
+ - process_id: 26
+ authentication:
+ disable: true
+ state: overridden
+
+ - name: Assert that changes were applied
+ ansible.builtin.assert:
+ that: "{{ round_trip['after'] == result['after'] }}"
+
+ - name: Revert back to base configuration using facts round trip
+ register: revert
+ cisco.iosxr.iosxr_ospfv3:
+ config: "{{ ansible_facts['network_resources']['ospfv3'] }}"
+ state: overridden
+
+ - name: Assert that configuration was reverted
+ ansible.builtin.assert:
+ that: "{{ base_config['after'] == revert['after'] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/vars/main.yaml
new file mode 100644
index 00000000..a1038098
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ospfv3/vars/main.yaml
@@ -0,0 +1,260 @@
+---
+merged:
+ before: {}
+ commands:
+ - router ospfv3 10
+ - area 11 default-cost 5
+ - area 11 cost 11
+ - area 22 default-cost 6
+ - router ospfv3 27
+ - area 10 hello-interval 2
+ - router ospfv3 26
+ - authentication disable
+ - router ospfv3 30
+ - cost 2
+ - priority 1
+ - default-metric 10
+ - router-id 2.2.2.2
+ - demand-circuit
+ - packet-size 577
+ - transmit-delay 2
+ - dead-interval 2
+ - hello-interval 1
+ - retransmit-interval 2
+ - mtu-ignore
+ - area 11 default-cost 5
+ - area 22 default-cost 6
+ update_commands:
+ - router ospfv3 27
+ - area 30 dead-interval 4
+ after:
+ processes:
+ - areas:
+ - area_id: "11"
+ cost: 11
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ process_id: "10"
+
+ - authentication:
+ disable: true
+ process_id: "26"
+ - areas:
+ - area_id: "10"
+ hello_interval: 2
+ process_id: "27"
+ - areas:
+ - area_id: "11"
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ cost: 2
+ dead_interval: 2
+ default_metric: 10
+ demand_circuit: true
+ hello_interval: 1
+ mtu_ignore: true
+ packet_size: 577
+ priority: 1
+ process_id: "30"
+ retransmit_interval: 2
+ router_id: "2.2.2.2"
+ transmit_delay: 2
+
+ update_after:
+ processes:
+ - areas:
+ - area_id: "11"
+ cost: 11
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ process_id: "10"
+ - authentication:
+ disable: true
+ process_id: "26"
+ - areas:
+ - area_id: "10"
+ hello_interval: 2
+ - area_id: "30"
+ dead_interval: 4
+ process_id: "27"
+ - areas:
+ - area_id: "11"
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+
+ cost: 2
+ dead_interval: 2
+ default_metric: 10
+ demand_circuit: true
+ hello_interval: 1
+ mtu_ignore: true
+ packet_size: 577
+ priority: 1
+ process_id: "30"
+ retransmit_interval: 2
+ router_id: "2.2.2.2"
+ transmit_delay: 2
+replaced:
+ before:
+ processes:
+ - areas:
+ - area_id: "11"
+ cost: 11
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ process_id: "10"
+ - authentication:
+ disable: true
+ process_id: "26"
+ - areas:
+ - area_id: "10"
+ hello_interval: 2
+ process_id: "27"
+ - areas:
+ - area_id: "11"
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ cost: 2
+ dead_interval: 2
+ default_metric: 10
+ demand_circuit: true
+ hello_interval: 1
+ mtu_ignore: true
+ packet_size: 577
+ priority: 1
+ process_id: "30"
+ retransmit_interval: 2
+ router_id: "2.2.2.2"
+ transmit_delay: 2
+
+ commands:
+ - router ospfv3 27
+ - area 20 default-cost 2
+ - area 20 cost 2
+
+ after:
+ processes:
+ - areas:
+ - area_id: "11"
+ cost: 11
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ process_id: "10"
+ - authentication:
+ disable: true
+ process_id: "26"
+ - areas:
+ - area_id: "10"
+ hello_interval: 2
+ - area_id: "20"
+ cost: 2
+ default_cost: 2
+ process_id: "27"
+ - areas:
+ - area_id: "11"
+ default_cost: 5
+ - area_id: "22"
+ default_cost: 6
+ cost: 2
+ dead_interval: 2
+ default_metric: 10
+ demand_circuit: true
+ hello_interval: 1
+ mtu_ignore: true
+ packet_size: 577
+ priority: 1
+ process_id: "30"
+ retransmit_interval: 2
+ router_id: "2.2.2.2"
+ transmit_delay: 2
+
+overridden:
+ commands:
+ - router ospfv3 10
+ - no area 11 default-cost 5
+ - no area 11 cost 11
+ - no area 22 default-cost 6
+ - router ospfv3 30
+ - no cost 2
+ - no priority 1
+ - no default-metric 10
+ - no router-id 2.2.2.2
+ - no demand-circuit
+ - no packet-size 577
+ - no transmit-delay 2
+ - no dead-interval 2
+ - no hello-interval 1
+ - no retransmit-interval 2
+ - no mtu-ignore
+ - no area 11 default-cost 5
+ - no area 22 default-cost 6
+ - router ospfv3 27
+ - area 20 default-cost 2
+ - area 20 cost 2
+ after:
+ processes:
+ - process_id: "10"
+ - authentication:
+ disable: true
+ process_id: "26"
+ - areas:
+ - area_id: "10"
+ hello_interval: 2
+ - area_id: "20"
+ cost: 2
+ default_cost: 2
+ process_id: "27"
+ - process_id: "30"
+deleted:
+ commands:
+ - router ospfv3 10
+ - no area 11 default-cost 5
+ - no area 11 cost 11
+ - no area 22 default-cost 6
+ - router ospfv3 26
+ - no authentication disable
+ - router ospfv3 27
+ - no area 10 hello-interval 2
+ - router ospfv3 30
+ - no cost 2
+ - no priority 1
+ - no default-metric 10
+ - no router-id 2.2.2.2
+ - no demand-circuit
+ - no packet-size 577
+ - no transmit-delay 2
+ - no dead-interval 2
+ - no hello-interval 1
+ - no retransmit-interval 2
+ - no mtu-ignore
+ - no area 11 default-cost 5
+ - no area 22 default-cost 6
+
+ after:
+ processes:
+ - process_id: "10"
+ - process_id: "26"
+ - process_id: "27"
+ - process_id: "30"
+round_trip:
+ after:
+ processes:
+ - process_id: "10"
+ - authentication:
+ disable: true
+ process_id: "26"
+ - areas:
+ - area_id: "10"
+ hello_interval: 2
+ - area_id: "20"
+ cost: 2
+ default_cost: 2
+ process_id: "27"
+ - process_id: "30"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/defaults/main.yaml
new file mode 100644
index 00000000..9ef5ba51
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/tests/cli/ping.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/tests/cli/ping.yaml
new file mode 100644
index 00000000..6c47cb95
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_ping/tests/cli/ping.yaml
@@ -0,0 +1,51 @@
+---
+- ansible.builtin.debug: msg="START cli/ping.yaml on connection={{ ansible_connection }}"
+
+- register: show_version_result
+ cisco.iosxr.iosxr_command:
+ commands: show version
+
+- ansible.builtin.set_fact: management_interface=GigabitEthernet0/0
+ when: "'Cisco IOSXR' in show_version_result.stdout[0]"
+
+- ansible.builtin.set_fact: management_interface=GigabitEthernet1
+ when: "'Cisco IOS-XR' in show_version_result.stdout[0]"
+
+- name: Get show IP management interface output
+ register: show_ip_interface_result
+ cisco.iosxr.iosxr_command:
+ commands:
+ - show ip interface {{ management_interface }} | include Internet address
+
+- name: Extract the IP address from registered output
+ ansible.builtin.set_fact: management_ip="{{ show_ip_interface_result.stdout[0].split()[-1].split('/')[0]}}"
+
+- name: Expected successful ping
+ register: esp
+ cisco.iosxr.iosxr_ping:
+ dest: "{{ management_ip }}"
+
+- name: Unexpected unsuccessful ping
+ register: uup
+ ignore_errors: true
+ cisco.iosxr.iosxr_ping:
+ dest: 10.255.255.250
+
+- name: Unexpected successful ping
+ register: usp
+ ignore_errors: true
+ cisco.iosxr.iosxr_ping:
+ dest: "{{ management_ip }}"
+ state: absent
+
+- name: Expected unsuccessful ping
+ register: eup
+ cisco.iosxr.iosxr_ping:
+ dest: 10.255.255.250
+ state: absent
+
+- name: Assert
+ ansible.builtin.assert:
+ that:
+ - esp.failed == eup.failed == false
+ - usp.failed == uup.failed == true
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/_populate_config.yaml
new file mode 100644
index 00000000..1782148a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/_populate_config.yaml
@@ -0,0 +1,22 @@
+---
+- name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_prefix_lists:
+ config:
+ - afi: ipv6
+ prefix_lists:
+ - name: pl_1
+ entries:
+ - prefix: 2001:db8:1234::/48
+ action: deny
+ sequence: 1
+ - afi: ipv4
+ prefix_lists:
+ - name: pl1
+ entries:
+ - sequence: 3
+ action: remark
+ description: TEST_PL1_2_REMARK
+ - sequence: 4
+ action: permit
+ prefix: 10.0.0.0/24
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..4470966a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/_remove_config.yaml
@@ -0,0 +1,5 @@
+---
+- name: Delete all prefix-lists from the device
+ register: result
+ cisco.iosxr.iosxr_prefix_lists:
+ state: deleted
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/deleted.yaml
new file mode 100644
index 00000000..1f7b9d90
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/deleted.yaml
@@ -0,0 +1,60 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_prefix_list deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete prefix-list by afi.
+ register: result
+ cisco.iosxr.iosxr_prefix_lists: &id001
+ config:
+ - afi: ipv6
+ state: deleted
+
+ - ansible.builtin.assert:
+ that:
+ - '"no ipv6 prefix-list pl_1" in result.commands'
+ - result.commands|length == 1
+
+ - name: Delete a single prefix-list by name (idempotent)
+ register: result
+ cisco.iosxr.iosxr_prefix_lists: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands|length == 0
+
+ - ansible.builtin.include_tasks: _populate_config.yaml
+
+ - name: Delete all prefix-lists from the device
+ register: result
+ cisco.iosxr.iosxr_prefix_lists: &id002
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Delete all prefix_lists from the device (idempotent)
+ register: result
+ cisco.iosxr.iosxr_prefix_lists: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands|length == 0
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..d2f3c00b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/empty_config.yaml
@@ -0,0 +1,58 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_prefix_lists empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_prefix_lists:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_prefix_lists:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_prefix_lists:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_prefix_lists:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_prefix_lists:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/fixtures/parsed.cfg
new file mode 100644
index 00000000..a8d69e9b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/fixtures/parsed.cfg
@@ -0,0 +1,7 @@
+ipv6 prefix-list pl1
+ 1 remark test
+!
+ipv4 prefix-list pl2
+ 1 deny 35.0.0.0/8
+ 2 deny 10.0.0.0/24
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/gathered.yaml
new file mode 100644
index 00000000..76c386b6
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/gathered.yaml
@@ -0,0 +1,19 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_prefix_lists gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Gather ACL interfaces facts using gathered state
+ register: result
+ cisco.iosxr.iosxr_prefix_lists:
+ state: gathered
+
+ - name: Assert that facts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['after'] | symmetric_difference(result['gathered']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/merged.yaml
new file mode 100644
index 00000000..2850388b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/merged.yaml
@@ -0,0 +1,61 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_prefix_lists merged integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_prefix_lists: &id001
+ config:
+ - afi: ipv6
+ prefix_lists:
+ - name: pl_1
+ entries:
+ - prefix: 2001:db8:1234::/48
+ action: deny
+ sequence: 1
+ - afi: ipv4
+ prefix_lists:
+ - name: pl1
+ entries:
+ - sequence: 3
+ action: remark
+ description: TEST_PL1_2_REMARK
+ - sequence: 4
+ action: permit
+ prefix: 10.0.0.0/24
+
+ state: merged
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_prefix_lists: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/overridden.yaml
new file mode 100644
index 00000000..5bb6db4d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/overridden.yaml
@@ -0,0 +1,55 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_prefix_lists overridden integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Overridde all prefix_lists configuration with provided configuration
+ register: result
+ cisco.iosxr.iosxr_prefix_lists: &id001
+ config:
+ - afi: ipv4
+ prefix_lists:
+ - name: pl3
+ entries:
+ - sequence: 3
+ action: remark
+ description: TEST_PL1_3_REMARK
+ - sequence: 4
+ action: permit
+ prefix: 10.0.0.0/24
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Overridde all interface lag interface configuration with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_prefix_lists: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/parsed.yaml
new file mode 100644
index 00000000..5e639264
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_prefix_lists parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided prefix_lists configuration to agnostic model
+ register: result
+ cisco.iosxr.iosxr_prefix_lists:
+ running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - "{{ parsed | symmetric_difference(result['parsed']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/rendered.yaml
new file mode 100644
index 00000000..3568ac8b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/rendered.yaml
@@ -0,0 +1,32 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_prefix_lists rendered integration tests on connection={{ ansible_connection }}
+
+- name: Render platform specific commands from task input using rendered state
+ register: result
+ cisco.iosxr.iosxr_prefix_lists:
+ config:
+ - afi: ipv6
+ prefix_lists:
+ - name: pl_1
+ entries:
+ - prefix: 2001:db8:1234::/48
+ action: deny
+ sequence: 1
+ - afi: ipv4
+ prefix_lists:
+ - name: pl1
+ entries:
+ - sequence: 3
+ action: remark
+ description: TEST_PL1_2_REMARK
+ - sequence: 4
+ action: permit
+ prefix: 10.0.0.0/24
+
+ state: rendered
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/replaced.yaml
new file mode 100644
index 00000000..eb35e084
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/replaced.yaml
@@ -0,0 +1,54 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_prefix_lists replaced integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replace device configurations of listed ACL with provided configurations
+ register: result
+ cisco.iosxr.iosxr_prefix_lists: &id001
+ config:
+ - afi: ipv4
+ prefix_lists:
+ - name: pl1
+ entries:
+ - sequence: 3
+ action: permit
+ prefix: 10.0.0.0/24
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ - ansible.builtin.debug:
+ msg: "{{ replaced['after'] | symmetric_difference(result['after']) }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Replace device configurations of listed interfaces with provided configurarions (idempotent)
+ register: result
+ cisco.iosxr.iosxr_prefix_lists: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/rtt.yaml
new file mode 100644
index 00000000..bf00d14d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/tests/cli/rtt.yaml
@@ -0,0 +1,81 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_prefix_lists round trip integration tests on connection={{ ansible_connection }}
+
+- block:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+ - name: Apply the provided configuration (base config)
+ register: base_config
+ cisco.iosxr.iosxr_prefix_lists:
+ config:
+ - afi: ipv6
+ prefix_lists:
+ - name: pl1_1
+ entries:
+ - prefix: 2001:db8:1234::/48
+ action: deny
+ sequence: 1
+ - name: pl1_2
+ entries:
+ - sequence: 2
+ action: remark
+ description: TEST_PL1_2_REMARK
+ - afi: ipv4
+ prefix_lists:
+ - name: pl1
+ entries:
+ - sequence: 3
+ action: remark
+ description: TEST_PL1_REMARK
+ - sequence: 4
+ action: permit
+ prefix: 10.0.0.0/24
+ - name: pl2
+ entries:
+ - sequence: 5
+ action: remark
+ description: TEST_PL2_REMARK
+
+ state: merged
+
+ - name: Gather interfaces facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - prefix_lists
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ cisco.iosxr.iosxr_prefix_lists:
+ config:
+ - afi: ipv4
+ prefix_lists:
+ - name: pl3
+ entries:
+ - sequence: 3
+ action: remark
+ description: TEST_PL1_3_REMARK
+ - sequence: 4
+ action: permit
+ prefix: 10.0.0.0/24
+
+ state: overridden
+
+ - name: Assert that changes were applied
+ ansible.builtin.assert:
+ that: "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Revert back to base configuration using facts round trip
+ register: revert
+ cisco.iosxr.iosxr_prefix_lists:
+ config: "{{ ansible_facts['network_resources']['prefix_lists'] }}"
+ state: overridden
+
+ - name: Assert that configuration was reverted
+ ansible.builtin.assert:
+ that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/vars/main.yaml
new file mode 100644
index 00000000..8db2ca54
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_prefix_lists/vars/main.yaml
@@ -0,0 +1,87 @@
+---
+merged:
+ before: []
+ commands:
+ - ipv6 prefix-list pl_1 1 deny 2001:db8:1234::/48
+ - ipv4 prefix-list pl1 3 remark TEST_PL1_2_REMARK
+ - ipv4 prefix-list pl1 4 permit 10.0.0.0/24
+ after:
+ - prefix_lists:
+ - entries:
+ - sequence: 3
+ action: remark
+ description: TEST_PL1_2_REMARK
+ - sequence: 4
+ action: permit
+ prefix: 10.0.0.0/24
+ name: pl1
+ afi: ipv4
+ - prefix_lists:
+ - entries:
+ - prefix: 2001:db8:1234::/48
+ action: deny
+ sequence: 1
+ name: pl_1
+ afi: ipv6
+
+replaced:
+ commands:
+ - no ipv4 prefix-list pl1 3 remark TEST_PL1_2_REMARK
+ - no ipv4 prefix-list pl1 4 permit 10.0.0.0/24
+ - ipv4 prefix-list pl1 3 permit 10.0.0.0/24
+
+ after:
+ - prefix_lists:
+ - entries:
+ - prefix: "2001:db8:1234::/48"
+ action: "deny"
+ sequence: 1
+ name: "pl_1"
+ afi: "ipv6"
+ - prefix_lists:
+ - entries:
+ - sequence: 3
+ action: "permit"
+ prefix: "10.0.0.0/24"
+ name: "pl1"
+ afi: "ipv4"
+overridden:
+ commands:
+ - no ipv6 prefix-list pl_1
+ - no ipv4 prefix-list pl1
+ - ipv4 prefix-list pl3 3 remark TEST_PL1_3_REMARK
+ - ipv4 prefix-list pl3 4 permit 10.0.0.0/24
+ after:
+ - afi: ipv4
+ prefix_lists:
+ - name: pl3
+ entries:
+ - sequence: 3
+ action: remark
+ description: TEST_PL1_3_REMARK
+ - sequence: 4
+ action: permit
+ prefix: 10.0.0.0/24
+deleted:
+ commands:
+ - no ipv6 prefix-list pl_1
+ - no ipv4 prefix-list pl1
+ after: []
+parsed:
+ - afi: ipv6
+ prefix_lists:
+ - name: pl1
+ entries:
+ - action: remark
+ description: test
+ sequence: 1
+ - afi: ipv4
+ prefix_lists:
+ - name: pl2
+ entries:
+ - action: deny
+ prefix: 35.0.0.0/8
+ sequence: 1
+ - action: deny
+ prefix: 10.0.0.0/24
+ sequence: 2
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/defaults/main.yaml
new file mode 100644
index 00000000..9ef5ba51
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/meta/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/meta/main.yaml
new file mode 100644
index 00000000..be631e5d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_iosxr_tests
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tasks/cli.yaml
new file mode 100644
index 00000000..f0489b91
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tasks/cli.yaml
@@ -0,0 +1,28 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/cli"
+ patterns: "{{ testcase }}.yaml"
+ 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=network_cli)
+ ansible.builtin.include_tasks: "{{ test_case_to_run }}"
+ with_items: "{{ test_items }}"
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+ loop_control:
+ loop_var: test_case_to_run
+ tags:
+ - network_cli
+
+- name: Run test cases with single_user_mode (connection=network_cli)
+ ansible.builtin.include_tasks: "{{ role_path }}/tests/cli/caching.yaml"
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+ ansible_network_single_user_mode: true
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tasks/main.yaml
new file mode 100644
index 00000000..419a6cde
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tasks/main.yaml
@@ -0,0 +1,6 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+
+- name: Include the netconf tasks
+ ansible.builtin.include_tasks: netconf.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tasks/netconf.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tasks/netconf.yaml
new file mode 100644
index 00000000..7488554f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tasks/netconf.yaml
@@ -0,0 +1,20 @@
+---
+- name: Collect all netconf test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/netconf"
+ patterns: "{{ testcase }}.yaml"
+ 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 cases (connection=netconf)
+ ansible.builtin.include_tasks: "{{ test_case_to_run }}"
+ vars:
+ ansible_connection: ansible.netcommon.netconf
+ with_items: "{{ test_items }}"
+ loop_control:
+ loop_var: test_case_to_run
+ tags:
+ - netconf
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tests/cli/caching.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tests/cli/caching.yaml
new file mode 100644
index 00000000..3ff359ca
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tests/cli/caching.yaml
@@ -0,0 +1,127 @@
+---
+- block:
+ - ansible.builtin.debug: msg="START connection={{ ansible_connection }} cli/caching.yaml"
+
+ - name: Remove interfaces from configuration before actual testing
+ ignore_errors: true
+ cisco.iosxr.iosxr_config: &rem
+ lines:
+ - no interface GigabitEthernet 0/0/0/1
+ - no interface GigabitEthernet 0/0/0/2
+ - no interface GigabitEthernet 0/0/0/4
+ match: none
+
+ # We need to do this because of a bug in iosxr_interfaces module
+ # https://github.com/ansible-collections/cisco.iosxr/issues/106
+ - name: Add back interfaces to configuration before actual testing
+ ignore_errors: true
+ cisco.iosxr.iosxr_config:
+ lines: shutdown
+ parents: "interface GigabitEthernet {{ intf }}"
+ match: none
+ with_items:
+ - "0/0/0/1"
+ - "0/0/0/2"
+ - "0/0/0/4"
+ loop_control:
+ loop_var: intf
+
+ - name: Merge base interfaces configuration
+ register: result
+ cisco.iosxr.iosxr_interfaces: &merged
+ config:
+ - name: GigabitEthernet0/0/0/1
+ description: Configured by Ansible
+ mtu: 110
+ enabled: true
+ duplex: half
+
+ - name: GigabitEthernet0/0/0/2
+ description: Configured by Ansible
+ mtu: 2800
+ speed: 100
+ enabled: true
+ duplex: full
+ state: merged
+
+ - ansible.builtin.assert:
+ that:
+ - '"interface GigabitEthernet0/0/0/1" in result.commands'
+ - '"description Configured by Ansible" in result.commands'
+ - '"mtu 110" in result.commands'
+ - '"duplex half" in result.commands'
+ - '"no shutdown" in result.commands'
+ - '"interface GigabitEthernet0/0/0/2" in result.commands'
+ - '"description Configured by Ansible" in result.commands'
+ - '"mtu 2800" in result.commands'
+ - '"speed 100" in result.commands'
+ - '"duplex full" in result.commands'
+ - '"no shutdown" in result.commands'
+ - result.commands|length == 11
+
+ - name: Merge base interfaces configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_interfaces: *merged
+ - ansible.builtin.assert:
+ that:
+ - result.changed == False
+
+ - name: Merge layer 2 interfaces configuration
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces: &mergedl2
+ config:
+ - name: GigabitEthernet0/0/0/1
+ l2transport: true
+ l2protocol:
+ - cpsv: drop
+ propagate: true
+
+ - name: GigabitEthernet0/0/0/4.1
+ encapsulation:
+ dot1q: 20
+ second_dot1q: 40
+
+ state: merged
+
+ - ansible.builtin.assert:
+ that:
+ - '"interface GigabitEthernet0/0/0/1" in result.commands'
+ - '"l2transport l2protocol cpsv drop" in result.commands'
+ - '"l2transport propagate remote-status" in result.commands'
+ - '"interface GigabitEthernet0/0/0/4.1" in result.commands'
+ - '"encapsulation dot1q 20 second-dot1q 40" in result.commands'
+ - result.commands|length == 5
+
+ - name: Merge layer 2 interfaces configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_l2_interfaces: *mergedl2
+ - ansible.builtin.assert:
+ that:
+ - result.changed == False
+
+ - name: Merge layer 3 interfaces configuration
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces: &mergedl3
+ config:
+ - name: GigabitEthernet0/0/0/2
+ ipv4:
+ - address: 198.51.100.1/24
+ state: merged
+
+ - ansible.builtin.assert:
+ that:
+ - '"interface GigabitEthernet0/0/0/2" in result.commands'
+ - '"ipv4 address 198.51.100.1 255.255.255.0" in result.commands'
+ - result.commands|length == 2
+
+ - name: Merge layer 3 interfaces configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_l3_interfaces: *mergedl3
+ - ansible.builtin.assert:
+ that:
+ - result.changed == False
+
+ always:
+ - name: Cleanup
+ cisco.iosxr.iosxr_config: *rem
+ when: ansible_connection == "ansible.netcommon.network_cli" and ansible_network_single_user_mode|d(False)
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tests/cli/common_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tests/cli/common_config.yaml
new file mode 100644
index 00000000..6b2376cd
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tests/cli/common_config.yaml
@@ -0,0 +1,105 @@
+---
+- ansible.builtin.debug: msg="START cli/common_config.yaml on connection={{ ansible_connection }}"
+
+# Sublevel / Block
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 host 192.0.2.1 any log
+ - 20 permit ipv4 host 192.0.2.2 any log
+ - 30 permit ipv4 host 192.0.2.3 any log
+ parents:
+ - "ipv4 access-list test"
+ before:
+ - "no ipv4 access-list test"
+ match: none
+
+- name: Configure sub level command using block resplace
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 host 192.0.2.1 any log
+ - 20 permit ipv4 host 192.0.2.2 any log
+ - 30 permit ipv4 host 192.0.2.3 any log
+ - 40 permit ipv4 host 192.0.2.4 any log
+ parents:
+ - "ipv4 access-list test"
+ replace: block
+ register: result
+
+- ansible.builtin.assert:
+ that:
+ - "result.changed == true"
+ - "'ipv4 access-list test' in result.commands"
+ - "'10 permit ipv4 host 192.0.2.1 any log' in result.commands"
+ - "'20 permit ipv4 host 192.0.2.2 any log' in result.commands"
+ - "'30 permit ipv4 host 192.0.2.3 any log' in result.commands"
+ - "'40 permit ipv4 host 192.0.2.4 any log' in result.commands"
+
+- name: Check sub level command using block replace
+ cisco.iosxr.iosxr_config:
+ commands:
+ - 10 permit ipv4 host 192.0.2.1 any log
+ - 20 permit ipv4 host 192.0.2.2 any log
+ - 30 permit ipv4 host 192.0.2.3 any log
+ - 40 permit ipv4 host 192.0.2.4 any log
+ parents:
+ - "ipv4 access-list test"
+ replace: block
+ register: result
+
+- ansible.builtin.assert:
+ that:
+ - "result.changed == false"
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ commands:
+ - "no ipv4 access-list test"
+ match: none
+
+# diff exact, strict, line
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ commands:
+ - "hostname {{ inventory_hostname_short }}"
+ register: result
+
+- name: Set hostname
+ cisco.iosxr.iosxr_config:
+ commands:
+ - hostname testhost
+ match: strict
+ register: result
+
+- cisco.iosxr.iosxr_command:
+ commands:
+ - show configuration running-config hostname
+ register: configured_hostname
+
+- ansible.builtin.assert:
+ that:
+ - "'testhost' in configured_hostname.stdout[0]"
+
+- name: Set hostname
+ cisco.iosxr.iosxr_config:
+ commands:
+ - hostname testhost2
+ match: exact
+ register: result
+
+- cisco.iosxr.iosxr_command:
+ commands:
+ - show configuration running-config hostname
+ register: configured_hostname
+
+- ansible.builtin.assert:
+ that:
+ - "'testhost2' in configured_hostname.stdout[0]"
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ commands:
+ - "hostname {{ inventory_hostname_short }}"
+ register: result
+
+- ansible.builtin.debug: msg="END cli/common_config.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tests/netconf/common_netconf.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tests/netconf/common_netconf.yaml
new file mode 100644
index 00000000..2ab0957a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_smoke/tests/netconf/common_netconf.yaml
@@ -0,0 +1,46 @@
+---
+- ansible.builtin.debug: msg="START iosxr netconf/common_netconf.yaml on connection={{ ansible_connection }}"
+
+# hit general code
+- name: Setup - remove login
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ state: absent
+
+- name: Set login
+ cisco.iosxr.iosxr_banner:
+ banner: login
+ text: "@this is my login banner\nthat has a multiline\nstring\n@"
+ state: present
+ register: result
+
+- ansible.builtin.debug:
+ msg: "{{ result }}"
+
+- ansible.builtin.assert:
+ that:
+ - "result.changed == true"
+ - "'this is my login banner' in result.xml"
+ - "'that has a multiline' in result.xml"
+
+# hit etree_findall()
+- name: Remove host logging
+ cisco.iosxr.iosxr_logging:
+ dest: host
+ name: 172.16.0.1
+ state: absent
+
+- name: Set up syslog host logging
+ cisco.iosxr.iosxr_logging:
+ dest: host
+ name: 172.16.0.1
+ level: errors
+ state: present
+ register: result
+
+- ansible.builtin.assert:
+ that:
+ - "result.changed == true"
+ - '"172.16.0.1" in result.xml[0]'
+
+- ansible.builtin.debug: msg="END iosxr netconf/common_netconf.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/defaults/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/defaults/main.yml
new file mode 100644
index 00000000..871ea460
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+testcase: "[^_].*"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/meta/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/meta/main.yml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/meta/main.yml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tasks/cli.yaml
new file mode 100644
index 00000000..a1b57ab4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tasks/cli.yaml
@@ -0,0 +1,21 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/common"
+ 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
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tasks/main.yaml
new file mode 100644
index 00000000..f75f2f03
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/_parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/_parsed.cfg
new file mode 100644
index 00000000..fd40661b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/_parsed.cfg
@@ -0,0 +1,54 @@
+snmp-server vrf vrf1
+ host 1.1.1.1 traps test1
+!
+snmp-server drop report acl IPv4 test1
+snmp-server drop unknown-user
+snmp-server ipv4 dscp af11
+snmp-server ipv6 precedence routine
+snmp-server user u1 test2 v1 IPv4 test1 IPv6 test2
+snmp-server community test2 RO SDROwner IPv4 test IPv6 test1
+snmp-server queue-length 2
+snmp-server trap-timeout 3
+snmp-server trap throttle-time 12
+snmp-server traps bfd
+snmp-server traps bgp cbgp2
+snmp-server traps copy-complete
+snmp-server traps hsrp
+snmp-server traps ipsla
+snmp-server traps msdp peer-state-change
+snmp-server traps ipsec tunnel stop
+snmp-server traps ipsec tunnel start
+snmp-server traps config
+snmp-server traps l2tun sessions
+snmp-server traps l2tun tunnel-up
+snmp-server traps l2tun tunnel-down
+snmp-server traps bulkstat collection
+snmp-server traps l2vpn all
+snmp-server traps l2vpn vc-up
+snmp-server traps l2vpn vc-down
+snmp-server traps bridgemib
+snmp-server traps addrpool low
+snmp-server traps addrpool high
+snmp-server traps cisco-entity-ext
+snmp-server chassis-id test2
+snmp-server contact t1
+snmp-server location test1
+snmp-server target list test host 1.1.1.2
+snmp-server context c1
+snmp-server context c2
+snmp-server logging threshold oid-processing 1
+snmp-server logging threshold pdu-processing 1
+snmp-server mib bulkstat max-procmem-size 101
+snmp-server timeouts duplicate 0
+snmp-server timeouts inQdrop 0
+snmp-server packetsize 490
+snmp-server correlator buffer-size 1024
+snmp-server trap-source GigabitEthernet0/0/0/2
+snmp-server throttle-time 60
+snmp-server community-map cm1 context c1 security-name s1 target-list t1
+snmp-server inform retries 7
+snmp-server overload-control 4 6
+snmp-server ifmib internal cache max-duration 4
+snmp-server mroutemib send-all-vrf
+snmp-server notification-log-mib size 5
+snmp-server notification-log-mib GlobalSize 5
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/_populate_config.yaml
new file mode 100644
index 00000000..550c7bcf
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/_populate_config.yaml
@@ -0,0 +1,59 @@
+---
+- name: "Setup"
+ cisco.iosxr.iosxr_config:
+ lines:
+ - "snmp-server vrf vrf1"
+ - " host 1.1.1.1 traps test1"
+ - "snmp-server drop report acl IPv4 test1"
+ - "snmp-server drop unknown-user"
+ - "snmp-server ipv4 dscp af11"
+ - "snmp-server ipv6 precedence routine"
+ - "snmp-server user u1 test2 v1 IPv4 test1 IPv6 test2"
+ - "snmp-server community test2 RO SDROwner IPv4 test IPv6 test1"
+ - "snmp-server queue-length 2"
+ - "snmp-server trap-timeout 3"
+ - "snmp-server trap throttle-time 12"
+ - "snmp-server traps bfd"
+ - "snmp-server traps bgp cbgp2"
+ - "snmp-server traps copy-complete"
+ - "snmp-server traps hsrp"
+ - "snmp-server traps ipsla"
+ - "snmp-server traps msdp peer-state-change"
+ - "snmp-server traps ipsec tunnel stop"
+ - "snmp-server traps ipsec tunnel start"
+ - "snmp-server traps config"
+ - "snmp-server traps l2tun sessions"
+ - "snmp-server traps l2tun tunnel-up"
+ - "snmp-server traps l2tun tunnel-down"
+ - "snmp-server traps bulkstat collection"
+ - "snmp-server traps l2vpn all"
+ - "snmp-server traps l2vpn vc-up"
+ - "snmp-server traps l2vpn vc-down"
+ - "snmp-server traps bridgemib"
+ - "snmp-server traps addrpool low"
+ - "snmp-server traps addrpool high"
+ - "snmp-server traps cisco-entity-ext"
+ - "snmp-server chassis-id test2"
+ - "snmp-server contact t1"
+ - "snmp-server location test1"
+ - "snmp-server target list test host 1.1.1.2"
+ - "snmp-server context c1"
+ - "snmp-server context c2"
+ - "snmp-server logging threshold oid-processing 1"
+ - "snmp-server logging threshold pdu-processing 1"
+ - "snmp-server mib bulkstat max-procmem-size 101"
+ - "snmp-server timeouts duplicate 0"
+ - "snmp-server timeouts inQdrop 0"
+ - "snmp-server packetsize 490"
+ - "snmp-server correlator buffer-size 1024"
+ - "snmp-server trap-source GigabitEthernet0/0/0/2"
+ - "snmp-server throttle-time 60"
+ - "snmp-server community-map cm1 context c1 security-name s1 target-list t1"
+ - "snmp-server inform retries 7"
+ - "snmp-server overload-control 4 6"
+ - "snmp-server ifmib internal cache max-duration 4"
+ - "snmp-server mroutemib send-all-vrf"
+ - "snmp-server notification-log-mib size 5"
+ - "snmp-server notification-log-mib GlobalSize 5"
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/_remove_config.yaml
new file mode 100644
index 00000000..cc6fd8fd
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/_remove_config.yaml
@@ -0,0 +1,6 @@
+---
+- name: "Remove SNMP server configuration"
+ cisco.iosxr.iosxr_snmp_server:
+ state: deleted
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/deleted.yaml
new file mode 100644
index 00000000..cb1115d2
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/deleted.yaml
@@ -0,0 +1,36 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_snmp_server deleted integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete given snmp-server configuration
+ become: true
+ register: result
+ cisco.iosxr.iosxr_snmp_server: &deleted
+ state: deleted
+
+ - become: true
+ cisco.iosxr.iosxr_facts:
+ gather_network_resources: snmp_server
+
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 52
+ - result.changed == true
+ - ansible_facts.network_resources.snmp_server == result.after
+ - result.after == deleted.after
+
+ - name: Idempotency check
+ become: true
+ register: result
+ cisco.iosxr.iosxr_snmp_server: *deleted
+ - ansible.builtin.assert:
+ that:
+ - result.commands|length == 0
+ - result.changed == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/empty_config.yaml
new file mode 100644
index 00000000..07010879
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/empty_config.yaml
@@ -0,0 +1,61 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_snmp_server empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_snmp_server:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_snmp_server:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Override with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_snmp_server:
+ config:
+ state: overridden
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Rendered with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_snmp_server:
+ config:
+ state: rendered
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
+
+- name: Parsed with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_snmp_server:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
+
+- ansible.builtin.debug:
+ msg: END iosxr_snmp_server empty_config integration tests on connection={{ ansible_connection }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/gathered.yaml
new file mode 100644
index 00000000..3ce0b0d2
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/gathered.yaml
@@ -0,0 +1,22 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_snmp_server gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Gathered the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_snmp_server:
+ config:
+ state: gathered
+
+ - name: Assert
+ ansible.builtin.assert:
+ that:
+ - merged.after == result.gathered
+ - result['changed'] == false
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/merged.yaml
new file mode 100644
index 00000000..c591a543
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/merged.yaml
@@ -0,0 +1,130 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_snmp_server merged integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ cisco.iosxr.iosxr_snmp_server: &merged
+ config:
+ vrfs:
+ - hosts:
+ - community: test1
+ host: 1.1.1.1
+ traps: true
+ vrf: vrf1
+ users:
+ - Ipv4_acl: test1
+ Ipv6_acl: test2
+ group: test2
+ user: u1
+ version: v1
+ timeouts:
+ duplicate: 0
+ inQdrop: 0
+ trap:
+ throttle_time: 12
+ targets:
+ - host: 1.1.1.2
+ name: test
+
+ ifmib:
+ internal_cache_max_duration: 4
+ inform:
+ retries: 7
+ chassis_id: test2
+ packetsize: 490
+ queue_length: 2
+ throttle_time: 60
+ trap_source: GigabitEthernet0/0/0/2
+ trap_timeout: 3
+ context:
+ - c1
+ - c2
+ contact: t1
+ correlator:
+ buffer_size: 1024
+ communities:
+ - name: test2
+ ro: true
+ sdrowner: true
+ acl_v4: test
+ acl_v6: test1
+ community_maps:
+ - name: cm1
+ context: c1
+ target_list: t1
+ security_name: s1
+ drop:
+ report_IPv4: test1
+ unknown_user: true
+ ipv6:
+ precedence: routine
+ ipv4:
+ dscp: af11
+ location: test1
+ logging_threshold_oid_processing: 1
+ logging_threshold_pdu_processing: 1
+ mib_bulkstat_max_procmem_size: 101
+ mroutemib_send_all_vrf: true
+ overload_control:
+ overload_drop_time: 4
+ overload_throttle_rate: 6
+ notification_log_mib:
+ GlobalSize: 5
+ size: 5
+ traps:
+ hsrp: true
+ ipsla: true
+ ipsec:
+ start: true
+ stop: true
+ bridgemib: true
+ bulkstat_collection: true
+ cisco_entity_ext: true
+ config: true
+ copy_complete: true
+ addrpool:
+ high: true
+ low: true
+ bfd: true
+ bgp:
+ cbgp2: true
+ l2tun:
+ sessions: true
+ tunnel_down: true
+ tunnel_up: true
+ l2vpn:
+ all: true
+ vc_down: true
+ vc_up: true
+ msdp_peer_state_change: true
+
+ register: result
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ result['before'] == {} }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['after']
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_snmp_server: *merged
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/overridden.yaml
new file mode 100644
index 00000000..e0dabf5c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/overridden.yaml
@@ -0,0 +1,112 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_snmp_server overridden integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Override snmp-server configuration with provided configuration
+ cisco.iosxr.iosxr_snmp_server: &override
+ config:
+ timeouts:
+ duplicate: 0
+ inQdrop: 0
+ trap:
+ throttle_time: 13
+ targets:
+ - host: 1.1.1.2
+ name: test
+
+ ifmib:
+ internal_cache_max_duration: 5
+ inform:
+ retries: 7
+ chassis_id: test
+ packetsize: 491
+ queue_length: 2
+ throttle_time: 60
+ trap_source: GigabitEthernet0/0/0/2
+ trap_timeout: 3
+ context:
+ - c1
+ - c2
+ contact: t1
+ correlator:
+ buffer_size: 1025
+ communities:
+ - name: test1
+ ro: true
+ sdrowner: true
+ acl_v4: test
+ acl_v6: test1
+ community_maps:
+ - name: cm2
+ context: c1
+ target_list: t1
+ security_name: s1
+ drop:
+ report_IPv4: test2
+ unknown_user: true
+ ipv6:
+ precedence: routine
+ ipv4:
+ dscp: af11
+ location: test1
+ logging_threshold_oid_processing: 2
+ logging_threshold_pdu_processing: 2
+ mib_bulkstat_max_procmem_size: 101
+ mroutemib_send_all_vrf: true
+ overload_control:
+ overload_drop_time: 4
+ overload_throttle_rate: 6
+ notification_log_mib:
+ GlobalSize: 5
+ size: 5
+ traps:
+ hsrp: true
+ ipsla: true
+ ipsec:
+ start: true
+ stop: true
+ bridgemib: true
+ bulkstat_collection: true
+ cisco_entity_ext: true
+ config: true
+ copy_complete: true
+ l2vpn:
+ all: true
+ vc_down: true
+ vc_up: true
+ msdp_peer_state_change: true
+ state: overridden
+
+ register: result
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - replaced['after'] == result['after']
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['before']
+
+ - name: Override the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_snmp_server: *override
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/parsed.yaml
new file mode 100644
index 00000000..4d7dce10
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/parsed.yaml
@@ -0,0 +1,14 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_snmp_server parsed integration tests on connection={{ ansible_connection }}
+
+- name: Parse externally provided snmp_server configuration
+ register: result
+ cisco.iosxr.iosxr_snmp_server:
+ running_config: "{{ lookup('file', './_parsed.cfg') }}"
+ state: parsed
+
+- name: Assert that configuration was correctly parsed
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['parsed']
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/rendered.yaml
new file mode 100644
index 00000000..052dd7fc
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/rendered.yaml
@@ -0,0 +1,108 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_snmp_server rendered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- name: Render platform specific configuration lines with state rendered (without connecting to the device)
+ cisco.iosxr.iosxr_snmp_server:
+ state: rendered
+ config:
+ vrfs:
+ - hosts:
+ - community: test1
+ host: 1.1.1.1
+ traps: true
+ vrf: vrf1
+ users:
+ - Ipv4_acl: test1
+ Ipv6_acl: test2
+ group: test2
+ user: u1
+ version: v1
+ timeouts:
+ duplicate: 0
+ inQdrop: 0
+ trap:
+ throttle_time: 12
+ targets:
+ - host: 1.1.1.2
+ name: test
+
+ ifmib:
+ internal_cache_max_duration: 4
+ inform:
+ retries: 7
+ chassis_id: test2
+ packetsize: 490
+ queue_length: 2
+ throttle_time: 60
+ trap_source: GigabitEthernet0/0/0/2
+ trap_timeout: 3
+ context:
+ - c1
+ - c2
+ contact: t1
+ correlator:
+ buffer_size: 1024
+ communities:
+ - name: test2
+ ro: true
+ sdrowner: true
+ acl_v4: test
+ acl_v6: test1
+ community_maps:
+ - name: cm1
+ context: c1
+ target_list: t1
+ security_name: s1
+ drop:
+ report_IPv4: test1
+ unknown_user: true
+ ipv6:
+ precedence: routine
+ ipv4:
+ dscp: af11
+ location: test1
+ logging_threshold_oid_processing: 1
+ logging_threshold_pdu_processing: 1
+ mib_bulkstat_max_procmem_size: 101
+ mroutemib_send_all_vrf: true
+ overload_control:
+ overload_drop_time: 4
+ overload_throttle_rate: 6
+ notification_log_mib:
+ GlobalSize: 5
+ size: 5
+ traps:
+ hsrp: true
+ ipsla: true
+ ipsec:
+ start: true
+ stop: true
+ bridgemib: true
+ bulkstat_collection: true
+ cisco_entity_ext: true
+ config: true
+ copy_complete: true
+ addrpool:
+ high: true
+ low: true
+ bfd: true
+ bgp:
+ cbgp2: true
+ l2tun:
+ sessions: true
+ tunnel_down: true
+ tunnel_up: true
+ l2vpn:
+ all: true
+ vc_down: true
+ vc_up: true
+ msdp_peer_state_change: true
+ register: result
+
+- name: Assert that correct set of commands were rendered
+ ansible.builtin.assert:
+ that:
+ - merged['commands'] == result['rendered']
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/replaced.yaml
new file mode 100644
index 00000000..c295777b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/tests/common/replaced.yaml
@@ -0,0 +1,114 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_snmp_server replaced integration tests connection={{ ansible_connection}}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replace snmp-server configuration with provided configuration
+ cisco.iosxr.iosxr_snmp_server: &replace
+ state: replaced
+ config:
+ timeouts:
+ duplicate: 0
+ inQdrop: 0
+ trap:
+ throttle_time: 13
+ targets:
+ - host: 1.1.1.2
+ name: test
+
+ ifmib:
+ internal_cache_max_duration: 5
+ inform:
+ retries: 7
+ chassis_id: test
+ packetsize: 491
+ queue_length: 2
+ throttle_time: 60
+ trap_source: GigabitEthernet0/0/0/2
+ trap_timeout: 3
+ context:
+ - c1
+ - c2
+ contact: t1
+ correlator:
+ buffer_size: 1025
+ communities:
+ - name: test1
+ ro: true
+ sdrowner: true
+ acl_v4: test
+ acl_v6: test1
+ community_maps:
+ - name: cm2
+ context: c1
+ target_list: t1
+ security_name: s1
+ drop:
+ report_IPv4: test2
+ unknown_user: true
+ ipv6:
+ precedence: routine
+ ipv4:
+ dscp: af11
+ location: test1
+ logging_threshold_oid_processing: 2
+ logging_threshold_pdu_processing: 2
+ mib_bulkstat_max_procmem_size: 101
+ mroutemib_send_all_vrf: true
+ overload_control:
+ overload_drop_time: 4
+ overload_throttle_rate: 6
+ notification_log_mib:
+ GlobalSize: 5
+ size: 5
+ traps:
+ hsrp: true
+ ipsla: true
+ ipsec:
+ start: true
+ stop: true
+ bridgemib: true
+ bulkstat_collection: true
+ cisco_entity_ext: true
+ config: true
+ copy_complete: true
+ l2vpn:
+ all: true
+ vc_down: true
+ vc_up: true
+ msdp_peer_state_change: true
+ register: result
+
+ - ansible.builtin.debug:
+ msg: "{{ replaced['commands'] | symmetric_difference(result['commands']) }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - replaced['after'] == result['after']
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - merged['after'] == result['before']
+
+ - name: Replace the provided configuration with the existing running configuration (idempotent)
+ cisco.iosxr.iosxr_snmp_server: *replace
+ register: result
+
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/vars/main.yaml
new file mode 100644
index 00000000..39031229
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_snmp_server/vars/main.yaml
@@ -0,0 +1,249 @@
+---
+merged:
+ commands:
+ - snmp-server chassis-id test2
+ - snmp-server correlator buffer-size 1024
+ - snmp-server contact t1
+ - snmp-server ipv4 dscp af11
+ - snmp-server ipv6 precedence routine
+ - snmp-server location test1
+ - snmp-server logging threshold oid-processing 1
+ - snmp-server logging threshold pdu-processing 1
+ - snmp-server mib bulkstat max-procmem-size 101
+ - snmp-server mroutemib send-all-vrf
+ - snmp-server overload-control 4 6
+ - snmp-server packetsize 490
+ - snmp-server queue-length 2
+ - snmp-server throttle-time 60
+ - snmp-server trap-source GigabitEthernet0/0/0/2
+ - snmp-server trap-timeout 3
+ - snmp-server drop report acl IPv4 test1
+ - snmp-server drop unknown-user
+ - snmp-server ifmib internal cache max-duration 4
+ - snmp-server inform retries 7
+ - snmp-server notification-log-mib size 5
+ - snmp-server notification-log-mib GlobalSize 5
+ - snmp-server trap throttle-time 12
+ - snmp-server timeouts inQdrop 0
+ - snmp-server timeouts duplicate 0
+ - snmp-server traps addrpool low
+ - snmp-server traps addrpool high
+ - snmp-server traps bfd
+ - snmp-server traps bgp cbgp2
+ - snmp-server traps bulkstat collection
+ - snmp-server traps bridgemib
+ - snmp-server traps copy-complete
+ - snmp-server traps cisco-entity-ext
+ - snmp-server traps config
+ - snmp-server traps hsrp
+ - snmp-server traps ipsla
+ - snmp-server traps ipsec tunnel start
+ - snmp-server traps ipsec tunnel stop
+ - snmp-server traps l2tun sessions
+ - snmp-server traps l2tun tunnel-up
+ - snmp-server traps l2tun tunnel-down
+ - snmp-server traps l2vpn all
+ - snmp-server traps l2vpn vc-up
+ - snmp-server traps l2vpn vc-down
+ - snmp-server traps msdp peer-state-change
+ - snmp-server community test2 RO SDROwner IPv4 test IPv6 test1
+ - snmp-server community-map cm1 context c1 security-name s1 target-list t1
+ - snmp-server context c1
+ - snmp-server context c2
+ - snmp-server user u1 test2 v1 IPv4 test1 IPv6 test2
+ - snmp-server target list test host 1.1.1.2
+ - snmp-server vrf vrf1
+ - host 1.1.1.1 traps test1
+
+ after:
+ vrfs:
+ - hosts:
+ - community: test1
+ host: 1.1.1.1
+ traps: true
+ vrf: vrf1
+ users:
+ - acl_v4: test1
+ acl_v6: test2
+ group: test2
+ user: u1
+ version: v1
+ timeouts:
+ duplicate: 0
+ inQdrop: 0
+ trap:
+ throttle_time: 12
+ targets:
+ - host: 1.1.1.2
+ name: test
+
+ ifmib:
+ internal_cache_max_duration: 4
+ inform:
+ retries: 7
+ chassis_id: test2
+ packetsize: 490
+ queue_length: 2
+ throttle_time: 60
+ trap_source: GigabitEthernet0/0/0/2
+ trap_timeout: 3
+ context:
+ - c1
+ - c2
+ contact: t1
+ correlator:
+ buffer_size: 1024
+ communities:
+ - name: test2
+ ro: true
+ sdrowner: true
+ acl_v4: test
+ acl_v6: test1
+ community_maps:
+ - name: cm1
+ context: c1
+ target_list: t1
+ security_name: s1
+ drop:
+ report_IPv4: test1
+ unknown_user: true
+ ipv6:
+ precedence: routine
+ ipv4:
+ dscp: af11
+ location: test1
+ logging_threshold_oid_processing: 1
+ logging_threshold_pdu_processing: 1
+ mib_bulkstat_max_procmem_size: 101
+ mroutemib_send_all_vrf: true
+ overload_control:
+ overload_drop_time: 4
+ overload_throttle_rate: 6
+ notification_log_mib:
+ GlobalSize: 5
+ size: 5
+ traps:
+ hsrp: true
+ ipsla: true
+ ipsec:
+ start: true
+ stop: true
+ bridgemib: true
+ bulkstat_collection: true
+ cisco_entity_ext: true
+ config: true
+ copy_complete: true
+ addrpool:
+ high: true
+ low: true
+ bfd: true
+ bgp:
+ cbgp2: true
+ l2tun:
+ sessions: true
+ tunnel_down: true
+ tunnel_up: true
+ l2vpn:
+ all: true
+ vc_down: true
+ vc_up: true
+ msdp_peer_state_change: true
+
+deleted:
+ after: {}
+
+replaced:
+ commands:
+ - no snmp-server traps addrpool low
+ - no snmp-server traps addrpool high
+ - no snmp-server traps bfd
+ - no snmp-server traps bgp cbgp2
+ - no snmp-server traps l2tun sessions
+ - no snmp-server traps l2tun tunnel-up
+ - no snmp-server traps l2tun tunnel-down
+ - no snmp-server community test2 RO SDROwner IPv4 test IPv6 test1
+ - no snmp-server community-map cm1 context c1 security-name s1 target-list t1
+ - no snmp-server user u1 test2 v1 IPv4 test1 IPv6 test2
+ - no snmp-server vrf vrf1
+ - snmp-server chassis-id test
+ - snmp-server correlator buffer-size 1025
+ - snmp-server logging threshold oid-processing 2
+ - snmp-server logging threshold pdu-processing 2
+ - snmp-server packetsize 491
+ - snmp-server drop report acl IPv4 test2
+ - snmp-server ifmib internal cache max-duration 5
+ - snmp-server trap throttle-time 13
+ - snmp-server community test1 RO SDROwner IPv4 test IPv6 test1
+ - snmp-server community-map cm2 context c1 security-name s1 target-list t1
+
+ after:
+ timeouts:
+ duplicate: 0
+ inQdrop: 0
+ trap:
+ throttle_time: 13
+ targets:
+ - host: 1.1.1.2
+ name: test
+
+ ifmib:
+ internal_cache_max_duration: 5
+ inform:
+ retries: 7
+ chassis_id: test
+ packetsize: 491
+ queue_length: 2
+ throttle_time: 60
+ trap_source: GigabitEthernet0/0/0/2
+ trap_timeout: 3
+ context:
+ - c1
+ - c2
+ contact: t1
+ correlator:
+ buffer_size: 1025
+ communities:
+ - name: test1
+ ro: true
+ sdrowner: true
+ acl_v4: test
+ acl_v6: test1
+ community_maps:
+ - name: cm2
+ context: c1
+ target_list: t1
+ security_name: s1
+ drop:
+ report_IPv4: test2
+ unknown_user: true
+ ipv6:
+ precedence: routine
+ ipv4:
+ dscp: af11
+ location: test1
+ logging_threshold_oid_processing: 2
+ logging_threshold_pdu_processing: 2
+ mib_bulkstat_max_procmem_size: 101
+ mroutemib_send_all_vrf: true
+ overload_control:
+ overload_drop_time: 4
+ overload_throttle_rate: 6
+ notification_log_mib:
+ GlobalSize: 5
+ size: 5
+ traps:
+ hsrp: true
+ ipsla: true
+ ipsec:
+ start: true
+ stop: true
+ bridgemib: true
+ bulkstat_collection: true
+ cisco_entity_ext: true
+ config: true
+ copy_complete: true
+ l2vpn:
+ all: true
+ vc_down: true
+ vc_up: true
+ msdp_peer_state_change: true
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/fixtures/parsed.cfg b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/fixtures/parsed.cfg
new file mode 100644
index 00000000..35948336
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/fixtures/parsed.cfg
@@ -0,0 +1,18 @@
+Fri Nov 29 21:10:41.896 UTC
+router static
+ address-family ipv4 unicast
+ 192.0.2.16/28 FastEthernet0/0/0/1 192.0.2.10 tag 10 description LAB metric 120
+ 192.0.2.16/28 FastEthernet0/0/0/5 track ip_sla_1
+ 192.0.2.32/28 192.0.2.11 100
+ !
+ address-family ipv6 unicast
+ 2001:db8:1000::/36 FastEthernet0/0/0/7 description DC
+ 2001:db8:1000::/36 FastEthernet0/0/0/8 2001:db8:2000:2::1
+ !
+ vrf DEV_SITE
+ address-family ipv4 unicast
+ 192.0.2.48/28 vrf test_1 192.0.2.12 description DEV
+ 192.0.2.80/28 vrf test_1 FastEthernet0/0/0/2 192.0.2.14 vrflabel 124 track ip_sla_2
+ !
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tasks/cli.yaml
new file mode 100644
index 00000000..01bf509b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/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 }}"
+ delegate_to: localhost
+
+- 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/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tasks/main.yaml
new file mode 100644
index 00000000..4b7d599c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/_populate_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/_populate_config.yaml
new file mode 100644
index 00000000..e38008ec
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/_populate_config.yaml
@@ -0,0 +1,58 @@
+---
+- name: Setup
+ cisco.iosxr.iosxr_static_routes:
+ config:
+ - address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.16/28
+ next_hops:
+ - forward_router_address: 192.0.2.10
+ interface: FastEthernet0/0/0/1
+ description: LAB
+ metric: 120
+ tag: 10
+
+ - interface: FastEthernet0/0/0/5
+ track: ip_sla_1
+
+ - dest: 192.0.2.32/28
+ next_hops:
+ - forward_router_address: 192.0.2.11
+ admin_distance: 100
+
+ - afi: ipv6
+ safi: unicast
+ routes:
+ - dest: 2001:db8:1000::/36
+ next_hops:
+ - interface: FastEthernet0/0/0/7
+ description: DC
+
+ - interface: FastEthernet0/0/0/8
+ forward_router_address: 2001:db8:2000:2::1
+
+ - vrf: DEV_SITE
+ address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.48/28
+ next_hops:
+ - forward_router_address: 192.0.2.12
+ description: DEV
+ dest_vrf: test_1
+
+ - forward_router_address: 192.0.3.24
+ interface: GigabitEthernet0/0/0/1
+ vrflabel: 2302
+
+ - dest: 192.0.2.80/28
+ next_hops:
+ - interface: FastEthernet0/0/0/2
+ forward_router_address: 192.0.2.14
+ dest_vrf: test_1
+ track: ip_sla_2
+ vrflabel: 124
+ state: merged
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/_remove_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/_remove_config.yaml
new file mode 100644
index 00000000..7acca740
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/_remove_config.yaml
@@ -0,0 +1,7 @@
+---
+- name: Remove static routes
+ vars:
+ lines: "no router static\n"
+ ignore_errors: true
+ ansible.netcommon.cli_config:
+ config: "{{ lines }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/deleted.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/deleted.yaml
new file mode 100644
index 00000000..dc53d003
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/deleted.yaml
@@ -0,0 +1,68 @@
+---
+- ansible.builtin.debug:
+ msg: Start iosxr_static_routes deleted integration tests ansible_connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Delete all destination network entries under a single AFI
+ register: result
+ cisco.iosxr.iosxr_static_routes: &id001
+ config:
+ - vrf: DEV_SITE
+ address_families:
+ - afi: ipv4
+ safi: unicast
+ state: deleted
+
+ - ansible.builtin.assert:
+ that:
+ - '"router static" in result.commands'
+ - '"vrf DEV_SITE" in result.commands'
+ - '"no address-family ipv4 unicast" in result.commands'
+ - result.commands|length == 3
+
+ - name: Delete all destination network entries under a single AFI (idempotent)
+ register: result
+ cisco.iosxr.iosxr_static_routes: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert: &id003
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - ansible.builtin.include_tasks: _populate_config.yaml
+
+ - name: Delete static routes configuration
+ register: result
+ cisco.iosxr.iosxr_static_routes: &id002
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that the correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Delete all static routes (idempotent)
+ register: result
+ cisco.iosxr.iosxr_static_routes: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert: *id003
+ - name: Assert that the before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ deleted['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/empty_config.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/empty_config.yaml
new file mode 100644
index 00000000..4dd456a1
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/empty_config.yaml
@@ -0,0 +1,47 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_static_routes empty_config integration tests on connection={{ ansible_connection }}
+
+- name: Merged with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_static_routes:
+ config:
+ state: merged
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_static_routes:
+ config:
+ state: replaced
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty configuration should give appropriate error message
+ register: result
+ ignore_errors: true
+ cisco.iosxr.iosxr_static_routes:
+ config:
+ state: overridden
+
+- ansible.builtin.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
+ cisco.iosxr.iosxr_static_routes:
+ running_config:
+ state: parsed
+
+- ansible.builtin.assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state parsed'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/gathered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/gathered.yaml
new file mode 100644
index 00000000..23b9b3d0
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/gathered.yaml
@@ -0,0 +1,18 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_static_routes gathered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Gather static routes facts from the device using iosxr_static_routes module
+ register: result
+ cisco.iosxr.iosxr_static_routes:
+ state: gathered
+
+ - ansible.builtin.assert:
+ that: "{{ replaced['before'] | symmetric_difference(result['gathered']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/merged.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/merged.yaml
new file mode 100644
index 00000000..c848e7c2
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/merged.yaml
@@ -0,0 +1,138 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_static_routes merged integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Merge the provided configuration with the existing running configuration
+ register: result
+ cisco.iosxr.iosxr_static_routes: &id001
+ config:
+ - address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.16/28
+ next_hops:
+ - forward_router_address: 192.0.2.10
+ interface: FastEthernet0/0/0/1
+ description: LAB
+ metric: 120
+ tag: 10
+
+ - interface: FastEthernet0/0/0/5
+ track: ip_sla_1
+
+ - dest: 192.0.2.32/28
+ next_hops:
+ - forward_router_address: 192.0.2.11
+ admin_distance: 100
+
+ - afi: ipv6
+ safi: unicast
+ routes:
+ - dest: 2001:db8:1000::/36
+ next_hops:
+ - interface: FastEthernet0/0/0/7
+ description: DC
+
+ - interface: FastEthernet0/0/0/8
+ forward_router_address: 2001:db8:2000:2::1
+
+ - vrf: DEV_SITE
+ address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.48/28
+ next_hops:
+ - forward_router_address: 192.0.2.12
+ description: DEV
+ dest_vrf: test_1
+
+ - dest: 192.0.2.80/28
+ next_hops:
+ - interface: FastEthernet0/0/0/2
+ forward_router_address: 192.0.2.14
+ dest_vrf: test_1
+ track: ip_sla_2
+ vrflabel: 124
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - ansible.builtin.set_fact:
+ diff: "{{ merged['after'] | symmetric_difference(result['after']) }}"
+
+ - name: Assert that after dicts was correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Merge the provided configuration with the existing running configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_static_routes: *id001
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Update existing configuration using merged
+ register: result
+ cisco.iosxr.iosxr_static_routes: &id002
+ config:
+ - vrf: DEV_SITE
+ address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.48/28
+ next_hops:
+ - forward_router_address: 192.0.2.12
+ vrflabel: 2301
+ dest_vrf: test_1
+
+ - dest: 192.0.2.80/28
+ next_hops:
+ - interface: FastEthernet0/0/0/2
+ forward_router_address: 192.0.2.14
+ dest_vrf: test_1
+ description: rt_test_1
+
+ - name: Assert that before dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ merged['update_commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that after dicts were correctly generated
+ ansible.builtin.assert:
+ that: "{{ merged['update_after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Update existing static_routes configuration using merged (idempotent)
+ register: result
+ cisco.iosxr.iosxr_static_routes: *id002
+ - name: Assert that the previous task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/overridden.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/overridden.yaml
new file mode 100644
index 00000000..0c75b6ca
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/overridden.yaml
@@ -0,0 +1,65 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_static_routes overridden integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Overridde all static routes configuration with provided configuration
+ register: result
+ cisco.iosxr.iosxr_static_routes: &id001
+ config:
+ - vrf: DEV_NEW
+ address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.48/28
+ next_hops:
+ - forward_router_address: 192.0.2.15
+ interface: FastEthernet0/0/0/3
+ description: DEV1
+
+ - afi: ipv6
+ safi: unicast
+ routes:
+ - dest: 2001:db8:3000::/36
+ next_hops:
+ - interface: FastEthernet0/0/0/4
+ forward_router_address: 2001:db8:2000:2::2
+ description: PROD1
+ track: ip_sla_1
+ state: overridden
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Overridde all static routes configuration with given configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_static_routes: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/parsed.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/parsed.yaml
new file mode 100644
index 00000000..d06987a5
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/parsed.yaml
@@ -0,0 +1,13 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_static_routes parsed integration tests on connection={{ ansible_connection }}
+
+- block:
+ - name: Use parsed state to convert externally supplied device specific static routes commands to structured format
+ register: result
+ cisco.iosxr.iosxr_static_routes:
+ running_config: "{{ lookup('file', '../../fixtures/parsed.cfg') }}"
+ state: parsed
+
+ - ansible.builtin.assert:
+ that: "{{ merged['after'] | symmetric_difference(result['parsed']) |length==0 }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/rendered.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/rendered.yaml
new file mode 100644
index 00000000..8170afb7
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/rendered.yaml
@@ -0,0 +1,75 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_static_routes rendered integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- block:
+ - name: Use rendered state to convert task input to device specific commands
+ register: result
+ cisco.iosxr.iosxr_static_routes:
+ config:
+ - vrf: DEV_SITE
+ address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.48/28
+ next_hops:
+ - forward_router_address: 192.0.2.12
+ description: DEV
+ dest_vrf: test_1
+
+ - dest: 192.0.2.80/28
+ next_hops:
+ - interface: FastEthernet0/0/0/2
+ forward_router_address: 192.0.2.14
+ dest_vrf: test_1
+ track: ip_sla_2
+ vrflabel: 124
+
+ - address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.16/28
+ next_hops:
+ - forward_router_address: 192.0.2.10
+ interface: FastEthernet0/0/0/1
+ description: LAB
+ metric: 120
+ tag: 10
+
+ - interface: FastEthernet0/0/0/5
+ track: ip_sla_1
+
+ - dest: 192.0.2.32/28
+ next_hops:
+ - forward_router_address: 192.0.2.11
+ admin_distance: 100
+
+ - afi: ipv6
+ safi: unicast
+ routes:
+ - dest: 2001:db8:1000::/36
+ next_hops:
+ - interface: FastEthernet0/0/0/7
+ description: DC
+
+ - interface: FastEthernet0/0/0/8
+ forward_router_address: 2001:db8:2000:2::1
+ state: rendered
+
+ - ansible.builtin.assert:
+ that: "{{ merged['commands'] | symmetric_difference(result['rendered']) |length==0 }}"
+
+ - name: Gather static routes facts from the device and assert that its empty
+ register: result
+ cisco.iosxr.iosxr_static_routes:
+ state: gathered
+
+ - name: Make sure that rendered task actually did not make any changes to the device
+ ansible.builtin.assert:
+ that: "{{ result['gathered'] == [] }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/replaced.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/replaced.yaml
new file mode 100644
index 00000000..4386731d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/replaced.yaml
@@ -0,0 +1,56 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_static_routes replaced integration tests on connection={{ ansible_connection }}
+
+- ansible.builtin.include_tasks: _remove_config.yaml
+
+- ansible.builtin.include_tasks: _populate_config.yaml
+
+- block:
+ - name: Replace device configurations of static routes with provided configurations
+ register: result
+ cisco.iosxr.iosxr_static_routes: &id001
+ config:
+ - vrf: DEV_SITE
+ address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.48/28
+ next_hops:
+ - forward_router_address: 192.0.2.15
+ interface: FastEthernet0/0/0/3
+ description: DEV_NEW
+ dest_vrf: dev_test_2
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['before'] | symmetric_difference(result['before']) |length == 0 }}"
+
+ - name: Assert that after dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Replace device configurations of listed vrfs/global entry with provided configuration (idempotent)
+ register: result
+ cisco.iosxr.iosxr_static_routes: *id001
+ - name: Assert that task was idempotent
+ ansible.builtin.assert:
+ that:
+ - result['changed'] == false
+ - result.commands|length == 0
+
+ - name: Assert that before dict is correctly generated
+ ansible.builtin.assert:
+ that:
+ - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/rtt.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/rtt.yaml
new file mode 100644
index 00000000..40e47d2a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/tests/cli/rtt.yaml
@@ -0,0 +1,73 @@
+---
+- ansible.builtin.debug:
+ msg: START iosxr_static_routes round trip integration tests on connection={{ ansible_connection }}
+
+- block:
+ - ansible.builtin.include_tasks: _remove_config.yaml
+
+ - name: Apply the provided configuration (base config)
+ register: base_config
+ cisco.iosxr.iosxr_static_routes:
+ config:
+ - address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.48/28
+ next_hops:
+ - forward_router_address: 192.0.2.15
+ admin_distance: 105
+ track: ip_sla_2
+
+ - vrf: DEV_SITE
+ address_families:
+ - afi: ipv6
+ safi: unicast
+ routes:
+ - dest: 2001:db8:3000::/36
+ next_hops:
+ - forward_router_address: 2001:db8:2000:2::2
+ interface: FastEthernet0/0/0/11
+ description: PROD1
+ state: merged
+
+ - name: Gather interfaces facts
+ cisco.iosxr.iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - static_routes
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ cisco.iosxr.iosxr_static_routes:
+ config:
+ - vrf: TEST_SITE
+ address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.80/28
+ next_hops:
+ - forward_router_address: 192.0.2.12
+ interface: FastEthernet0/0/0/3
+ description: DEV_MOVED
+ dest_vrf: dev_moved
+ state: overridden
+
+ - name: Assert that changes were applied
+ ansible.builtin.assert:
+ that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length == 0 }}"
+
+ - name: Revert back to base configuration using facts round trip
+ register: revert
+ cisco.iosxr.iosxr_static_routes:
+ config: "{{ ansible_facts['network_resources']['static_routes'] }}"
+ state: overridden
+
+ - name: Assert that configuration was reverted
+ ansible.builtin.assert:
+ that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}"
+ always:
+ - ansible.builtin.include_tasks: _remove_config.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/vars/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/vars/main.yaml
new file mode 100644
index 00000000..b12c6698
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_static_routes/vars/main.yaml
@@ -0,0 +1,264 @@
+---
+merged:
+ before: []
+ commands:
+ - router static
+ - address-family ipv4 unicast
+ - 192.0.2.16/28 192.0.2.10 FastEthernet0/0/0/1 description LAB metric 120 tag
+ 10
+ - 192.0.2.16/28 FastEthernet0/0/0/5 track ip_sla_1
+ - 192.0.2.32/28 192.0.2.11 100
+ - address-family ipv6 unicast
+ - 2001:db8:1000::/36 FastEthernet0/0/0/7 description DC
+ - 2001:db8:1000::/36 2001:db8:2000:2::1 FastEthernet0/0/0/8
+ - vrf DEV_SITE
+ - address-family ipv4 unicast
+ - 192.0.2.48/28 vrf test_1 192.0.2.12 description DEV
+ - 192.0.2.80/28 vrf test_1 192.0.2.14 FastEthernet0/0/0/2 track ip_sla_2 vrflabel
+ 124
+ update_commands:
+ - router static
+ - vrf DEV_SITE
+ - address-family ipv4 unicast
+ - 192.0.2.48/28 vrf test_1 192.0.2.12 description DEV vrflabel 2301
+ - 192.0.2.80/28 vrf test_1 192.0.2.14 FastEthernet0/0/0/2 description rt_test_1
+ track ip_sla_2 vrflabel 124
+ after:
+ - address_families:
+ - afi: ipv4
+ routes:
+ - dest: 192.0.2.16/28
+ next_hops:
+ - description: LAB
+ forward_router_address: 192.0.2.10
+ interface: FastEthernet0/0/0/1
+ metric: 120
+ tag: 10
+ - interface: FastEthernet0/0/0/5
+ track: ip_sla_1
+ - dest: 192.0.2.32/28
+ next_hops:
+ - admin_distance: 100
+ forward_router_address: 192.0.2.11
+ safi: unicast
+ - afi: ipv6
+ routes:
+ - dest: 2001:db8:1000::/36
+ next_hops:
+ - description: DC
+ interface: FastEthernet0/0/0/7
+ - forward_router_address: 2001:db8:2000:2::1
+ interface: FastEthernet0/0/0/8
+ safi: unicast
+ - address_families:
+ - afi: ipv4
+ routes:
+ - dest: 192.0.2.48/28
+ next_hops:
+ - description: DEV
+ dest_vrf: test_1
+ forward_router_address: 192.0.2.12
+ - dest: 192.0.2.80/28
+ next_hops:
+ - dest_vrf: test_1
+ forward_router_address: 192.0.2.14
+ interface: FastEthernet0/0/0/2
+ track: ip_sla_2
+ vrflabel: 124
+ safi: unicast
+ vrf: DEV_SITE
+ update_after:
+ - address_families:
+ - afi: ipv4
+ routes:
+ - dest: 192.0.2.16/28
+ next_hops:
+ - description: LAB
+ forward_router_address: 192.0.2.10
+ interface: FastEthernet0/0/0/1
+ metric: 120
+ tag: 10
+ - interface: FastEthernet0/0/0/5
+ track: ip_sla_1
+ - dest: 192.0.2.32/28
+ next_hops:
+ - admin_distance: 100
+ forward_router_address: 192.0.2.11
+ safi: unicast
+ - afi: ipv6
+ routes:
+ - dest: 2001:db8:1000::/36
+ next_hops:
+ - description: DC
+ interface: FastEthernet0/0/0/7
+ - forward_router_address: 2001:db8:2000:2::1
+ interface: FastEthernet0/0/0/8
+ safi: unicast
+ - address_families:
+ - afi: ipv4
+ routes:
+ - dest: 192.0.2.48/28
+ next_hops:
+ - description: DEV
+ dest_vrf: test_1
+ forward_router_address: 192.0.2.12
+ vrflabel: 2301
+ - dest: 192.0.2.80/28
+ next_hops:
+ - dest_vrf: test_1
+ forward_router_address: 192.0.2.14
+ interface: FastEthernet0/0/0/2
+ track: ip_sla_2
+ vrflabel: 124
+ description: rt_test_1
+ safi: unicast
+ vrf: DEV_SITE
+replaced:
+ before:
+ - address_families:
+ - afi: ipv4
+ routes:
+ - dest: 192.0.2.16/28
+ next_hops:
+ - description: LAB
+ forward_router_address: 192.0.2.10
+ interface: FastEthernet0/0/0/1
+ metric: 120
+ tag: 10
+ - interface: FastEthernet0/0/0/5
+ track: ip_sla_1
+ - dest: 192.0.2.32/28
+ next_hops:
+ - admin_distance: 100
+ forward_router_address: 192.0.2.11
+ safi: unicast
+ - afi: ipv6
+ routes:
+ - dest: 2001:db8:1000::/36
+ next_hops:
+ - description: DC
+ interface: FastEthernet0/0/0/7
+ - forward_router_address: 2001:db8:2000:2::1
+ interface: FastEthernet0/0/0/8
+ safi: unicast
+ - address_families:
+ - afi: ipv4
+ routes:
+ - dest: 192.0.2.48/28
+ next_hops:
+ - description: DEV
+ dest_vrf: test_1
+ forward_router_address: 192.0.2.12
+ - forward_router_address: 192.0.3.24
+ interface: GigabitEthernet0/0/0/1
+ vrflabel: 2302
+ - dest: 192.0.2.80/28
+ next_hops:
+ - dest_vrf: test_1
+ forward_router_address: 192.0.2.14
+ interface: FastEthernet0/0/0/2
+ track: ip_sla_2
+ vrflabel: 124
+ safi: unicast
+ vrf: DEV_SITE
+ commands:
+ - router static
+ - vrf DEV_SITE
+ - address-family ipv4 unicast
+ - no 192.0.2.48/28 192.0.3.24 GigabitEthernet0/0/0/1
+ - no 192.0.2.48/28 vrf test_1 192.0.2.12
+ - 192.0.2.48/28 vrf dev_test_2 192.0.2.15 FastEthernet0/0/0/3 description DEV_NEW
+ after:
+ - address_families:
+ - afi: ipv4
+ routes:
+ - dest: 192.0.2.16/28
+ next_hops:
+ - description: LAB
+ forward_router_address: 192.0.2.10
+ interface: FastEthernet0/0/0/1
+ metric: 120
+ tag: 10
+ - interface: FastEthernet0/0/0/5
+ track: ip_sla_1
+ - dest: 192.0.2.32/28
+ next_hops:
+ - admin_distance: 100
+ forward_router_address: 192.0.2.11
+ safi: unicast
+ - afi: ipv6
+ routes:
+ - dest: 2001:db8:1000::/36
+ next_hops:
+ - description: DC
+ interface: FastEthernet0/0/0/7
+ - forward_router_address: 2001:db8:2000:2::1
+ interface: FastEthernet0/0/0/8
+ safi: unicast
+ - address_families:
+ - afi: ipv4
+ routes:
+ - dest: 192.0.2.48/28
+ next_hops:
+ - forward_router_address: 192.0.2.15
+ interface: FastEthernet0/0/0/3
+ description: DEV_NEW
+ dest_vrf: dev_test_2
+ - dest: 192.0.2.80/28
+ next_hops:
+ - dest_vrf: test_1
+ forward_router_address: 192.0.2.14
+ interface: FastEthernet0/0/0/2
+ track: ip_sla_2
+ vrflabel: 124
+ safi: unicast
+ vrf: DEV_SITE
+overridden:
+ commands:
+ - router static
+ - no vrf DEV_SITE
+ - no address-family ipv4 unicast
+ - no address-family ipv6 unicast
+ - vrf DEV_NEW
+ - address-family ipv4 unicast
+ - 192.0.2.48/28 192.0.2.15 FastEthernet0/0/0/3 description DEV1
+ - address-family ipv6 unicast
+ - 2001:db8:3000::/36 2001:db8:2000:2::2 FastEthernet0/0/0/4 description PROD1
+ track ip_sla_1
+ after:
+ - vrf: DEV_NEW
+ address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.48/28
+ next_hops:
+ - forward_router_address: 192.0.2.15
+ interface: FastEthernet0/0/0/3
+ description: DEV1
+ - afi: ipv6
+ safi: unicast
+ routes:
+ - dest: 2001:db8:3000::/36
+ next_hops:
+ - interface: FastEthernet0/0/0/4
+ forward_router_address: 2001:db8:2000:2::2
+ description: PROD1
+ track: ip_sla_1
+deleted:
+ commands:
+ - no router static
+ after: []
+round_trip:
+ after:
+ - vrf: TEST_SITE
+ address_families:
+ - afi: ipv4
+ safi: unicast
+ routes:
+ - dest: 192.0.2.80/28
+ next_hops:
+ - forward_router_address: 192.0.2.12
+ interface: FastEthernet0/0/0/3
+ description: DEV_MOVED
+ dest_vrf: dev_moved
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/defaults/main.yaml
new file mode 100644
index 00000000..5f709c5a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/defaults/main.yaml
@@ -0,0 +1,2 @@
+---
+testcase: "*"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/meta/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/meta/main.yml
new file mode 100644
index 00000000..be631e5d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_iosxr_tests
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tasks/cli.yaml
new file mode 100644
index 00000000..8ae46e43
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tasks/cli.yaml
@@ -0,0 +1,23 @@
+---
+- name: Collect all CLI test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/cli"
+ patterns: "{{ testcase }}.yaml"
+ 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
+ tags:
+ - network_cli
+
+- name: Reset connection
+ ansible.builtin.meta: reset_connection
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tasks/main.yaml
new file mode 100644
index 00000000..419a6cde
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tasks/main.yaml
@@ -0,0 +1,6 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+
+- name: Include the netconf tasks
+ ansible.builtin.include_tasks: netconf.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tasks/netconf.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tasks/netconf.yaml
new file mode 100644
index 00000000..d04b0210
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tasks/netconf.yaml
@@ -0,0 +1,21 @@
+---
+- name: Collect all netconf test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/netconf"
+ patterns: "{{ testcase }}.yaml"
+ 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.netconf)
+ ansible.builtin.include_tasks: "{{ test_case_to_run }}"
+ with_items: "{{ test_items }}"
+ loop_control:
+ loop_var: test_case_to_run
+ tags:
+ - netconf
+
+- name: Reset connection
+ ansible.builtin.meta: reset_connection
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_domain_list.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_domain_list.yaml
new file mode 100644
index 00000000..0cde8790
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_domain_list.yaml
@@ -0,0 +1,111 @@
+---
+- ansible.builtin.debug: msg="START cli/set_domain_search.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no domain list ansible.com
+ - no domain list redhat.com
+ match: none
+
+- name: Configure domain_search
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+ - redhat.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'domain list ansible.com' in result.commands"
+ - "'domain list redhat.com' in result.commands"
+
+- name: Verify domain_search
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+ - redhat.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Remove one entry
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'no domain list redhat.com' in result.commands"
+
+- name: Verify remove one entry
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Add one entry
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+ - redhat.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'domain list redhat.com' in result.commands"
+
+- name: Verify add one entry
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+ - redhat.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Add and remove one entry
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+ - eng.ansible.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'no domain list redhat.com' in result.commands"
+ - "'domain list eng.ansible.com' in result.commands"
+ - result.commands|length == 2
+
+- name: Verify add and remove one entry
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+ - eng.ansible.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no domain list ansible.com
+ - no domain list eng.ansible.com
+ match: none
+
+- ansible.builtin.debug: msg="END cli/set_domain_search.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_domain_name.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_domain_name.yaml
new file mode 100644
index 00000000..08e18c2b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_domain_name.yaml
@@ -0,0 +1,32 @@
+---
+- ansible.builtin.debug: msg="START cli/set_domain_name.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ lines: no domain name
+ match: none
+
+- name: Configure domain_name
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_name: eng.ansible.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Verify domain_name
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_name: eng.ansible.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ lines: no domain name
+ match: none
+
+- ansible.builtin.debug: msg="END cli/set_domain_name.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_hostname.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_hostname.yaml
new file mode 100644
index 00000000..f9a9e13f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_hostname.yaml
@@ -0,0 +1,32 @@
+---
+- ansible.builtin.debug: msg="START cli/set_hostname.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ lines: hostname switch
+ match: none
+
+- name: Configure hostname
+ register: result
+ cisco.iosxr.iosxr_system:
+ hostname: foo
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Verify hostname
+ register: result
+ cisco.iosxr.iosxr_system:
+ hostname: foo
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ lines: hostname {{ inventory_hostname }}
+ match: none
+
+- ansible.builtin.debug: msg="END cli/set_hostname.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_lookup_source.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_lookup_source.yaml
new file mode 100644
index 00000000..098741fa
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_lookup_source.yaml
@@ -0,0 +1,34 @@
+---
+- ansible.builtin.debug: msg="START cli/set_lookup_source.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ lines: no domain lookup source-interface Loopback10
+ match: none
+
+- name: Configure lookup_source
+ register: result
+ cisco.iosxr.iosxr_system:
+ lookup_source: Loopback10
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'domain lookup source-interface Loopback10' in result.commands"
+
+- name: Verify lookup_source
+ register: result
+ cisco.iosxr.iosxr_system:
+ lookup_source: Loopback10
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no domain lookup source-interface Loopback10
+ match: none
+
+- ansible.builtin.debug: msg="END cli/set_lookup_source.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_name_servers.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_name_servers.yaml
new file mode 100644
index 00000000..cc2df411
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/cli/set_name_servers.yaml
@@ -0,0 +1,59 @@
+---
+- ansible.builtin.debug: msg="START cli/set_name_servers.yaml on connection={{ ansible_connection }}"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no ip name-server 192.0.2.1
+ - no ip name-server 192.0.2.2
+ - no ip name-server 192.0.2.3
+ match: none
+
+- name: Configure name_servers
+ register: result
+ cisco.iosxr.iosxr_system:
+ name_servers:
+ - 192.0.2.1
+ - 192.0.2.2
+ - 192.0.2.3
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'domain name-server 192.0.2.1' in result.commands"
+ - "'domain name-server 192.0.2.2' in result.commands"
+ - "'domain name-server 192.0.2.3' in result.commands"
+
+- name: Verify name_servers
+ register: result
+ cisco.iosxr.iosxr_system:
+ name_servers:
+ - 192.0.2.1
+ - 192.0.2.2
+ - 192.0.2.3
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Remove one
+ register: result
+ cisco.iosxr.iosxr_system:
+ name_servers:
+ - 192.0.2.1
+ - 192.0.2.2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - result.commands|length == 1
+ - "'no domain name-server 192.0.2.3' in result.commands"
+
+- name: Setup
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no ip name-server 192.0.2.1
+ - no ip name-server 192.0.2.2
+ match: none
+
+- ansible.builtin.debug: msg="END cli/set_name_servers.yaml on connection={{ ansible_connection }}"
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_domain_list.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_domain_list.yaml
new file mode 100644
index 00000000..e83cda97
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_domain_list.yaml
@@ -0,0 +1,164 @@
+---
+- ansible.builtin.debug:
+ msg: START netconf/set_domain_search.yaml on connection={{ ansible_connection }}
+
+- name: Setup
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no domain list ansible.com
+ - no domain list redhat.com
+ - no domain list eng.ansible.com
+ - no domain vrf ansiblevrf list redhat.com
+ - no domain vrf ansiblevrf list ansible.com
+ match: none
+
+- name: Configure domain_search
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+ - redhat.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'ansible.com' in result.xml[0]"
+ - "'redhat.com' in result.xml[0]"
+
+- name: Configure domain_search with VRF
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: &id001
+ vrf: ansiblevrf
+ domain_search:
+ - redhat.com
+ - ansible.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'ansiblevrf' in result.xml[0]"
+ - "'ansible.com' in result.xml[0]"
+ - "'redhat.com' in result.xml[0]"
+
+- name: Verify domain_search with VRF
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: *id001
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Delete domain_search with VRF
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: &id002
+ vrf: ansiblevrf
+ domain_search:
+ - redhat.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'ansiblevrf' in result.xml[0]"
+ - "'ansible.com' in result.xml[0]"
+
+- name: Verify delete domain_search with VRF
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: *id002
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Remove one entry
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'redhat.com' in result.xml[0]"
+
+- name: Verify remove one entry
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Add one entry
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+ - redhat.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'redhat.com' in result.xml[0]"
+
+- name: Verify add one entry
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+ - redhat.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Add and remove one entry
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+ - eng.ansible.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'redhat.com' in result.xml[1]"
+ - "'eng.ansible.com' in result.xml[0]"
+ - result.xml|length == 2
+
+- name: Verify add and remove one entry
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system:
+ domain_search:
+ - ansible.com
+ - eng.ansible.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no domain list ansible.com
+ - no domain list redhat.com
+ - no domain list eng.ansible.com
+ - no domain vrf ansiblevrf list redhat.com
+ - no domain vrf ansiblevrf list ansible.com
+ - no domain vrf ansiblevrf list eng.ansible.com
+ match: none
+
+- ansible.builtin.debug:
+ msg: END netconf/set_domain_search.yaml on connection={{ ansible_connection }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_domain_name.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_domain_name.yaml
new file mode 100644
index 00000000..b2b9d7b4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_domain_name.yaml
@@ -0,0 +1,70 @@
+---
+- ansible.builtin.debug:
+ msg: START netconf/set_domain_name.yaml on connection={{ ansible_connection }}
+
+- name: Setup
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no domain name
+ - no domain vrf ansiblevrf name
+ match: none
+
+- name: Configure domain_name
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: &id001
+ domain_name: eng.ansible.com
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Verify domain_name
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: *id001
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Configure domain_name
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: &id002
+ domain_name: eng.ansible.com
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Verify domain_name
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: *id002
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Configure domain_name with VRF
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: &id003
+ domain_name: eng.ansible.com
+ vrf: ansiblevrf
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+- name: Verify domain_name with VRF
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: *id003
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- ansible.builtin.debug:
+ msg: END netconf/set_domain_name.yaml on connection={{ ansible_connection }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_hostname.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_hostname.yaml
new file mode 100644
index 00000000..fb803845
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_hostname.yaml
@@ -0,0 +1,39 @@
+---
+- ansible.builtin.debug:
+ msg: START netconf/set_hostname.yaml on connection={{ ansible_connection }}
+
+- block:
+ - name: Setup
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_config:
+ lines: hostname switch
+ match: none
+
+ - name: Configure hostname
+ register: result
+ cisco.iosxr.iosxr_system:
+ hostname: foo
+
+ - ansible.builtin.assert:
+ that:
+ - result.changed == true
+
+ - name: Verify hostname
+ register: result
+ cisco.iosxr.iosxr_system:
+ hostname: foo
+
+ - ansible.builtin.assert:
+ that:
+ - result.changed == false
+ always:
+ - name: Teardown
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_config:
+ lines: hostname {{ inventory_hostname }}
+ match: none
+
+- ansible.builtin.debug:
+ msg: END netconf/set_hostname.yaml on connection={{ ansible_connection }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_lookup_source.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_lookup_source.yaml
new file mode 100644
index 00000000..61277e0d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_lookup_source.yaml
@@ -0,0 +1,149 @@
+---
+- ansible.builtin.debug:
+ msg: START netconf/set_lookup_source.yaml on connection={{ ansible_connection }}
+
+- name: Setup
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no domain lookup source-interface Loopback10
+ - no domain vrf ansiblevrf lookup source-interface Loopback10
+ - no domain lookup disable
+ - no domain vrf ansiblevrf lookup disable
+ match: none
+
+- name: Reset connection
+ ansible.builtin.meta: reset_connection
+
+- name: Configure lookup_source
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: &id001
+ lookup_source: Loopback10
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'Loopback10' in result.xml[0]"
+
+- name: Verify lookup_source
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: *id001
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Disable lookup
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: &id002
+ lookup_enabled: false
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'lookup' in result.xml[0]"
+
+- name: Verify disable lookup
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: *id002
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Delete lookup_source
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: &id003
+ lookup_source: Loopback10
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'Loopback10' in result.xml[0]"
+
+- name: Verify lookup_source
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: *id003
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Configure lookup_source with VRF
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: &id004
+ lookup_source: Loopback10
+ vrf: ansiblevrf
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'Loopback10' in result.xml[0]"
+ - "'ansiblevrf' in result.xml[0]"
+
+- name: Verify lookup_source
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: *id004
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Disable lookup
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: &id005
+ lookup_enabled: false
+ vrf: ansiblevrf
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'lookup' in result.xml[0]"
+ - "'ansiblevrf' in result.xml[0]"
+
+- name: Verify disable lookup
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: *id005
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Delete lookup_source
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: &id006
+ lookup_source: Loopback10
+ vrf: ansiblevrf
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - "'Loopback10' in result.xml[0]"
+ - "'ansiblevrf' in result.xml[0]"
+
+- name: Verify lookup_source
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: *id006
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Teardown
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no domain lookup disable
+ - no domain vrf ansiblevrf lookup disable
+ match: none
+
+- ansible.builtin.debug:
+ msg: END netconf/set_lookup_source.yaml on connection={{ ansible_connection }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_name_servers.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_name_servers.yaml
new file mode 100644
index 00000000..dc888158
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_system/tests/netconf/set_name_servers.yaml
@@ -0,0 +1,127 @@
+---
+- ansible.builtin.debug:
+ msg: START netconf/set_name_servers.yaml on connection={{ ansible_connection }}
+
+- name: Setup
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no domain name-server 192.0.2.1
+ - no domain name-server 192.0.2.2
+ - no domain name-server 192.0.2.3
+ match: none
+
+- name: Setup
+ connection: ansible.netcommon.netconf
+ ignore_errors: true
+ register: result
+ cisco.iosxr.iosxr_system:
+ vrf: ansible
+ name_servers:
+ - 192.0.2.1
+ - 192.0.2.2
+ - 192.0.2.3
+ state: absent
+
+- name: Configure name_servers
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system:
+ name_servers:
+ - 192.0.2.1
+ - 192.0.2.2
+ - 192.0.2.3
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - result.xml|length == 1
+ - "'192.0.2.1' in result.xml[0]"
+ - "'192.0.2.2' in result.xml[0]"
+ - "'192.0.2.3' in result.xml[0]"
+
+- name: Verify name_servers
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system:
+ name_servers:
+ - 192.0.2.1
+ - 192.0.2.2
+ - 192.0.2.3
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Add name servers with VRF
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: &id001
+ vrf: ansible
+ name_servers:
+ - 192.0.2.1
+ - 192.0.2.2
+ - 192.0.2.3
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - result.xml|length == 1
+ - "'ansible' in result.xml[0]"
+ - "'192.0.2.1' in result.xml[0]"
+ - "'192.0.2.2' in result.xml[0]"
+ - "'192.0.2.3' in result.xml[0]"
+
+- name: Verify change to VRF
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system: *id001
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+
+- name: Remove one
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_system:
+ name_servers:
+ - 192.0.2.1
+ - 192.0.2.2
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - result.xml|length == 1
+ - "'192.0.2.3' in result.xml[0]"
+
+- name: Remove one with VRF
+ connection: ansible.netcommon.netconf
+ ignore_errors: true
+ register: result
+ cisco.iosxr.iosxr_system:
+ vrf: ansible
+ name_servers:
+ - 192.0.2.1
+ - 192.0.2.2
+
+- name: Teardown
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no domain name-server 192.0.2.1
+ - no domain name-server 192.0.2.2
+ match: none
+
+- name: Teardown
+ connection: ansible.netcommon.netconf
+ ignore_errors: true
+ register: result
+ cisco.iosxr.iosxr_system:
+ vrf: ansible
+ name_servers:
+ - 192.0.2.1
+ - 192.0.2.2
+ state: absent
+
+- ansible.builtin.debug:
+ msg: END netconf/set_name_servers.yaml on connection={{ ansible_connection }}
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/defaults/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/defaults/main.yaml
new file mode 100644
index 00000000..164afead
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/files/private b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/files/private
new file mode 100644
index 00000000..bf2425bb
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/files/private
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,A823A6B5ED873917
+
+mLZ1xM1+xwutkRy+K/c9QsstDPQ9F6UWtDpoYyIgs7n9VgMjhIMbWQC9CkTvnFJM
+ey+iwGdQZZOThwxalm+k3pMibwRjhnF+PNFhiVkzWH8/K8QvXRQiW/vYmE/QB9pY
+T0IWbMcC7/ktEfQn+6GLXoe/L7yH+aNv/2Flsa2jN2cfSXpzbneUA06/LVVOw6E+
+C74NKRWUmMPA39Zd4WOeBoWUdS5Kgwl57SOtrKs1LIGh33+TPu+Go8gJ7h/t/kaN
+kverVSz+0eeX+exKumejfo1UfosplRhcjRG8YgiQ8l7SN3NBF/gXiiSrH3fLwmRJ
+hbokJ8TmCozrYBs1MNe3LoU2iuIqVnJ5Sd6DJELs6vCuFz+v6J/s80NaaYMlBCbB
+1lahelYqoyLb4uiDd4zQSpaxzO+Cx/d50Wpee8mFxbAL/YxacOzD3b/VCBgB+AZN
+TTHr1ayd+ITd8gewXAyERKWyrDcC2beJI0fOil23PYowWvEncS6I1f4hKQY28sRf
+vHSbwQdltky/xiib2/feQTaMSQFvsY67uTHipMwl5wJNOKcbeqDVMWPYST3XUsBg
+LRlbT+VTUEehbOJAJ6Hh7Yv4nqu7fEh95HUQK7Ed56rMLKpmdorYO49JtewkEUsj
+LJn7tcxMUuOcWKHMPu6vB/63f6Ulthqp1SEG8aNBaZMuPyLWAPAJc2okOmkiSbvO
+0Hxe6BtAGn2fUo2jK6E3tD/dsIR2qqMlL09FkACGT8D5Lfh5d3z+lo9DxpXl281R
+ablehPyHgHcIC6cD2/7FwwjzUuyj/kYcETnMs51agcWFAXTom/ehqD+IQ8jZ73zT
+5O4FFgslnNmB/vddh9PeYpjDYdR4y5xMrlMxJ+qcZuQOq7dfaiodq8oj+XPmwgxA
+audX/sHMutOpmOagrsQfaQXaPqRXdQTnuwHacQfwq+tBBhrft5gwt1HE7Ir2ulwD
+Q19kefchkJu/0c1cAGg1VHtQic0a6tX6PrwqZOMDfpSywcImMCF4KHgD2EC5/8h6
+tq0PqPLNcwiM2NhpypCuYmkYZ0gnJ/xAwtM85Ck9nmPFptLSd0b7YB7dtGsFYY5A
+rhIcq5lZhy06/RRAPluIkniscA50iEO/EXKwzYzovBJh6jQz7oYsbEUW5kwg0gm/
+YPSa6lqv2kTpXS+UiGyeNWdUkr5DpdwKe4lrAsN94HE9/SoLgFvz0X5/WyTssSzo
+IO3WfLfBc7SOkZK1ibcleIqilzd+LSoIqqGrft2yonXgJD3p9xO+Hlldczx2kHmu
+z4lZBq53AkVAQ4os5L7ZRnmxoqKn2XAQRwVH3M9ZFYFEqEyDmZhlFdJSGEnKws81
+Ej48t6KWwqml02cx675bSYI22tL3+RL7AGmlC0/Xh8wIVesgulsYmnhW4BtpBYf2
+fwv5esJJMjkh2LvLNG3edYChugudeZXtcBJdNr0GYRbBAhvO25bRcr6z8nYDusKX
+e/+30vATOcBO/zaOYIwDGT5ZwMQAV1aQl8HyeyYESNjb0fBXQ3OYObOrTTs8MLyC
+I4b6wr1vlbN+lMOm+RIXCDgmC3COdlgCHyo3qiIu2YNYQVoNF4NN4A==
+-----END RSA PRIVATE KEY-----
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/files/public.pub b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/files/public.pub
new file mode 100644
index 00000000..db1847f4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/files/public.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAkvLTTJdwZ0lg1cUCn13Hi3+ho2+G6/96XuAP7jA7Ghz9NPbC/eqXnjvb27BA8CxtFXYuXR5eZWSq2UN5zFcfrFb57XFxdAg2q21hGEX+FGiTUuRZh8+ByVEh0LUetFTwsEZ1iGv6GZiLBt7IJvClXbyNTJEt3DZncHfGwudyGFviV4dGrzusDAGAcoHqvD/5uXYl4PjMH9oSfraO3sG4Q7soQwxNeiM8qOLf3c1SabHBAtSewwnA0E/jhzpOLD2QUncU5s+Oa9PvEXXhGv5eZo9lp71brsgyWj32m2UuXx/n+EZg78GVJT5mFO7LG239n3gTnwkMVdr6zVBFNX5Mvw== rsa-key-20171025
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/files/public2.pub b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/files/public2.pub
new file mode 100644
index 00000000..26af0db9
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/files/public2.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAhTxbibM8hKZn7xDURs15L3gkcsnpDoZ+tNm5zpP9dcboASnIyJzfC7J/RdRCQsO/pDmUY4y/tsTx18uenyfazxtNkyCHdANlp8XVF1fGNv5GM+QbsDqxe54sdG9csASX0/Ljvl538IbcLFVH0zxyKspbDOgkAkUSuKIAH5x+/GhkAoGQO2tOhYjqofNtUxLSvfRsf4Gm1M0WgdWmz3MW4NOdZhsL4S+STgRPU1jy1dKGj7BKY9cpnCWBFHa2wSaOXJEBZEKNaFVxlBBrFs5brjRQA0mVPmE+pz+/+IJeSNEEma9cXur0ONeb6OoXvkManxKfkaswT2ybOChAzJR8dQ== T-MOBILE
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/meta/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/meta/main.yaml
new file mode 100644
index 00000000..be631e5d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_iosxr_tests
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tasks/cli.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tasks/cli.yaml
new file mode 100644
index 00000000..ab72bff1
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tasks/cli.yaml
@@ -0,0 +1,34 @@
+---
+- name: Collect all common test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/common"
+ patterns: "{{ testcase }}.yaml"
+ use_regex: true
+ register: common_test_cases
+ delegate_to: localhost
+
+- 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 facts
+ ansible.builtin.set_fact:
+ test_cases:
+ files: "{{ common_test_cases.files + test_cases.files }}"
+
+- 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
+ tags:
+ - network_cli
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tasks/main.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tasks/main.yaml
new file mode 100644
index 00000000..419a6cde
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tasks/main.yaml
@@ -0,0 +1,6 @@
+---
+- name: Include the CLI tasks
+ ansible.builtin.include_tasks: cli.yaml
+
+- name: Include the netconf tasks
+ ansible.builtin.include_tasks: netconf.yaml
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tasks/netconf.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tasks/netconf.yaml
new file mode 100644
index 00000000..855bba5c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tasks/netconf.yaml
@@ -0,0 +1,32 @@
+---
+- name: Collect all common test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/common"
+ patterns: "{{ testcase }}.yaml"
+ register: common_test_cases
+ delegate_to: localhost
+
+- name: Collect all netconf test cases
+ ansible.builtin.find:
+ paths: "{{ role_path }}/tests/netconf"
+ patterns: "{{ testcase }}.yaml"
+ register: test_cases
+ delegate_to: localhost
+
+- name: Set facts
+ ansible.builtin.set_fact:
+ test_cases:
+ files: "{{ common_test_cases.files + test_cases.files }}"
+
+- name: Set test_items
+ ansible.builtin.set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
+
+- name: Run test case (connection=ansible.netcommon.netconf)
+ ansible.builtin.include_tasks: "{{ test_case_to_run }}"
+ vars:
+ ansible_connection: ansible.netcommon.netconf
+ with_items: "{{ test_items }}"
+ loop_control:
+ loop_var: test_case_to_run
+ tags:
+ - netconf
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tests/cli/basic.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tests/cli/basic.yaml
new file mode 100644
index 00000000..d8c12a8a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tests/cli/basic.yaml
@@ -0,0 +1,165 @@
+---
+- name: Remove users prior to tests
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no username ansibletest1
+ - no username ansibletest2
+ - no username ansibletest3
+
+- name: Create user (setup)
+ register: result
+ cisco.iosxr.iosxr_user:
+ name: ansibletest1
+ configured_password: test
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"username" in result.commands[0]'
+ - '"secret" in result.commands[1]'
+
+- name: Create user with update_password always (not idempotent)
+ register: result
+ cisco.iosxr.iosxr_user:
+ name: ansibletest1
+ configured_password: test
+ update_password: always
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"username" in result.commands[0]'
+ - '"secret" in result.commands[0]'
+
+- name: Create user again with update_password on_create (idempotent)
+ register: result
+ cisco.iosxr.iosxr_user:
+ name: ansibletest1
+ configured_password: test
+ update_password: on_create
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands | length == 0
+
+- name: Modify user group
+ register: result
+ cisco.iosxr.iosxr_user:
+ name: ansibletest1
+ configured_password: test
+ update_password: on_create
+ group: sysadmin
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"username" in result.commands[0]'
+ - '"group" in result.commands[0]'
+
+- name: Modify user group again (idempotent)
+ register: result
+ cisco.iosxr.iosxr_user:
+ name: ansibletest1
+ configured_password: test
+ update_password: on_create
+ group: sysadmin
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands | length == 0
+
+- name: Collection of users (setup)
+ register: result
+ cisco.iosxr.iosxr_user:
+ aggregate:
+ - name: ansibletest2
+
+ - name: ansibletest3
+ configured_password: test
+ state: present
+ group: sysadmin
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"username" in result.commands[0]'
+ - '"secret" in result.commands[1]'
+ - '"group sysadmin" in result.commands[2]'
+ - '"username" in result.commands[3]'
+ - '"secret" in result.commands[4]'
+ - '"group sysadmin" in result.commands[5]'
+
+- name: Add collection of users again with update_password always (not idempotent)
+ register: result
+ cisco.iosxr.iosxr_user:
+ aggregate:
+ - name: ansibletest2
+
+ - name: ansibletest3
+ configured_password: test
+ state: present
+ group: sysadmin
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"username" in result.commands[0]'
+ - '"secret" in result.commands[0]'
+ - '"username" in result.commands[1]'
+ - '"secret" in result.commands[1]'
+
+- name: Add collection of users again with update_password on_create (idempotent)
+ register: result
+ cisco.iosxr.iosxr_user:
+ aggregate:
+ - name: ansibletest2
+
+ - name: ansibletest3
+ configured_password: test
+ update_password: on_create
+ state: present
+ group: sysadmin
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands | length == 0
+
+- name: Delete collection of users
+ register: result
+ cisco.iosxr.iosxr_user:
+ aggregate:
+ - name: ansibletest1
+
+ - name: ansibletest2
+
+ - name: ansibletest3
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - result.commands == ["no username ansibletest1", "no username ansibletest2", "no username ansibletest3"]
+
+- name: Delete collection of users again (idempotent)
+ register: result
+ cisco.iosxr.iosxr_user:
+ aggregate:
+ - name: ansibletest1
+
+ - name: ansibletest2
+
+ - name: ansibletest3
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.commands | length == 0
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tests/common/auth.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tests/common/auth.yaml
new file mode 100644
index 00000000..3c2e6e46
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tests/common/auth.yaml
@@ -0,0 +1,109 @@
+---
+- block:
+ - name: Create user with password
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_user:
+ name: auth_user
+ state: present
+ configured_password: pass123
+
+ - name: Test login
+ ansible.builtin.expect:
+ command: ssh auth_user@{{ ansible_ssh_host }} -p {{ ansible_ssh_port|default(22) }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no show version
+ responses:
+ (?i)password: pass123
+ connection: ansible.netcommon.network_cli
+
+ - name: Test login with invalid password (should fail)
+ ansible.builtin.expect:
+ command: ssh auth_user@{{ ansible_ssh_host }} -p {{ ansible_ssh_port|default(22) }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no show version
+ responses:
+ (?i)password: badpass
+ ignore_errors: true
+ connection: ansible.netcommon.network_cli
+ register: results
+
+ - name: Check that attempt failed
+ ansible.builtin.assert:
+ that:
+ - results.failed
+
+ - name: Create user with private key (contents input)
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_user:
+ name: auth_user
+ state: present
+ public_key_contents: '{{ lookup(''file'', "{{ role_path }}/files/public.pub") }}'
+
+ - name: Test login with private key
+ ansible.builtin.expect:
+ command:
+ ssh auth_user@{{ ansible_ssh_host }} -p {{ ansible_ssh_port|default(22) }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i {{ role_path
+ }}/files/private show version
+ responses:
+ (?i)password: pass123
+ connection: ansible.netcommon.network_cli
+
+ - name: Remove user and key
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_user:
+ name: auth_user
+ state: absent
+
+ - name: Test login with private key (should fail, no user)
+ ansible.builtin.expect:
+ command:
+ ssh auth_user@{{ ansible_ssh_host }} -p {{ ansible_ssh_port|default(22) }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i {{ role_path
+ }}/files/private show version
+ responses:
+ (?i)password: pass123
+ ignore_errors: true
+ connection: ansible.netcommon.network_cli
+ register: results
+
+ - name: Create user with private key (path input)
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_user:
+ name: auth_user
+ state: present
+ public_key: "{{ role_path }}/files/public.pub"
+
+ - name: Test login with private key
+ ansible.builtin.expect:
+ command:
+ ssh auth_user@{{ ansible_ssh_host }} -p {{ ansible_ssh_port|default(22) }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i {{ role_path
+ }}/files/private show version
+ responses:
+ (?i)password: pass123
+ ignore_errors: true
+ connection: ansible.netcommon.network_cli
+
+ - name: Change private key for user
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_user:
+ name: auth_user
+ state: present
+ public_key_contents: '{{ lookup(''file'', "{{ role_path }}/files/public2.pub") }}'
+
+ - name: Test login with invalid private key (should fail)
+ ansible.builtin.expect:
+ command:
+ ssh auth_user@{{ ansible_ssh_host }} -p {{ ansible_ssh_port|default(22) }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i {{ role_path
+ }}/files/private show version
+ responses:
+ (?i)password: pass123
+ ignore_errors: true
+ connection: ansible.netcommon.network_cli
+ register: results
+
+ - name: Check that attempt failed
+ ansible.builtin.assert:
+ that:
+ - results.failed
+ always:
+ - name: Delete user
+ connection: ansible.netcommon.network_cli
+ register: result
+ cisco.iosxr.iosxr_user:
+ name: auth_user
+ state: absent
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tests/netconf/_basic.yaml b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tests/netconf/_basic.yaml
new file mode 100644
index 00000000..6107ff02
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/iosxr_user/tests/netconf/_basic.yaml
@@ -0,0 +1,177 @@
+---
+- name: Remove users prior to tests
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_config:
+ lines:
+ - no username ansible1
+ - no username ansible2
+ - no username ansible3
+
+- name: Create user (setup)
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_user:
+ name: ansible1
+ configured_password: password
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"ansible1" in result.xml[0]'
+ - '"secret" in result.xml[0]'
+
+- name: Create user with update_password always (not idempotent)
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_user:
+ name: ansible1
+ configured_password: password
+ update_password: always
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"ansible1" in result.xml[0]'
+ - '"secret" in result.xml[0]'
+
+- name: Create user again with update_password on_create (idempotent)
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_user:
+ name: ansible1
+ configured_password: password
+ update_password: on_create
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.xml | length == 0
+
+- name: Modify user group
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_user:
+ name: ansible1
+ configured_password: password
+ update_password: on_create
+ group: sysadmin
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"ansible1" in result.xml[0]'
+ - '"sysadmin" in result.xml[0]'
+
+- name: Modify user group again (idempotent)
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_user:
+ name: ansible1
+ configured_password: password
+ update_password: on_create
+ group: sysadmin
+ state: present
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.xml | length == 0
+
+- name: Collection of users (setup)
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_user:
+ aggregate:
+ - name: ansible2
+
+ - name: ansible3
+ configured_password: password
+ state: present
+ group: sysadmin
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"ansible2" in result.xml[0]'
+ - '"secret" in result.xml[0]'
+ - '"sysadmin" in result.xml[1]'
+ - '"ansible2" in result.xml[0]'
+ - '"secret" in result.xml[0]'
+ - '"sysadmin" in result.xml[1]'
+
+- name: Add collection of users again with update_password always (not idempotent)
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_user:
+ aggregate:
+ - name: ansible2
+
+ - name: ansible3
+ configured_password: password
+ state: present
+ group: sysadmin
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"ansible2" in result.xml[0]'
+ - '"ansible3" in result.xml[0]'
+ - '"secret" in result.xml[0]'
+
+- name: Add collection of users again with update_password on_create (idempotent)
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_user:
+ aggregate:
+ - name: ansible2
+
+ - name: ansible3
+ configured_password: password
+ update_password: on_create
+ state: present
+ group: sysadmin
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.xml | length == 0
+
+- name: Delete collection of users
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_user:
+ aggregate:
+ - name: ansible1
+
+ - name: ansible2
+
+ - name: ansible3
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - '"ansible1" in result.xml[0]'
+ - '"ansible2" in result.xml[0]'
+ - '"ansible3" in result.xml[0]'
+
+- name: Delete collection of users again (idempotent)
+ connection: ansible.netcommon.netconf
+ register: result
+ cisco.iosxr.iosxr_user:
+ aggregate:
+ - name: ansible1
+
+ - name: ansible2
+
+ - name: ansible3
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.xml | length == 0
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/prepare_iosxr_tests/tasks/main.yml b/ansible_collections/cisco/iosxr/tests/integration/targets/prepare_iosxr_tests/tasks/main.yml
new file mode 100644
index 00000000..d93230f9
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/prepare_iosxr_tests/tasks/main.yml
@@ -0,0 +1,17 @@
+---
+- name: Ensure we have loopback 888 for testing
+ connection: ansible.netcommon.network_cli
+ cisco.iosxr.iosxr_config:
+ src: config.j2
+
+- name: Enable netconf service
+ connection: ansible.netcommon.network_cli
+ tags: netconf
+ cisco.iosxr.iosxr_netconf:
+ netconf_port: 830
+ netconf_vrf: default
+ state: present
+
+- name: Set facts
+ ansible.builtin.set_fact:
+ shorter_hostname: '{{ inventory_hostname_short | truncate(10, True, "") }}'
diff --git a/ansible_collections/cisco/iosxr/tests/integration/targets/prepare_iosxr_tests/templates/config.j2 b/ansible_collections/cisco/iosxr/tests/integration/targets/prepare_iosxr_tests/templates/config.j2
new file mode 100644
index 00000000..cc89171c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/integration/targets/prepare_iosxr_tests/templates/config.j2
@@ -0,0 +1,3 @@
+interface Loopback888
+ description test for ansible
+ shutdown
diff --git a/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.10.txt b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.10.txt
new file mode 100644
index 00000000..b61dcef1
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.10.txt
@@ -0,0 +1,30 @@
+plugins/action/iosxr.py action-plugin-docs # base class for deprecated network platform modules using `connection: local
+plugins/modules/iosxr_bgp.py validate-modules:deprecation-mismatch
+plugins/modules/iosxr_bgp.py validate-modules:invalid-documentation
+plugins/module_utils/network/iosxr/config/acl_interfaces/acl_interfaces.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/ospf_interfaces/ospf_interfaces.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv2/ospfv2.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_address_family/bgp_address_family.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/prefix_lists/prefix_lists.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/logging_global/logging_global.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/acl_interfaces/acl_interfaces.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/ospf_interfaces/ospf_interfaces.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv2/ospfv2.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_address_family/bgp_address_family.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/prefix_lists/prefix_lists.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/logging_global/logging_global.py import-2.6!skip
+plugins/modules/iosxr_acl_interfaces.py import-2.6!skip
+plugins/modules/iosxr_ospf_interfaces.py import-2.6!skip
+plugins/modules/iosxr_ospfv2.py import-2.6!skip
+plugins/modules/iosxr_ospfv3.py import-2.6!skip
+plugins/modules/iosxr_bgp_neighbor_address_family.py import-2.6!skip
+plugins/modules/iosxr_bgp_address_family.py import-2.6!skip
+plugins/modules/iosxr_bgp_global.py import-2.6!skip
+plugins/modules/iosxr_prefix_lists.py import-2.6!skip
+plugins/modules/iosxr_logging_global.py import-2.6!skip
diff --git a/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.11.txt b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.11.txt
new file mode 100644
index 00000000..b83ac9dc
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.11.txt
@@ -0,0 +1,36 @@
+plugins/action/iosxr.py action-plugin-docs # base class for deprecated network platform modules using `connection: local
+plugins/modules/iosxr_bgp.py validate-modules:deprecation-mismatch
+plugins/modules/iosxr_bgp.py validate-modules:invalid-documentation
+plugins/module_utils/network/iosxr/config/acl_interfaces/acl_interfaces.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/ospf_interfaces/ospf_interfaces.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv2/ospfv2.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_address_family/bgp_address_family.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/prefix_lists/prefix_lists.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/logging_global/logging_global.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/acl_interfaces/acl_interfaces.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/ospf_interfaces/ospf_interfaces.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv2/ospfv2.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_address_family/bgp_address_family.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/prefix_lists/prefix_lists.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/logging_global/logging_global.py import-2.6!skip
+plugins/modules/iosxr_acl_interfaces.py import-2.6!skip
+plugins/modules/iosxr_ospf_interfaces.py import-2.6!skip
+plugins/modules/iosxr_ospfv2.py import-2.6!skip
+plugins/modules/iosxr_ospfv3.py import-2.6!skip
+plugins/modules/iosxr_bgp_neighbor_address_family.py import-2.6!skip
+plugins/modules/iosxr_bgp_address_family.py import-2.6!skip
+plugins/modules/iosxr_bgp_global.py import-2.6!skip
+plugins/modules/iosxr_prefix_lists.py import-2.6!skip
+plugins/modules/iosxr_logging_global.py import-2.6!skip
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.7!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.7!skip
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.8!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.8!skip
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.9!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.9!skip
diff --git a/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.12.txt b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.12.txt
new file mode 100644
index 00000000..393d598b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.12.txt
@@ -0,0 +1,39 @@
+plugins/action/iosxr.py action-plugin-docs # base class for deprecated network platform modules using `connection: local
+plugins/modules/iosxr_bgp.py validate-modules:deprecation-mismatch
+plugins/modules/iosxr_bgp.py validate-modules:invalid-documentation
+plugins/module_utils/network/iosxr/config/acl_interfaces/acl_interfaces.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/ospf_interfaces/ospf_interfaces.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv2/ospfv2.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_address_family/bgp_address_family.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/prefix_lists/prefix_lists.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/logging_global/logging_global.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/acl_interfaces/acl_interfaces.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/ospf_interfaces/ospf_interfaces.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv2/ospfv2.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_address_family/bgp_address_family.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/prefix_lists/prefix_lists.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/logging_global/logging_global.py import-2.6!skip
+plugins/modules/iosxr_acl_interfaces.py import-2.6!skip
+plugins/modules/iosxr_ospf_interfaces.py import-2.6!skip
+plugins/modules/iosxr_ospfv2.py import-2.6!skip
+plugins/modules/iosxr_ospfv3.py import-2.6!skip
+plugins/modules/iosxr_bgp_neighbor_address_family.py import-2.6!skip
+plugins/modules/iosxr_bgp_address_family.py import-2.6!skip
+plugins/modules/iosxr_bgp_global.py import-2.6!skip
+plugins/modules/iosxr_prefix_lists.py import-2.6!skip
+plugins/modules/iosxr_logging_global.py import-2.6!skip
+plugins/cliconf/iosxr.py pylint:arguments-renamed
+plugins/netconf/iosxr.py pylint:arguments-renamed
+tests/unit/mock/loader.py pylint:arguments-renamed
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.8!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.8!skip
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.9!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.9!skip
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.10!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.10!skip
diff --git a/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.13.txt b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.13.txt
new file mode 100644
index 00000000..b00006c2
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.13.txt
@@ -0,0 +1,12 @@
+plugins/action/iosxr.py action-plugin-docs # base class for deprecated network platform modules using `connection: local
+plugins/modules/iosxr_bgp.py validate-modules:deprecation-mismatch
+plugins/modules/iosxr_bgp.py validate-modules:invalid-documentation
+plugins/cliconf/iosxr.py pylint:arguments-renamed
+plugins/netconf/iosxr.py pylint:arguments-renamed
+tests/unit/mock/loader.py pylint:arguments-renamed
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.8!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.8!skip
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.9!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.9!skip
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.10!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.10!skip
diff --git a/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.14.txt b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.14.txt
new file mode 100644
index 00000000..ad1f84d8
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.14.txt
@@ -0,0 +1,12 @@
+plugins/action/iosxr.py action-plugin-docs # base class for deprecated network platform modules using `connection: local
+plugins/modules/iosxr_bgp.py validate-modules:deprecation-mismatch
+plugins/modules/iosxr_bgp.py validate-modules:invalid-documentation
+plugins/cliconf/iosxr.py pylint:arguments-renamed
+plugins/netconf/iosxr.py pylint:arguments-renamed
+tests/unit/mock/loader.py pylint:arguments-renamed
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.9!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.9!skip
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.10!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.10!skip
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.11!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.11!skip
diff --git a/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.15.txt b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.15.txt
new file mode 100644
index 00000000..ad1f84d8
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.15.txt
@@ -0,0 +1,12 @@
+plugins/action/iosxr.py action-plugin-docs # base class for deprecated network platform modules using `connection: local
+plugins/modules/iosxr_bgp.py validate-modules:deprecation-mismatch
+plugins/modules/iosxr_bgp.py validate-modules:invalid-documentation
+plugins/cliconf/iosxr.py pylint:arguments-renamed
+plugins/netconf/iosxr.py pylint:arguments-renamed
+tests/unit/mock/loader.py pylint:arguments-renamed
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.9!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.9!skip
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.10!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.10!skip
+plugins/sub_plugins/grpc/pb/ems_grpc_pb2.py import-3.11!skip
+plugins/sub_plugins/grpc/iosxr.py import-3.11!skip
diff --git a/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.9.txt b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.9.txt
new file mode 100644
index 00000000..eedc28b7
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/sanity/ignore-2.9.txt
@@ -0,0 +1,32 @@
+plugins/action/iosxr.py action-plugin-docs # base class for deprecated network platform modules using `connection: local
+plugins/modules/iosxr_logging.py validate-modules:deprecation-mismatch # 2.9 expects METADATA
+plugins/modules/iosxr_logging.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict
+plugins/modules/iosxr_bgp.py validate-modules:deprecation-mismatch
+plugins/modules/iosxr_bgp.py validate-modules:invalid-documentation
+plugins/module_utils/network/iosxr/config/acl_interfaces/acl_interfaces.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/ospf_interfaces/ospf_interfaces.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv2/ospfv2.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_address_family/bgp_address_family.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/prefix_lists/prefix_lists.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/logging_global/logging_global.py compile-2.6!skip
+plugins/module_utils/network/iosxr/config/acl_interfaces/acl_interfaces.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/ospf_interfaces/ospf_interfaces.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv2/ospfv2.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_address_family/bgp_address_family.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/prefix_lists/prefix_lists.py import-2.6!skip
+plugins/module_utils/network/iosxr/config/logging_global/logging_global.py import-2.6!skip
+plugins/modules/iosxr_acl_interfaces.py import-2.6!skip
+plugins/modules/iosxr_ospf_interfaces.py import-2.6!skip
+plugins/modules/iosxr_ospfv2.py import-2.6!skip
+plugins/modules/iosxr_ospfv3.py import-2.6!skip
+plugins/modules/iosxr_bgp_neighbor_address_family.py import-2.6!skip
+plugins/modules/iosxr_bgp_address_family.py import-2.6!skip
+plugins/modules/iosxr_bgp_global.py import-2.6!skip
+plugins/modules/iosxr_prefix_lists.py import-2.6!skip
+plugins/modules/iosxr_logging_global.py import-2.6!skip
diff --git a/ansible_collections/cisco/iosxr/tests/unit/__init__.py b/ansible_collections/cisco/iosxr/tests/unit/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/__init__.py
diff --git a/ansible_collections/cisco/iosxr/tests/unit/compat/__init__.py b/ansible_collections/cisco/iosxr/tests/unit/compat/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/compat/__init__.py
diff --git a/ansible_collections/cisco/iosxr/tests/unit/compat/builtins.py b/ansible_collections/cisco/iosxr/tests/unit/compat/builtins.py
new file mode 100644
index 00000000..e898a081
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/compat/builtins.py
@@ -0,0 +1,35 @@
+# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
+#
+# 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+#
+# Compat for python2.7
+#
+
+# One unittest needs to import builtins via __import__() so we need to have
+# the string that represents it
+try:
+ import __builtin__
+except ImportError:
+ BUILTINS = "builtins"
+else:
+ BUILTINS = "__builtin__"
diff --git a/ansible_collections/cisco/iosxr/tests/unit/compat/mock.py b/ansible_collections/cisco/iosxr/tests/unit/compat/mock.py
new file mode 100644
index 00000000..e4ce72b3
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/compat/mock.py
@@ -0,0 +1,129 @@
+# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
+#
+# 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+"""
+Compat module for Python3.x's unittest.mock module
+"""
+import sys
+
+import _io
+
+
+# Python 2.7
+
+# Note: Could use the pypi mock library on python3.x as well as python2.x. It
+# is the same as the python3 stdlib mock library
+
+try:
+ # Allow wildcard import because we really do want to import all of mock's
+ # symbols into this compat shim
+ # pylint: disable=wildcard-import,unused-wildcard-import
+ from unittest.mock import *
+except ImportError:
+ # Python 2
+ # pylint: disable=wildcard-import,unused-wildcard-import
+ try:
+ from mock import *
+ except ImportError:
+ print("You need the mock library installed on python2.x to run tests")
+
+
+# Prior to 3.4.4, mock_open cannot handle binary read_data
+if sys.version_info >= (3,) and sys.version_info < (3, 4, 4):
+ file_spec = None
+
+ def _iterate_read_data(read_data):
+ # Helper for mock_open:
+ # Retrieve lines from read_data via a generator so that separate calls to
+ # readline, read, and readlines are properly interleaved
+ sep = b"\n" if isinstance(read_data, bytes) else "\n"
+ data_as_list = [l + sep for l in read_data.split(sep)]
+
+ if data_as_list[-1] == sep:
+ # If the last line ended in a newline, the list comprehension will have an
+ # extra entry that's just a newline. Remove this.
+ data_as_list = data_as_list[:-1]
+ else:
+ # If there wasn't an extra newline by itself, then the file being
+ # emulated doesn't have a newline to end the last line remove the
+ # newline that our naive format() added
+ data_as_list[-1] = data_as_list[-1][:-1]
+
+ for line in data_as_list:
+ yield line
+
+ def mock_open(mock=None, read_data=""):
+ """
+ A helper function to create a mock to replace the use of `open`. It works
+ for `open` called directly or used as a context manager.
+
+ The `mock` argument is the mock object to configure. If `None` (the
+ default) then a `MagicMock` will be created for you, with the API limited
+ to methods or attributes available on standard file handles.
+
+ `read_data` is a string for the `read` methoddline`, and `readlines` of the
+ file handle to return. This is an empty string by default.
+ """
+
+ def _readlines_side_effect(*args, **kwargs):
+ if handle.readlines.return_value is not None:
+ return handle.readlines.return_value
+ return list(_data)
+
+ def _read_side_effect(*args, **kwargs):
+ if handle.read.return_value is not None:
+ return handle.read.return_value
+ return type(read_data)().join(_data)
+
+ def _readline_side_effect():
+ if handle.readline.return_value is not None:
+ while True:
+ yield handle.readline.return_value
+ for line in _data:
+ yield line
+
+ global file_spec
+ if file_spec is None:
+ file_spec = list(
+ set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO))),
+ )
+
+ if mock is None:
+ mock = MagicMock(name="open", spec=open)
+
+ handle = MagicMock(spec=file_spec)
+ handle.__enter__.return_value = handle
+
+ _data = _iterate_read_data(read_data)
+
+ handle.write.return_value = None
+ handle.read.return_value = None
+ handle.readline.return_value = None
+ handle.readlines.return_value = None
+
+ handle.read.side_effect = _read_side_effect
+ handle.readline.side_effect = _readline_side_effect()
+ handle.readlines.side_effect = _readlines_side_effect
+
+ mock.return_value = handle
+ return mock
diff --git a/ansible_collections/cisco/iosxr/tests/unit/compat/unittest.py b/ansible_collections/cisco/iosxr/tests/unit/compat/unittest.py
new file mode 100644
index 00000000..df4266ec
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/compat/unittest.py
@@ -0,0 +1,41 @@
+# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
+#
+# 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+"""
+Compat module for Python2.7's unittest module
+"""
+
+import sys
+
+
+# Allow wildcard import because we really do want to import all of
+# unittests's symbols into this compat shim
+# pylint: disable=wildcard-import,unused-wildcard-import
+if sys.version_info < (2, 7):
+ try:
+ # Need unittest2 on python2.6
+ from unittest2 import *
+ except ImportError:
+ print("You need unittest2 installed on python2.6.x to run tests")
+else:
+ from unittest import *
diff --git a/ansible_collections/cisco/iosxr/tests/unit/mock/__init__.py b/ansible_collections/cisco/iosxr/tests/unit/mock/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/mock/__init__.py
diff --git a/ansible_collections/cisco/iosxr/tests/unit/mock/loader.py b/ansible_collections/cisco/iosxr/tests/unit/mock/loader.py
new file mode 100644
index 00000000..2b5eb36a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/mock/loader.py
@@ -0,0 +1,117 @@
+# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
+#
+# 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+import os
+
+from ansible.errors import AnsibleParserError
+from ansible.module_utils._text import to_bytes, to_text
+from ansible.parsing.dataloader import DataLoader
+
+
+class DictDataLoader(DataLoader):
+ def __init__(self, file_mapping=None):
+ file_mapping = {} if file_mapping is None else file_mapping
+ assert type(file_mapping) == dict
+
+ super(DictDataLoader, self).__init__()
+
+ self._file_mapping = file_mapping
+ self._build_known_directories()
+ self._vault_secrets = None
+
+ def load_from_file(self, path, cache=True, unsafe=False):
+ path = to_text(path)
+ if path in self._file_mapping:
+ return self.load(self._file_mapping[path], path)
+ return None
+
+ # TODO: the real _get_file_contents returns a bytestring, so we actually convert the
+ # unicode/text it's created with to utf-8
+ def _get_file_contents(self, path):
+ path = to_text(path)
+ if path in self._file_mapping:
+ return (to_bytes(self._file_mapping[path]), False)
+ else:
+ raise AnsibleParserError("file not found: %s" % path)
+
+ def path_exists(self, path):
+ path = to_text(path)
+ return path in self._file_mapping or path in self._known_directories
+
+ def is_file(self, path):
+ path = to_text(path)
+ return path in self._file_mapping
+
+ def is_directory(self, path):
+ path = to_text(path)
+ return path in self._known_directories
+
+ def list_directory(self, path):
+ ret = []
+ path = to_text(path)
+ for x in list(self._file_mapping.keys()) + self._known_directories:
+ if x.startswith(path):
+ if os.path.dirname(x) == path:
+ ret.append(os.path.basename(x))
+ return ret
+
+ def is_executable(self, path):
+ # FIXME: figure out a way to make paths return true for this
+ return False
+
+ def _add_known_directory(self, directory):
+ if directory not in self._known_directories:
+ self._known_directories.append(directory)
+
+ def _build_known_directories(self):
+ self._known_directories = []
+ for path in self._file_mapping:
+ dirname = os.path.dirname(path)
+ while dirname not in ("/", ""):
+ self._add_known_directory(dirname)
+ dirname = os.path.dirname(dirname)
+
+ def push(self, path, content):
+ rebuild_dirs = False
+ if path not in self._file_mapping:
+ rebuild_dirs = True
+
+ self._file_mapping[path] = content
+
+ if rebuild_dirs:
+ self._build_known_directories()
+
+ def pop(self, path):
+ if path in self._file_mapping:
+ del self._file_mapping[path]
+ self._build_known_directories()
+
+ def clear(self):
+ self._file_mapping = dict()
+ self._known_directories = []
+
+ def get_basedir(self):
+ return os.getcwd()
+
+ def set_vault_secrets(self, vault_secrets):
+ self._vault_secrets = vault_secrets
diff --git a/ansible_collections/cisco/iosxr/tests/unit/mock/path.py b/ansible_collections/cisco/iosxr/tests/unit/mock/path.py
new file mode 100644
index 00000000..0c87896d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/mock/path.py
@@ -0,0 +1,13 @@
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+from ansible.utils.path import unfrackpath
+
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import MagicMock
+
+
+mock_unfrackpath_noop = MagicMock(
+ spec_set=unfrackpath,
+ side_effect=lambda x, *args, **kwargs: x,
+)
diff --git a/ansible_collections/cisco/iosxr/tests/unit/mock/procenv.py b/ansible_collections/cisco/iosxr/tests/unit/mock/procenv.py
new file mode 100644
index 00000000..3a4231bd
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/mock/procenv.py
@@ -0,0 +1,97 @@
+# (c) 2016, Matt Davis <mdavis@ansible.com>
+# (c) 2016, Toshio Kuratomi <tkuratomi@ansible.com>
+#
+# 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+import json
+import sys
+
+from contextlib import contextmanager
+from io import BytesIO, StringIO
+
+from ansible.module_utils._text import to_bytes
+from ansible.module_utils.six import PY3
+
+from ansible_collections.cisco.iosxr.tests.unit.compat import unittest
+
+
+@contextmanager
+def swap_stdin_and_argv(stdin_data="", argv_data=tuple()):
+ """
+ context manager that temporarily masks the test runner's values for stdin and argv
+ """
+ real_stdin = sys.stdin
+ real_argv = sys.argv
+
+ if PY3:
+ fake_stream = StringIO(stdin_data)
+ fake_stream.buffer = BytesIO(to_bytes(stdin_data))
+ else:
+ fake_stream = BytesIO(to_bytes(stdin_data))
+
+ try:
+ sys.stdin = fake_stream
+ sys.argv = argv_data
+
+ yield
+ finally:
+ sys.stdin = real_stdin
+ sys.argv = real_argv
+
+
+@contextmanager
+def swap_stdout():
+ """
+ context manager that temporarily replaces stdout for tests that need to verify output
+ """
+ old_stdout = sys.stdout
+
+ if PY3:
+ fake_stream = StringIO()
+ else:
+ fake_stream = BytesIO()
+
+ try:
+ sys.stdout = fake_stream
+
+ yield fake_stream
+ finally:
+ sys.stdout = old_stdout
+
+
+class ModuleTestCase(unittest.TestCase):
+ def setUp(self, module_args=None):
+ if module_args is None:
+ module_args = {
+ "_ansible_remote_tmp": "/tmp",
+ "_ansible_keep_remote_files": False,
+ }
+
+ args = json.dumps(dict(ANSIBLE_MODULE_ARGS=module_args))
+
+ # unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually
+ self.stdin_swap = swap_stdin_and_argv(stdin_data=args)
+ self.stdin_swap.__enter__()
+
+ def tearDown(self):
+ # unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually
+ self.stdin_swap.__exit__(None, None, None)
diff --git a/ansible_collections/cisco/iosxr/tests/unit/mock/vault_helper.py b/ansible_collections/cisco/iosxr/tests/unit/mock/vault_helper.py
new file mode 100644
index 00000000..82d01f5c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/mock/vault_helper.py
@@ -0,0 +1,44 @@
+# 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible.module_utils._text import to_bytes
+from ansible.parsing.vault import VaultSecret
+
+
+class TextVaultSecret(VaultSecret):
+ """A secret piece of text. ie, a password. Tracks text encoding.
+
+ The text encoding of the text may not be the default text encoding so
+ we keep track of the encoding so we encode it to the same bytes."""
+
+ def __init__(self, text, encoding=None, errors=None, _bytes=None):
+ super(TextVaultSecret, self).__init__()
+ self.text = text
+ self.encoding = encoding or "utf-8"
+ self._bytes = _bytes
+ self.errors = errors or "strict"
+
+ @property
+ def bytes(self):
+ """The text encoded with encoding, unless we specifically set _bytes."""
+ return self._bytes or to_bytes(
+ self.text,
+ encoding=self.encoding,
+ errors=self.errors,
+ )
diff --git a/ansible_collections/cisco/iosxr/tests/unit/mock/yaml_helper.py b/ansible_collections/cisco/iosxr/tests/unit/mock/yaml_helper.py
new file mode 100644
index 00000000..e46d3180
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/mock/yaml_helper.py
@@ -0,0 +1,177 @@
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+import io
+
+import yaml
+
+from ansible.module_utils.six import PY3
+from ansible.parsing.yaml.dumper import AnsibleDumper
+from ansible.parsing.yaml.loader import AnsibleLoader
+
+
+class YamlTestUtils(object):
+ """Mixin class to combine with a unittest.TestCase subclass."""
+
+ def _loader(self, stream):
+ """Vault related tests will want to override this.
+
+ Vault cases should setup a AnsibleLoader that has the vault password."""
+ return AnsibleLoader(stream)
+
+ def _dump_stream(self, obj, stream, dumper=None):
+ """Dump to a py2-unicode or py3-string stream."""
+ if PY3:
+ return yaml.dump(obj, stream, Dumper=dumper)
+ else:
+ return yaml.dump(obj, stream, Dumper=dumper, encoding=None)
+
+ def _dump_string(self, obj, dumper=None):
+ """Dump to a py2-unicode or py3-string"""
+ if PY3:
+ return yaml.dump(obj, Dumper=dumper)
+ else:
+ return yaml.dump(obj, Dumper=dumper, encoding=None)
+
+ def _dump_load_cycle(self, obj):
+ # Each pass though a dump or load revs the 'generation'
+ # obj to yaml string
+ string_from_object_dump = self._dump_string(obj, dumper=AnsibleDumper)
+
+ # wrap a stream/file like StringIO around that yaml
+ stream_from_object_dump = io.StringIO(string_from_object_dump)
+ loader = self._loader(stream_from_object_dump)
+ # load the yaml stream to create a new instance of the object (gen 2)
+ obj_2 = loader.get_data()
+
+ # dump the gen 2 objects directory to strings
+ string_from_object_dump_2 = self._dump_string(
+ obj_2,
+ dumper=AnsibleDumper,
+ )
+
+ # The gen 1 and gen 2 yaml strings
+ self.assertEqual(string_from_object_dump, string_from_object_dump_2)
+ # the gen 1 (orig) and gen 2 py object
+ self.assertEqual(obj, obj_2)
+
+ # again! gen 3... load strings into py objects
+ stream_3 = io.StringIO(string_from_object_dump_2)
+ loader_3 = self._loader(stream_3)
+ obj_3 = loader_3.get_data()
+
+ string_from_object_dump_3 = self._dump_string(
+ obj_3,
+ dumper=AnsibleDumper,
+ )
+
+ self.assertEqual(obj, obj_3)
+ # should be transitive, but...
+ self.assertEqual(obj_2, obj_3)
+ self.assertEqual(string_from_object_dump, string_from_object_dump_3)
+
+ def _old_dump_load_cycle(self, obj):
+ """Dump the passed in object to yaml, load it back up, dump again, compare."""
+ stream = io.StringIO()
+
+ yaml_string = self._dump_string(obj, dumper=AnsibleDumper)
+ self._dump_stream(obj, stream, dumper=AnsibleDumper)
+
+ yaml_string_from_stream = stream.getvalue()
+
+ # reset stream
+ stream.seek(0)
+
+ loader = self._loader(stream)
+ # loader = AnsibleLoader(stream, vault_password=self.vault_password)
+ obj_from_stream = loader.get_data()
+
+ stream_from_string = io.StringIO(yaml_string)
+ loader2 = self._loader(stream_from_string)
+ # loader2 = AnsibleLoader(stream_from_string, vault_password=self.vault_password)
+ obj_from_string = loader2.get_data()
+
+ stream_obj_from_stream = io.StringIO()
+ stream_obj_from_string = io.StringIO()
+
+ if PY3:
+ yaml.dump(
+ obj_from_stream,
+ stream_obj_from_stream,
+ Dumper=AnsibleDumper,
+ )
+ yaml.dump(
+ obj_from_stream,
+ stream_obj_from_string,
+ Dumper=AnsibleDumper,
+ )
+ else:
+ yaml.dump(
+ obj_from_stream,
+ stream_obj_from_stream,
+ Dumper=AnsibleDumper,
+ encoding=None,
+ )
+ yaml.dump(
+ obj_from_stream,
+ stream_obj_from_string,
+ Dumper=AnsibleDumper,
+ encoding=None,
+ )
+
+ yaml_string_stream_obj_from_stream = stream_obj_from_stream.getvalue()
+ yaml_string_stream_obj_from_string = stream_obj_from_string.getvalue()
+
+ stream_obj_from_stream.seek(0)
+ stream_obj_from_string.seek(0)
+
+ if PY3:
+ yaml_string_obj_from_stream = yaml.dump(
+ obj_from_stream,
+ Dumper=AnsibleDumper,
+ )
+ yaml_string_obj_from_string = yaml.dump(
+ obj_from_string,
+ Dumper=AnsibleDumper,
+ )
+ else:
+ yaml_string_obj_from_stream = yaml.dump(
+ obj_from_stream,
+ Dumper=AnsibleDumper,
+ encoding=None,
+ )
+ yaml_string_obj_from_string = yaml.dump(
+ obj_from_string,
+ Dumper=AnsibleDumper,
+ encoding=None,
+ )
+
+ assert yaml_string == yaml_string_obj_from_stream
+ assert yaml_string == yaml_string_obj_from_stream == yaml_string_obj_from_string
+ assert (
+ yaml_string
+ == yaml_string_obj_from_stream
+ == yaml_string_obj_from_string
+ == yaml_string_stream_obj_from_stream
+ == yaml_string_stream_obj_from_string
+ )
+ assert obj == obj_from_stream
+ assert obj == obj_from_string
+ assert obj == yaml_string_obj_from_stream
+ assert obj == yaml_string_obj_from_string
+ assert (
+ obj
+ == obj_from_stream
+ == obj_from_string
+ == yaml_string_obj_from_stream
+ == yaml_string_obj_from_string
+ )
+ return {
+ "obj": obj,
+ "yaml_string": yaml_string,
+ "yaml_string_from_stream": yaml_string_from_stream,
+ "obj_from_stream": obj_from_stream,
+ "obj_from_string": obj_from_string,
+ "yaml_string_obj_from_string": yaml_string_obj_from_string,
+ }
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/__init__.py b/ansible_collections/cisco/iosxr/tests/unit/modules/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/__init__.py
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/conftest.py b/ansible_collections/cisco/iosxr/tests/unit/modules/conftest.py
new file mode 100644
index 00000000..349e71ad
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/conftest.py
@@ -0,0 +1,34 @@
+# Copyright (c) 2017 Ansible Project
+# 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
+
+import json
+
+import pytest
+
+from ansible.module_utils._text import to_bytes
+from ansible.module_utils.common._collections_compat import MutableMapping
+from ansible.module_utils.six import string_types
+
+
+@pytest.fixture
+def patch_ansible_module(request, mocker):
+ if isinstance(request.param, string_types):
+ args = request.param
+ elif isinstance(request.param, MutableMapping):
+ if "ANSIBLE_MODULE_ARGS" not in request.param:
+ request.param = {"ANSIBLE_MODULE_ARGS": request.param}
+ if "_ansible_remote_tmp" not in request.param["ANSIBLE_MODULE_ARGS"]:
+ request.param["ANSIBLE_MODULE_ARGS"]["_ansible_remote_tmp"] = "/tmp"
+ if "_ansible_keep_remote_files" not in request.param["ANSIBLE_MODULE_ARGS"]:
+ request.param["ANSIBLE_MODULE_ARGS"]["_ansible_keep_remote_files"] = False
+ args = json.dumps(request.param)
+ else:
+ raise Exception(
+ "Malformed data to the patch_ansible_module pytest fixture",
+ )
+
+ mocker.patch("ansible.module_utils.basic._ANSIBLE_ARGS", to_bytes(args))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/__init__.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/__init__.py
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/__init__.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/__init__.py
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/__init__.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/__init__.py
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf/iosxr/show_running-config_hostname b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf/iosxr/show_running-config_hostname
new file mode 100644
index 00000000..ebc5bf85
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf/iosxr/show_running-config_hostname
@@ -0,0 +1 @@
+hostname iosxr01
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf/iosxr/show_version__utility_head_-n_20 b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf/iosxr/show_version__utility_head_-n_20
new file mode 100644
index 00000000..6922cbbf
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf/iosxr/show_version__utility_head_-n_20
@@ -0,0 +1,17 @@
+Cisco IOS XR Software, Version 6.0.0[Default]
+Copyright (c) 2015 by Cisco Systems, Inc.
+
+ROM: GRUB, Version 1.99(0), DEV RELEASE
+
+iosxr01 uptime is 11 weeks, 2 days, 5 hours, 48 minutes
+System image file is "bootflash:disk0/xrvr-os-mbi-6.0.0/mbixrvr-rp.vm"
+
+cisco IOS XRv Series (Pentium Celeron Stepping 3) processor with 3169911K bytes of memory.
+Pentium Celeron Stepping 3 processor at 3836MHz, Revision 2.174
+IOS XRv Chassis
+
+1 Management Ethernet
+6 GigabitEthernet
+97070k bytes of non-volatile configuration memory.
+866M bytes of hard disk.
+2321392k bytes of disk0: (Sector size 512 bytes).
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf_ncs540/iosxr/show_running-config_hostname b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf_ncs540/iosxr/show_running-config_hostname
new file mode 100644
index 00000000..ebc5bf85
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf_ncs540/iosxr/show_running-config_hostname
@@ -0,0 +1 @@
+hostname iosxr01
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf_ncs540/iosxr/show_version__utility_head_-n_20 b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf_ncs540/iosxr/show_version__utility_head_-n_20
new file mode 100644
index 00000000..5aa174c4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/cliconf_ncs540/iosxr/show_version__utility_head_-n_20
@@ -0,0 +1,15 @@
+Cisco IOS XR Software, Version 7.5.2 LNT
+Copyright (c) 2013-2022 by Cisco Systems, Inc.
+
+Build Information:
+ Built By : ingunawa
+ Built On : Tue Apr 26 23:47:22 UTC 2022
+ Build Host : iox-lnx-023
+ Workspace : /auto/srcarchive14/prod/7.5.2/ncs540l-aarch64/ws
+ Version : 7.5.2
+ Label : 7.5.2
+
+cisco NCS540L
+cisco N540X-6Z18G-SYS-A processor with 8GB of memory
+iosxr01 uptime is 5 days, 1 hour, 45 minutes
+Cisco NCS 540 Series Fixed Router 18x1G, 6x1/10G, AC
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/dir_7all b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/dir_7all
new file mode 100644
index 00000000..b992498c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/dir_7all
@@ -0,0 +1,6 @@
+Directory of disk0:
+file1
+file2
+
+Directory of flash0:
+file3
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_acl_interfaces_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_acl_interfaces_config.cfg
new file mode 100644
index 00000000..6a05274a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_acl_interfaces_config.cfg
@@ -0,0 +1,11 @@
+interface GigabitEthernet0/0/0/0
+ shutdown
+ ipv4 access-group acl_1 ingress
+ ipv4 access-group acl_2 egress
+ ipv6 access-group acl6_1 ingress
+ ipv6 access-group acl6_2 egress
+!
+interface GigabitEthernet0/0/0/1
+ shutdown
+ ipv4 access-group acl_1 egress
+!
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_acls_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_acls_config.cfg
new file mode 100644
index 00000000..f5d1708c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_acls_config.cfg
@@ -0,0 +1,8 @@
+ipv4 access-list acl_2
+ 10 deny ipv4 any any
+ 20 permit tcp host 192.168.1.100 any
+ipv4 access-list acl_1
+ 10 deny ipv4 10.233.0.0 0.0.255.255 net-group netgroup1
+ 20 deny ipv4 10.233.0.0 0.0.255.255 port-group portgroup1
+ipv6 access-list acl6_1
+ 10 deny icmpv6 any any
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_banner_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_banner_config.cfg
new file mode 100644
index 00000000..ed8e6d6d
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_banner_config.cfg
@@ -0,0 +1,2 @@
+banner motd this is my motd banner
+banner login this is my login banner
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_config_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_config_config.cfg
new file mode 100644
index 00000000..afad9d08
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_config_config.cfg
@@ -0,0 +1,12 @@
+!
+hostname router
+!
+interface GigabitEthernet0/0
+ ip address 1.2.3.4 255.255.255.0
+ description test string
+!
+interface GigabitEthernet0/1
+ ip address 6.7.8.9 255.255.255.0
+ description test string
+ shutdown
+!
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_config_src.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_config_src.cfg
new file mode 100644
index 00000000..b3d8961a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_config_src.cfg
@@ -0,0 +1,11 @@
+!
+hostname foo
+!
+interface GigabitEthernet0/0
+ no ip address
+!
+interface GigabitEthernet0/1
+ ip address 6.7.8.9 255.255.255.0
+ description test string
+ shutdown
+!
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_interface_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_interface_config.cfg
new file mode 100644
index 00000000..700dde0a
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_interface_config.cfg
@@ -0,0 +1,9 @@
+interface GigabitEthernet0/0/0/0
+ description Configured and Merged by Ansible-Network
+ mtu 110
+ duplex half
+interface GigabitEthernet0/0/0/1
+ description Configured and Merged by Ansible-Network
+ no shutdown
+ mtu 2800
+ speed 100
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_l2_interface_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_l2_interface_config.cfg
new file mode 100644
index 00000000..4192ee39
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_l2_interface_config.cfg
@@ -0,0 +1,9 @@
+interface GigabitEthernet0/0/0/1
+ l2transport
+ l2protocol cpsv tunnel
+ propagate remote-status
+ !
+!
+interface GigabitEthernet0/0/0/3.900
+ encapsulation dot1q 20 second-dot1q 40
+!
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_l3_interface_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_l3_interface_config.cfg
new file mode 100644
index 00000000..d870f4e8
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_l3_interface_config.cfg
@@ -0,0 +1,6 @@
+interface GigabitEthernet0/0/0/0
+ipv4 address 198.51.100.1 255.255.255.0
+ipv6 address 2001:db8::/32
+interface GigabitEthernet0/0/0/1
+ipv4 address 192.0.2.1 255.255.255.0
+ipv4 address 192.0.2.2 255.255.255.0 secondary
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lacp_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lacp_config.cfg
new file mode 100644
index 00000000..01776dbe
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lacp_config.cfg
@@ -0,0 +1,2 @@
+lacp system mac 00c1.4c00.bd15
+lacp system priority 12
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lacp_interfaces_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lacp_interfaces_config.cfg
new file mode 100644
index 00000000..b38bb39f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lacp_interfaces_config.cfg
@@ -0,0 +1,11 @@
+interface Bundle-Ether10
+ lacp churn logging actor
+ lacp switchover suppress-flaps 500
+ lacp collector-max-delay 100
+!
+interface Bundle-Ether11
+ lacp system mac 00c2.4c00.bd15
+!
+interface GigabitEthernet0/0/0/1
+ lacp period 200
+!
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lag_interface_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lag_interface_config.cfg
new file mode 100644
index 00000000..256d3f23
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lag_interface_config.cfg
@@ -0,0 +1,24 @@
+interface Bundle-Ether10
+ lacp mode active
+ bundle maximum-active links 10
+ bundle minimum-active links 2
+!
+interface Bundle-Ether11
+lacp mode active
+!
+interface GigabitEthernet0/0/0/0
+ description "GigabitEthernet - 0"
+ bundle id 10 mode inherit
+!
+interface GigabitEthernet0/0/0/1
+ description "GigabitEthernet - 2"
+ bundle id 10 mode passive
+!
+interface GigabitEthernet0/0/0/8
+ description "GigabitEthernet - 8"
+ bundle id 11 mode passive
+!
+interface GigabitEthernet0/0/0/9
+ description "GigabitEthernet - 9"
+ bundle id 11 mode passive
+!
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lldp_global_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lldp_global_config.cfg
new file mode 100644
index 00000000..4bd23847
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lldp_global_config.cfg
@@ -0,0 +1,10 @@
+lldp
+ timer 3000
+ reinit 2
+ subinterfaces enable
+ holdtime 100
+ tlv-select
+ management-address disable
+ system-description disable
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lldp_interfaces_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lldp_interfaces_config.cfg
new file mode 100644
index 00000000..b50b42e5
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_lldp_interfaces_config.cfg
@@ -0,0 +1,16 @@
+interface TenGigE0/0/0/0
+ ipv4 address 192.0.2.11 255.255.255.192
+!
+interface preconfigure GigabitEthernet0/0/0/0
+ lldp
+ transmit disable
+ destination mac-address
+ ieee-nearest-bridge
+ !
+ !
+!
+interface preconfigure GigabitEthernet0/0/0/1
+ lldp
+ receive disable
+ destination mac-address
+ ieee-nearest-non-tmpr-bridge
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_ospf_interfaces.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_ospf_interfaces.cfg
new file mode 100644
index 00000000..9ddb8d66
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_ospf_interfaces.cfg
@@ -0,0 +1,8 @@
+router ospf LAB3
+ area 0.0.0.3
+ interface GigabitEthernet0/0/0/0
+ cost 20
+ authentication message-digest keychain cisco
+ !
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_ospfv2.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_ospfv2.cfg
new file mode 100644
index 00000000..8645482e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_ospfv2.cfg
@@ -0,0 +1,8 @@
+Sun Jun 14 12:10:47.455 UTC
+router ospf 30
+ cost 2
+ default-metric 10
+ area 11
+ default-cost 5
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_ospfv3.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_ospfv3.cfg
new file mode 100644
index 00000000..b52c0ee0
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_ospfv3.cfg
@@ -0,0 +1,8 @@
+Sun Jun 14 12:10:47.455 UTC
+router ospfv3 30
+ cost 2
+ default-metric 10
+ area 11
+ default-cost 5
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_static_routes_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_static_routes_config.cfg
new file mode 100644
index 00000000..35948336
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_static_routes_config.cfg
@@ -0,0 +1,18 @@
+Fri Nov 29 21:10:41.896 UTC
+router static
+ address-family ipv4 unicast
+ 192.0.2.16/28 FastEthernet0/0/0/1 192.0.2.10 tag 10 description LAB metric 120
+ 192.0.2.16/28 FastEthernet0/0/0/5 track ip_sla_1
+ 192.0.2.32/28 192.0.2.11 100
+ !
+ address-family ipv6 unicast
+ 2001:db8:1000::/36 FastEthernet0/0/0/7 description DC
+ 2001:db8:1000::/36 FastEthernet0/0/0/8 2001:db8:2000:2::1
+ !
+ vrf DEV_SITE
+ address-family ipv4 unicast
+ 192.0.2.48/28 vrf test_1 192.0.2.12 description DEV
+ 192.0.2.80/28 vrf test_1 FastEthernet0/0/0/2 192.0.2.14 vrflabel 124 track ip_sla_2
+ !
+ !
+!
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_system_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_system_config.cfg
new file mode 100644
index 00000000..fc6fd2b7
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_system_config.cfg
@@ -0,0 +1,8 @@
+hostname iosxr01
+domain name eng.ansible.com
+domain lookup disable
+domain lookup source-interface MgmtEth0/0/CPU0/0
+domain list redhat.com
+domain list cisco.com
+domain name-server 8.8.8.8
+domain name-server 8.8.4.4
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_user_config.cfg b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_user_config.cfg
new file mode 100644
index 00000000..0f0ab168
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/iosxr_user_config.cfg
@@ -0,0 +1,8 @@
+username admin
+ secret 5 $1$mdQIUxjg$3t3lzBpfKfITKvFm1uEIY.
+ group sysadmin
+!
+username ansible
+ secret 5 $1$3yWSXiIi$VdzV59ChiurrNdGxlDeAW/
+ group sysadmin
+!
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_interfaces b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_interfaces
new file mode 100644
index 00000000..edb3c6a0
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_interfaces
@@ -0,0 +1,41 @@
+Loopback0 is up, line protocol is up
+ Interface state transitions: 1
+ Hardware is Loopback interface(s)
+ Description: Loopback
+ Internet address is 192.168.0.3/32
+ MTU 1500 bytes, BW 0 Kbit
+ reliability Unknown, txload Unknown, rxload Unknown
+ Encapsulation Loopback, loopback not set,
+ Last link flapped 12w1d
+ Last input Unknown, output Unknown
+ Last clearing of "show interface" counters Unknown
+ Input/output data rate is disabled.
+
+GigabitEthernet0/0/0/0 is up, line protocol is up
+ Interface state transitions: 1
+ Hardware is GigabitEthernet, address is fa16.3e6c.20bd (bia fa16.3e6c.20bd)
+ Description: to nxos01
+ Internet address is 10.0.0.5/30
+ MTU 1514 bytes, BW 1000000 Kbit (Max: 1000000 Kbit)
+ reliability 255/255, txload 0/255, rxload 0/255
+ Encapsulation ARPA,
+ Full-duplex, 1000Mb/s, unknown, link type is force-up
+ output flow control is off, input flow control is off
+ Carrier delay (up) is 10 msec
+ loopback not set,
+ Last link flapped 12w1d
+ ARP type ARPA, ARP timeout 04:00:00
+ Last input 00:00:44, output 00:12:45
+ Last clearing of "show interface" counters never
+ 5 minute input rate 0 bits/sec, 0 packets/sec
+ 5 minute output rate 0 bits/sec, 0 packets/sec
+ 150700 packets input, 36897055 bytes, 0 total input drops
+ 0 drops for unrecognized upper-level protocol
+ Received 1 broadcast packets, 150445 multicast packets
+ 0 runts, 0 giants, 0 throttles, 0 parity
+ 0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored, 0 abort
+ 11691 packets output, 2904632 bytes, 0 total output drops
+ Output 1 broadcast packets, 11436 multicast packets
+ 0 output errors, 0 underruns, 0 applique, 0 resets
+ 0 output buffer failures, 0 output buffers swapped out
+ 1 carrier transitions
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_ipv6_interface b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_ipv6_interface
new file mode 100644
index 00000000..971d1f65
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_ipv6_interface
@@ -0,0 +1,5 @@
+Loopback0 is Up, ipv6 protocol is Up, Vrfid is default (0x60000000)
+ IPv6 is disabled, link-local address unassigned
+ No global unicast address is configured
+GigabitEthernet0/0/0/0 is Up, ipv6 protocol is Up, Vrfid is default (0x60000000)
+ IPv6 is disabled, link-local address unassigned
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_lldp b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_lldp
new file mode 100644
index 00000000..60ab287f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_lldp
@@ -0,0 +1 @@
+% LLDP is not enabled
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_lldp_neighbors_detail b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_lldp_neighbors_detail
new file mode 100644
index 00000000..60ab287f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_lldp_neighbors_detail
@@ -0,0 +1 @@
+% LLDP is not enabled
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_memory_summary b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_memory_summary
new file mode 100644
index 00000000..b26abeae
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_memory_summary
@@ -0,0 +1,5 @@
+Physical Memory: 3095M total (1499M available)
+ Application Memory : 2893M (1499M available)
+ Image: 73M (bootram: 73M)
+ Reserved: 128M, IOMem: 0, flashfsys: 0
+ Total shared window: 23M
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_running-config b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_running-config
new file mode 100644
index 00000000..085baef4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_running-config
@@ -0,0 +1,43 @@
+hostname iosxr01
+service timestamps log datetime msec
+service timestamps debug datetime msec
+telnet vrf default ipv4 server max-servers 10
+telnet vrf Mgmt-intf ipv4 server max-servers 10
+domain name eng.ansible.com
+domain lookup disable
+vrf Mgmt-intf
+ address-family ipv4 unicast
+ !
+ address-family ipv6 unicast
+ !
+!
+line template vty
+ timestamp
+ exec-timeout 720 0
+!
+line console
+ exec-timeout 0 0
+!
+line default
+ exec-timeout 720 0
+!
+vty-pool default 0 50
+control-plane
+ management-plane
+ inband
+ interface all
+ allow all
+ !
+ !
+ !
+!
+interface Loopback0
+ description Loopback
+ ipv4 address 192.168.0.1 255.255.255.255
+!
+interface GigabitEthernet0/0/0/0
+ description to nxos01
+ cdp
+ ipv4 address 10.0.0.1 255.255.255.252
+!
+end
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_version b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_version
new file mode 100644
index 00000000..faecfffd
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_version
@@ -0,0 +1,84 @@
+Cisco IOS XR Software, Version 6.0.0[Default]
+Copyright (c) 2015 by Cisco Systems, Inc.
+
+ROM: GRUB, Version 1.99(0), DEV RELEASE
+
+iosxr01 uptime is 11 weeks, 2 days, 5 hours, 48 minutes
+System image file is "bootflash:disk0/xrvr-os-mbi-6.0.0/mbixrvr-rp.vm"
+
+cisco IOS XRv Series (Pentium Celeron Stepping 3) processor with 3169911K bytes of memory.
+Pentium Celeron Stepping 3 processor at 3836MHz, Revision 2.174
+IOS XRv Chassis
+
+1 Management Ethernet
+6 GigabitEthernet
+97070k bytes of non-volatile configuration memory.
+866M bytes of hard disk.
+2321392k bytes of disk0: (Sector size 512 bytes).
+
+Configuration register on node 0/0/CPU0 is 0x2102
+Boot device on node 0/0/CPU0 is disk0:
+Package active on node 0/0/CPU0:
+iosxr-infra, V 6.0.0[Default], Cisco Systems, at disk0:iosxr-infra-6.0.0
+ Built on Thu Dec 24 08:53:49 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+iosxr-fwding, V 6.0.0[Default], Cisco Systems, at disk0:iosxr-fwding-6.0.0
+ Built on Thu Dec 24 08:53:49 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+iosxr-routing, V 6.0.0[Default], Cisco Systems, at disk0:iosxr-routing-6.0.0
+ Built on Thu Dec 24 08:53:49 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+iosxr-ce, V 6.0.0[Default], Cisco Systems, at disk0:iosxr-ce-6.0.0
+ Built on Thu Dec 24 08:53:49 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+xrvr-os-mbi, V 6.0.0[Default], Cisco Systems, at disk0:xrvr-os-mbi-6.0.0
+ Built on Thu Dec 24 08:54:41 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+xrvr-base, V 6.0.0[Default], Cisco Systems, at disk0:xrvr-base-6.0.0
+ Built on Thu Dec 24 08:53:49 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+xrvr-fwding, V 6.0.0[Default], Cisco Systems, at disk0:xrvr-fwding-6.0.0
+ Built on Thu Dec 24 08:53:49 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+xrvr-mgbl-x, V 6.0.0[Default], Cisco Systems, at disk0:xrvr-mgbl-x-6.0.0
+ Built on Thu Dec 24 08:53:57 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+iosxr-mpls, V 6.0.0[Default], Cisco Systems, at disk0:iosxr-mpls-6.0.0
+ Built on Thu Dec 24 08:53:49 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+iosxr-mgbl, V 6.0.0[Default], Cisco Systems, at disk0:iosxr-mgbl-6.0.0
+ Built on Thu Dec 24 08:53:49 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+iosxr-mcast, V 6.0.0[Default], Cisco Systems, at disk0:iosxr-mcast-6.0.0
+ Built on Thu Dec 24 08:53:49 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+xrvr-mcast-supp, V 6.0.0[Default], Cisco Systems, at disk0:xrvr-mcast-supp-6.0.0
+ Built on Thu Dec 24 08:53:49 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+iosxr-bng, V 6.0.0[Default], Cisco Systems, at disk0:iosxr-bng-6.0.0
+ Built on Thu Dec 24 08:53:47 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+xrvr-bng-supp, V 6.0.0[Default], Cisco Systems, at disk0:xrvr-bng-supp-6.0.0
+ Built on Thu Dec 24 08:53:47 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+iosxr-security, V 6.0.0[Default], Cisco Systems, at disk0:iosxr-security-6.0.0
+ Built on Thu Dec 24 08:53:41 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
+
+xrvr-fullk9-x, V 6.0.0[Default], Cisco Systems, at disk0:xrvr-fullk9-x-6.0.0
+ Built on Thu Dec 24 08:55:12 UTC 2015
+ By iox-lnx-010 in /auto/srcarchive16/production/6.0.0/xrvr/workspace for pie
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_version___utility_head_-n_20 b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_version___utility_head_-n_20
new file mode 100644
index 00000000..7f82039f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_version___utility_head_-n_20
@@ -0,0 +1,18 @@
+Cisco IOS XR Software, Version 6.0.0[Default]
+Copyright (c) 2015 by Cisco Systems, Inc.
+
+ROM: GRUB, Version 1.99(0), DEV RELEASE
+
+iosxr01 uptime is 11 weeks, 6 days, 2 hours, 2 minutes
+System image file is "bootflash:disk0/xrvr-os-mbi-6.0.0/mbixrvr-rp.vm"
+
+cisco IOS XRv Series (Pentium Celeron Stepping 3) processor with 3169911K bytes
+of memory.
+Pentium Celeron Stepping 3 processor at 3836MHz, Revision 2.174
+IOS XRv Chassis
+
+1 Management Ethernet
+6 GigabitEthernet
+97070k bytes of non-volatile configuration memory.
+866M bytes of hard disk.
+2321392k bytes of disk0: (Sector size 512 bytes).
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_version_brief b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_version_brief
new file mode 100644
index 00000000..7f82039f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/fixtures/show_version_brief
@@ -0,0 +1,18 @@
+Cisco IOS XR Software, Version 6.0.0[Default]
+Copyright (c) 2015 by Cisco Systems, Inc.
+
+ROM: GRUB, Version 1.99(0), DEV RELEASE
+
+iosxr01 uptime is 11 weeks, 6 days, 2 hours, 2 minutes
+System image file is "bootflash:disk0/xrvr-os-mbi-6.0.0/mbixrvr-rp.vm"
+
+cisco IOS XRv Series (Pentium Celeron Stepping 3) processor with 3169911K bytes
+of memory.
+Pentium Celeron Stepping 3 processor at 3836MHz, Revision 2.174
+IOS XRv Chassis
+
+1 Management Ethernet
+6 GigabitEthernet
+97070k bytes of non-volatile configuration memory.
+866M bytes of hard disk.
+2321392k bytes of disk0: (Sector size 512 bytes).
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/iosxr_module.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/iosxr_module.py
new file mode 100644
index 00000000..1915b07e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/iosxr_module.py
@@ -0,0 +1,108 @@
+# (c) 2016 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+import json
+import os
+
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import (
+ AnsibleExitJson,
+ AnsibleFailJson,
+ ModuleTestCase,
+)
+
+
+fixture_path = os.path.join(os.path.dirname(__file__), "fixtures")
+fixture_data = {}
+
+
+def load_fixture(name):
+ path = os.path.join(fixture_path, name)
+
+ if path in fixture_data:
+ return fixture_data[path]
+
+ with open(path) as f:
+ data = f.read()
+
+ try:
+ data = json.loads(data)
+ except Exception:
+ pass
+
+ fixture_data[path] = data
+ return data
+
+
+class TestIosxrModule(ModuleTestCase):
+ def execute_module(
+ self,
+ failed=False,
+ changed=False,
+ commands=None,
+ sort=True,
+ defaults=False,
+ ):
+
+ self.load_fixtures(commands)
+
+ if failed:
+ result = self.failed()
+ self.assertTrue(result["failed"], result)
+ else:
+ result = self.changed(changed)
+ self.assertEqual(result["changed"], changed, result)
+
+ if commands is not None:
+ if sort:
+ self.assertEqual(
+ sorted(commands),
+ sorted(result["commands"]),
+ result["commands"],
+ )
+ else:
+ self.assertEqual(
+ commands,
+ result["commands"],
+ result["commands"],
+ )
+
+ return result
+
+ def failed(self):
+ with self.assertRaises(AnsibleFailJson) as exc:
+ self.module.main()
+
+ result = exc.exception.args[0]
+ self.assertTrue(result["failed"], result)
+ return result
+
+ def changed(self, changed=False):
+ with self.assertRaises(AnsibleExitJson) as exc:
+ self.module.main()
+
+ result = exc.exception.args[0]
+ self.assertEqual(result["changed"], changed, result)
+ return result
+
+ def load_fixtures(self, commands=None):
+ pass
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_hostname.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_hostname.py
new file mode 100644
index 00000000..7c676530
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_hostname.py
@@ -0,0 +1,114 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from textwrap import dedent
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_hostname
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule
+
+
+class TestIosxrHostnameModule(TestIosxrModule):
+ module = iosxr_hostname
+
+ def setUp(self):
+ super(TestIosxrHostnameModule, self).setUp()
+
+ self.mock_get_resource_connection = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection = self.mock_get_resource_connection.start()
+
+ self.mock_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.hostname.hostname."
+ "HostnameFacts.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ def tearDown(self):
+ super(TestIosxrHostnameModule, self).tearDown()
+ self.get_resource_connection.stop()
+ self.get_config.stop()
+
+ def test_iosxr_hostname_merged_idempotent(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ hostname iosxr1
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(config=dict(hostname="iosxr1"), state="merged"))
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_hostname_merged(self):
+ self.maxDiff = None
+ set_module_args(dict(config=dict(hostname="iosxr1"), state="merged"))
+ commands = ["hostname iosxr1"]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_hostname_deleted(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ hostname iosxr1
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(state="deleted"))
+ commands = ["no hostname iosxr1"]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_hostname_rendered(self):
+ self.maxDiff = None
+ set_module_args(dict(config=dict(hostname="iosxr1"), state="rendered"))
+ commands = ["hostname iosxr1"]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_hostname_gathered(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ hostname iosxr1
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ print(self.get_config.return_value)
+ set_module_args(dict(state="gathered"))
+ gathered = {"hostname": "iosxr1"}
+ result = self.execute_module(changed=False)
+ self.assertEqual(gathered, result["gathered"])
+
+ def test_iosxr_hostname_parsed(self):
+ self.maxDiff = None
+ set_module_args(dict(running_config="hostname iosxr1", state="parsed"))
+ result = self.execute_module(changed=False)
+ parsed_list = {"hostname": "iosxr1"}
+ self.assertEqual(parsed_list, result["parsed"])
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr.py
new file mode 100644
index 00000000..af2fd3a5
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr.py
@@ -0,0 +1,97 @@
+#
+# (c) 2020 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 os import path
+
+from ansible.module_utils._text import to_bytes, to_text
+from mock import MagicMock
+
+from ansible_collections.cisco.iosxr.plugins.cliconf import iosxr
+from ansible_collections.cisco.iosxr.tests.unit.compat import unittest
+
+
+class TestPluginCLIConfIOSXR(unittest.TestCase):
+ """Test class for IOSXR CLI Conf Methods"""
+
+ def setUp(self):
+ self._mock_connection = MagicMock()
+ self._prepare()
+ self._cliconf = iosxr.Cliconf(self._mock_connection)
+ self.maxDiff = None
+
+ def _prepare(self, platform="iosxr"):
+ b_FIXTURE_DIR = b"%s/fixtures/cliconf/%s" % (
+ to_bytes(
+ path.dirname(path.abspath(__file__)),
+ errors="surrogate_or_strict",
+ ),
+ to_bytes(platform),
+ )
+
+ def _connection_side_effect(*args, **kwargs):
+ try:
+ if args:
+ value = args[0]
+ else:
+ value = kwargs.get("command")
+ if b"|" in value:
+ value = value.replace(b"|", b"")
+ fixture_path = path.abspath(
+ b"%s/%s" % (b_FIXTURE_DIR, b"_".join(value.split(b" "))),
+ )
+ with open(fixture_path, "rb") as file_desc:
+ return to_text(file_desc.read())
+ except (OSError, IOError):
+ if args:
+ value = args[0]
+ return value
+ elif kwargs.get("command"):
+ value = kwargs.get("command")
+ return value
+ return "NO-OP"
+
+ self._mock_connection.send.side_effect = _connection_side_effect
+
+ def tearDown(self):
+ pass
+
+ def test_get_device_info_iosxr(self):
+ """Test get_device_info for nxos"""
+ device_info = self._cliconf.get_device_info()
+
+ mock_device_info = {
+ "network_os_image": "bootflash:disk0/xrvr-os-mbi-6.0.0/mbixrvr-rp.vm",
+ "network_os_version": "6.0.0[Default]",
+ "network_os": "iosxr",
+ "network_os_hostname": "iosxr01",
+ "network_os_model": "IOS XRv",
+ }
+
+ self.assertEqual(device_info, mock_device_info)
+
+ def test_get_command_output_iosxr(self):
+ """Test _get_command_with_output for iosxr"""
+ self._prepare()
+ cmd = self._cliconf.get_command_output("show running-config hostname")
+
+ self.assertEqual(cmd, "hostname iosxr01")
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_acl_interfaces.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_acl_interfaces.py
new file mode 100644
index 00000000..8500c073
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_acl_interfaces.py
@@ -0,0 +1,329 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_acl_interfaces
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrAclInterfacesModule(TestIosxrModule):
+ module = iosxr_acl_interfaces
+
+ def setUp(self):
+ super(TestIosxrAclInterfacesModule, self).setUp()
+
+ self.mock_get_resource_connection = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection",
+ )
+ self.get_resource_connection = self.mock_get_resource_connection.start()
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.acl_interfaces.acl_interfaces.Acl_interfacesFacts.get_config",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrAclInterfacesModule, self).tearDown()
+ self.get_resource_connection.stop()
+ self.mock_execute_show_command.stop()
+
+ def _prepare(self):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_acl_interfaces_config.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_acl_interfaces_merged_idempotent(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ access_groups=[
+ dict(
+ afi="ipv4",
+ acls=[
+ dict(name="acl_1", direction="in"),
+ dict(name="acl_2", direction="out"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ acls=[
+ dict(name="acl6_1", direction="in"),
+ dict(name="acl6_2", direction="out"),
+ ],
+ ),
+ ],
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ access_groups=[
+ dict(
+ afi="ipv4",
+ acls=[dict(name="acl_1", direction="out")],
+ ),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_acl_interfaces_merged(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ access_groups=[
+ dict(
+ afi="ipv4",
+ acls=[
+ dict(name="acl_1", direction="in"),
+ dict(name="acl_2", direction="out"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ acls=[
+ dict(name="acl6_1", direction="in"),
+ dict(name="acl6_2", direction="out"),
+ ],
+ ),
+ ],
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ access_groups=[
+ dict(
+ afi="ipv4",
+ acls=[dict(name="acl_1", direction="in")],
+ ),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "ipv4 access-group acl_1 ingress",
+ "ipv4 access-group acl_2 egress",
+ "ipv6 access-group acl6_1 ingress",
+ "ipv6 access-group acl6_2 egress",
+ "interface GigabitEthernet0/0/0/1",
+ "ipv4 access-group acl_1 ingress",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_acl_interfaces_replaced(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ access_groups=[
+ dict(
+ afi="ipv6",
+ acls=[dict(name="acl6_3", direction="in")],
+ ),
+ ],
+ ),
+ ],
+ state="replaced",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "no ipv4 access-group acl_1 ingress",
+ "no ipv4 access-group acl_2 egress",
+ "no ipv6 access-group acl6_2 egress",
+ "ipv6 access-group acl6_3 ingress",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_acl_interfaces_deleted(self):
+ self._prepare()
+ set_module_args(dict(state="deleted"))
+
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "no ipv4 access-group acl_1 ingress",
+ "no ipv4 access-group acl_2 egress",
+ "no ipv6 access-group acl6_1 ingress",
+ "no ipv6 access-group acl6_2 egress",
+ "interface GigabitEthernet0/0/0/1",
+ "no ipv4 access-group acl_1 egress",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_acl_interfaces_rendered(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ access_groups=[
+ dict(
+ afi="ipv4",
+ acls=[
+ dict(name="acl_1", direction="in"),
+ dict(name="acl_2", direction="out"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ acls=[
+ dict(name="acl6_1", direction="in"),
+ dict(name="acl6_2", direction="out"),
+ ],
+ ),
+ ],
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ access_groups=[
+ dict(
+ afi="ipv4",
+ acls=[dict(name="acl_1", direction="in")],
+ ),
+ ],
+ ),
+ ],
+ state="rendered",
+ ),
+ )
+
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "ipv4 access-group acl_1 ingress",
+ "ipv4 access-group acl_2 egress",
+ "ipv6 access-group acl6_1 ingress",
+ "ipv6 access-group acl6_2 egress",
+ "interface GigabitEthernet0/0/0/1",
+ "ipv4 access-group acl_1 ingress",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_acl_interfaces_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="interface GigabitEthernet0/0/0/0\r\n shutdown\r\n ipv4 access-group acl_1 ingress\r\n"
+ " ipv4 access-group acl_2 egress\r\n ipv6 access-group acl6_1 ingress\r\n ipv6 "
+ "access-group acl6_2 egress\r\n!\r\ninterface GigabitEthernet0/0/0/1\r\n "
+ "shutdown\r\n ipv4 access-group acl_1 egress\r\n!",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ print(result["parsed"])
+ parsed_list = [
+ {
+ "name": "GigabitEthernet0/0/0/0",
+ "access_groups": [
+ {
+ "afi": "ipv4",
+ "acls": [
+ {"name": "acl_1", "direction": "in"},
+ {"name": "acl_2", "direction": "out"},
+ ],
+ },
+ {
+ "afi": "ipv6",
+ "acls": [
+ {"name": "acl6_1", "direction": "in"},
+ {"name": "acl6_2", "direction": "out"},
+ ],
+ },
+ ],
+ },
+ {
+ "name": "GigabitEthernet0/0/0/1",
+ "access_groups": [
+ {
+ "afi": "ipv4",
+ "acls": [{"name": "acl_1", "direction": "out"}],
+ },
+ ],
+ },
+ ]
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_acl_interfaces_overridden(self):
+ self.maxDiff = None
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ access_groups=[
+ dict(
+ afi="ipv6",
+ acls=[dict(name="acl6_3", direction="in")],
+ ),
+ ],
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ access_groups=[
+ dict(
+ afi="ipv4",
+ acls=[dict(name="acl_2", direction="in")],
+ ),
+ dict(
+ afi="ipv6",
+ acls=[dict(name="acl6_3", direction="out")],
+ ),
+ ],
+ ),
+ ],
+ state="overridden",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "no ipv4 access-group acl_1 ingress",
+ "no ipv4 access-group acl_2 egress",
+ "no ipv6 access-group acl6_2 egress",
+ "ipv6 access-group acl6_3 ingress",
+ "interface GigabitEthernet0/0/0/1",
+ "no ipv4 access-group acl_1 egress",
+ "ipv4 access-group acl_2 ingress",
+ "ipv6 access-group acl6_3 egress",
+ ]
+
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_acls.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_acls.py
new file mode 100644
index 00000000..ed826b93
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_acls.py
@@ -0,0 +1,496 @@
+#
+# (c) 2019, Ansible by Red Hat, inc
+# 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
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_acls
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrAclsModule(TestIosxrModule):
+ module = iosxr_acls
+
+ def setUp(self):
+ super(TestIosxrAclsModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.acls.acls.AclsFacts.get_device_data",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrAclsModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def _prepare(self):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_acls_config.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_acls_merged(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv4",
+ acls=[
+ dict(
+ name="acl_1",
+ aces=[
+ dict(
+ sequence="30",
+ grant="permit",
+ protocol="ospf",
+ source=dict(prefix="192.168.1.0/24"),
+ destination=dict(any="true"),
+ log="true",
+ ),
+ dict(
+ sequence="40",
+ grant="deny",
+ protocol="ipv4",
+ source=dict(
+ address="10.233.0.0",
+ wildcard_bits="0.0.255.255",
+ ),
+ destination=dict(
+ net_group="netgroup1",
+ ),
+ ),
+ dict(
+ sequence="50",
+ grant="deny",
+ protocol="ipv4",
+ source=dict(
+ address="10.233.0.0",
+ wildcard_bits="0.0.255.255",
+ ),
+ destination=dict(
+ port_group="portgroup1",
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ commands = [
+ "ipv4 access-list acl_1",
+ "30 permit ospf 192.168.1.0 0.0.0.255 any log",
+ "40 deny ipv4 10.233.0.0 0.0.255.255 net-group netgroup1",
+ "50 deny ipv4 10.233.0.0 0.0.255.255 port-group portgroup1",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_acls_merged_idempotent(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv4",
+ acls=[
+ dict(
+ name="acl_2",
+ aces=[
+ dict(
+ sequence="10",
+ grant="deny",
+ protocol="ipv4",
+ destination=dict(any="true"),
+ source=dict(any="true"),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_acls_replaced(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv4",
+ acls=[
+ dict(
+ name="acl_2",
+ aces=[
+ dict(
+ sequence="30",
+ grant="permit",
+ protocol="ospf",
+ source=dict(prefix="10.0.0.0/8"),
+ destination=dict(any="true"),
+ log="true",
+ ),
+ dict(
+ sequence="40",
+ grant="deny",
+ protocol="ipv4",
+ source=dict(
+ address="10.233.0.0",
+ wildcard_bits="0.0.255.255",
+ ),
+ destination=dict(
+ net_group="netgroup1",
+ ),
+ ),
+ dict(
+ sequence="50",
+ grant="deny",
+ protocol="ipv4",
+ source=dict(
+ address="10.233.0.0",
+ wildcard_bits="0.0.255.255",
+ ),
+ destination=dict(
+ port_group="portgroup1",
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="replaced",
+ ),
+ )
+ commands = [
+ "ipv4 access-list acl_2",
+ "no 10",
+ "no 20",
+ "30 permit ospf 10.0.0.0 0.255.255.255 any log",
+ "40 deny ipv4 10.233.0.0 0.0.255.255 net-group netgroup1",
+ "50 deny ipv4 10.233.0.0 0.0.255.255 port-group portgroup1",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_acls_replaced_idempotent(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv4",
+ acls=[
+ dict(
+ name="acl_2",
+ aces=[
+ dict(
+ sequence="10",
+ grant="deny",
+ protocol="ipv4",
+ destination=dict(any="true"),
+ source=dict(any="true"),
+ ),
+ dict(
+ sequence="20",
+ grant="permit",
+ protocol="tcp",
+ destination=dict(any="true"),
+ source=dict(host="192.168.1.100"),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="replaced",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_acls_overridden(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv4",
+ acls=[
+ dict(
+ name="acl_2",
+ aces=[
+ dict(
+ sequence="40",
+ grant="permit",
+ protocol="ospf",
+ source=dict(any="true"),
+ destination=dict(any="true"),
+ log="true",
+ ),
+ dict(
+ sequence="50",
+ grant="deny",
+ protocol="ipv4",
+ source=dict(
+ address="10.233.0.0",
+ wildcard_bits="0.0.255.255",
+ ),
+ destination=dict(
+ net_group="netgroup1",
+ ),
+ ),
+ dict(
+ sequence="60",
+ grant="deny",
+ protocol="ipv4",
+ source=dict(
+ address="10.233.0.0",
+ wildcard_bits="0.0.255.255",
+ ),
+ destination=dict(
+ port_group="portgroup1",
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="overridden",
+ ),
+ )
+ commands = [
+ "no ipv6 access-list acl6_1",
+ "no ipv4 access-list acl_1",
+ "ipv4 access-list acl_2",
+ "no 10",
+ "no 20",
+ "40 permit ospf any any log",
+ "50 deny ipv4 10.233.0.0 0.0.255.255 net-group netgroup1",
+ "60 deny ipv4 10.233.0.0 0.0.255.255 port-group portgroup1",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_acls_overridden_idempotent(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv4",
+ acls=[
+ dict(
+ name="acl_1",
+ aces=[
+ dict(
+ sequence="10",
+ grant="deny",
+ protocol="ipv4",
+ source=dict(
+ address="10.233.0.0",
+ wildcard_bits="0.0.255.255",
+ ),
+ destination=dict(
+ net_group="netgroup1",
+ ),
+ ),
+ dict(
+ sequence="20",
+ grant="deny",
+ protocol="ipv4",
+ source=dict(
+ address="10.233.0.0",
+ wildcard_bits="0.0.255.255",
+ ),
+ destination=dict(
+ port_group="portgroup1",
+ ),
+ ),
+ ],
+ ),
+ dict(
+ name="acl_2",
+ aces=[
+ dict(
+ sequence="10",
+ grant="deny",
+ protocol="ipv4",
+ destination=dict(any="true"),
+ source=dict(any="true"),
+ ),
+ dict(
+ sequence="20",
+ grant="permit",
+ protocol="tcp",
+ destination=dict(any="true"),
+ source=dict(host="192.168.1.100"),
+ ),
+ ],
+ ),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ acls=[
+ dict(
+ name="acl6_1",
+ aces=[
+ dict(
+ sequence="10",
+ grant="deny",
+ protocol="icmpv6",
+ destination=dict(any="true"),
+ source=dict(any="true"),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="overridden",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_acls_deletedacls(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[dict(afi="ipv6", acls=[dict(name="acl6_1")])],
+ state="deleted",
+ ),
+ )
+ commands = ["no ipv6 access-list acl6_1"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_acls_deletedafis(self):
+ self._prepare()
+ set_module_args(dict(config=[dict(afi="ipv4")], state="deleted"))
+ commands = ["no ipv4 access-list acl_2", "no ipv4 access-list acl_1"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_acls_rendered(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv4",
+ acls=[
+ dict(
+ name="acl_2",
+ aces=[
+ dict(
+ grant="permit",
+ source=dict(any="true"),
+ destination=dict(any="true"),
+ protocol="igmp",
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="rendered",
+ ),
+ )
+ commands = ["ipv4 access-list acl_2", "permit igmp any any"]
+ result = self.execute_module(changed=False)
+ self.assertEqual(
+ sorted(result["rendered"]),
+ sorted(commands),
+ result["rendered"],
+ )
+
+ def test_iosxr_acls_overridden_on_empty_config(self):
+ self.execute_show_command.return_value = ""
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv4",
+ acls=[
+ dict(
+ name="acl_1",
+ aces=[
+ dict(
+ sequence="10",
+ grant="deny",
+ source=dict(any=True),
+ destination=dict(any=True),
+ protocol="ip",
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="overridden",
+ ),
+ )
+ cmds = ["ipv4 access-list acl_1", "10 deny ip any any"]
+ self.execute_module(changed=True, commands=cmds)
+
+ def test_iosxr_acls_parsed_matches(self):
+ set_module_args(
+ dict(
+ running_config="""ipv4 access-list ACL_NAME\n5 permit ipv4 host x.x.x.x any (409 matches)""",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = [
+ {
+ "acls": [
+ {
+ "name": "ACL_NAME",
+ "aces": [
+ {
+ "sequence": 5,
+ "grant": "permit",
+ "protocol": "ipv4",
+ "source": {"host": "x.x.x.x"},
+ "destination": {"any": True},
+ },
+ ],
+ },
+ ],
+ "afi": "ipv4",
+ },
+ ]
+ self.assertEqual(parsed_list, result["parsed"])
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_banner.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_banner.py
new file mode 100644
index 00000000..8c426f83
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_banner.py
@@ -0,0 +1,117 @@
+# (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/>.
+
+# Make coding more python3-ish
+# (c) 2016 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_banner
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrBannerModule(TestIosxrModule):
+
+ module = iosxr_banner
+
+ def setUp(self):
+ super(TestIosxrBannerModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_banner.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_banner.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_is_cliconf = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_banner.is_cliconf",
+ )
+ self.is_cliconf = self.mock_is_cliconf.start()
+
+ def tearDown(self):
+ super(TestIosxrBannerModule, self).tearDown()
+
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_is_cliconf.stop()
+
+ def load_fixtures(self, commands=None):
+ self.get_config.return_value = load_fixture("iosxr_banner_config.cfg")
+ self.load_config.return_value = dict(diff=None, session="session")
+ self.is_cliconf.return_value = True
+
+ def test_iosxr_banner_login_create(self):
+ set_module_args(dict(banner="login", text="test\nbanner\nstring"))
+ commands = ["banner login test\nbanner\nstring"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_banner_login_remove(self):
+ set_module_args(dict(banner="login", state="absent"))
+ commands = ["no banner login"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_banner_fail_create(self):
+ set_module_args(dict(banner="exec1", text="test\nbanner\nstring"))
+ result = self.execute_module(failed=True, changed=True)
+ self.assertEqual(
+ result["msg"],
+ "value of banner must be one of: login, motd, got: exec1",
+ )
+
+ def test_iosxr_banner_exec1_fail_remove(self):
+ set_module_args(dict(banner="exec1", state="absent"))
+ result = self.execute_module(failed=True, changed=True)
+ self.assertIn(
+ result["msg"],
+ "value of banner must be one of: login, motd, got: exec1",
+ )
+
+ def test_iosxr_banner_motd_create(self):
+ set_module_args(dict(banner="motd", text="test\nbanner\nstring"))
+ commands = ["banner motd test\nbanner\nstring"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_banner_motd_remove(self):
+ set_module_args(dict(banner="motd", state="absent"))
+ commands = ["no banner motd"]
+ self.execute_module(changed=True, commands=commands)
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_bgp_address_family.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_bgp_address_family.py
new file mode 100644
index 00000000..57770b59
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_bgp_address_family.py
@@ -0,0 +1,384 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from textwrap import dedent
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_bgp_address_family
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule
+
+
+class TestIosxrBgpGlobalModule(TestIosxrModule):
+ module = iosxr_bgp_address_family
+
+ def setUp(self):
+ super(TestIosxrBgpGlobalModule, self).setUp()
+
+ self.mock_get_resource_connection = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection",
+ )
+ self.get_resource_connection = self.mock_get_resource_connection.start()
+
+ self.mock_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.bgp_address_family.bgp_address_family.Bgp_address_familyFacts.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ def tearDown(self):
+ super(TestIosxrBgpGlobalModule, self).tearDown()
+ self.get_resource_connection.stop()
+ self.get_config.stop()
+
+ def test_iosxr_bgp_address_family_merged_idempotent(self):
+ run_cfg = dedent(
+ """\
+ router bgp 65536
+ address-family ipv4 unicast
+ bgp attribute-download
+ advertise best-external
+ dynamic-med interval 10
+ bgp scan-time 20
+ redistribute connected metric 10
+ redistribute isis test3 metric 4
+ redistribute application test1 metric 10
+ allocate-label all
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ dynamic_med=10,
+ redistribute=[
+ dict(
+ protocol="application",
+ id="test1",
+ metric=10,
+ ),
+ dict(protocol="connected", metric=10),
+ dict(protocol="isis", id="test3", metric=4),
+ ],
+ bgp=dict(scan_time=20, attribute_download=True),
+ advertise_best_external=True,
+ allocate_label=dict(all=True),
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_bgp_address_family_merged(self):
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ dynamic_med=10,
+ redistribute=[
+ dict(
+ protocol="application",
+ id="test1",
+ metric=10,
+ ),
+ dict(protocol="connected", metric=10),
+ dict(protocol="isis", id="test3", metric=4),
+ ],
+ bgp=dict(scan_time=20, attribute_download=True),
+ advertise_best_external=True,
+ allocate_label=dict(all=True),
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+ commands = [
+ "router bgp 65536",
+ "address-family ipv4 unicast",
+ "advertise best-external",
+ "allocate-label all",
+ "bgp attribute-download",
+ "bgp scan-time 20",
+ "dynamic-med interval 10",
+ "redistribute application test1 metric 10",
+ "redistribute connected metric 10",
+ "redistribute isis test3 metric 4",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_bgp_address_family_replaced(self):
+ run_cfg = dedent(
+ """\
+ router bgp 65536
+ address-family ipv4 unicast
+ bgp attribute-download
+ advertise best-external
+ dynamic-med interval 10
+ bgp scan-time 20
+ redistribute connected metric 10
+ redistribute isis test3 metric 4
+ redistribute application test1 metric 10
+ allocate-label all
+ address-family ipv4 mvpn
+ """,
+ )
+ self.get_config.return_value = run_cfg
+
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ dynamic_med=4,
+ redistribute=[
+ dict(
+ protocol="application",
+ id="test1",
+ metric=10,
+ ),
+ dict(protocol="connected", metric=10),
+ dict(protocol="isis", id="test3", metric=4),
+ ],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "router bgp 65536",
+ "address-family ipv4 unicast",
+ "no advertise best-external",
+ "no allocate-label all",
+ "no bgp attribute-download",
+ "no bgp scan-time 20",
+ "dynamic-med interval 4",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_bgp_address_family_replaced_idempotent(self):
+ run_cfg = dedent(
+ """\
+ router bgp 65536
+ address-family ipv4 unicast
+ dynamic-med interval 4
+ redistribute connected metric 10
+ redistribute isis test3 metric 4
+ redistribute application test1 metric 10
+ address-family ipv4 mvpn
+ """,
+ )
+ self.get_config.return_value = run_cfg
+
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ dynamic_med=4,
+ redistribute=[
+ dict(
+ protocol="application",
+ id="test1",
+ metric=10,
+ ),
+ dict(protocol="connected", metric=10),
+ dict(protocol="isis", id="test3", metric=4),
+ ],
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_bgp_address_family_deleted(self):
+ run_cfg = dedent(
+ """\
+ router bgp 65536
+ address-family ipv4 unicast
+ bgp attribute-download
+ advertise best-external
+ dynamic-med interval 10
+ bgp scan-time 20
+ redistribute connected metric 10
+ redistribute isis test3 metric 4
+ redistribute application test1 metric 10
+ allocate-label all
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(config=dict(), state="deleted"))
+
+ commands = ["router bgp 65536", "no address-family ipv4 unicast"]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_bgp_address_family_deleted1(self):
+ run_cfg = dedent(
+ """\
+ router bgp 65536
+ address-family ipv6 unicast
+ dynamic-med interval 4
+ address-family ipv4 unicast
+ bgp attribute-download
+ advertise best-external
+ dynamic-med interval 10
+ bgp scan-time 20
+ redistribute connected metric 10
+ redistribute isis test3 metric 4
+ redistribute application test1 metric 10
+ allocate-label all
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ as_number=65536,
+ address_family=[
+ dict(afi="ipv6", safi="unicast", dynamic_med=4),
+ ],
+ ),
+ state="deleted",
+ ),
+ )
+ commands = ["router bgp 65536", "no address-family ipv6 unicast"]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_bgp_address_family_deleted_idempotent(self):
+ run_cfg = dedent(
+ """\
+ "router bgp 65536"
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(config=dict(as_number="65536"), state="deleted"))
+
+ result = self.execute_module(changed=False)
+ self.assertEqual(result["commands"], [])
+
+ def test_iosxr_bgp_address_family_rendered(self):
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ dynamic_med=10,
+ redistribute=[
+ dict(
+ protocol="application",
+ id="test1",
+ metric=10,
+ ),
+ dict(protocol="connected", metric=10),
+ dict(protocol="isis", id="test3", metric=4),
+ ],
+ bgp=dict(scan_time=20, attribute_download=True),
+ advertise_best_external=True,
+ allocate_label=dict(all=True),
+ ),
+ ],
+ ),
+ state="rendered",
+ ),
+ )
+ commands = [
+ "router bgp 65536",
+ "address-family ipv4 unicast",
+ "advertise best-external",
+ "allocate-label all",
+ "bgp attribute-download",
+ "bgp scan-time 20",
+ "dynamic-med interval 10",
+ "redistribute application test1 metric 10",
+ "redistribute connected metric 10",
+ "redistribute isis test3 metric 4",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_bgp_address_family_parsed(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ router bgp 65536
+ address-family ipv4 unicast
+ bgp attribute-download
+ advertise best-external
+ dynamic-med interval 10
+ bgp scan-time 20
+ redistribute application test1 metric 10
+ allocate-label all
+ """,
+ )
+ set_module_args(dict(running_config=run_cfg, state="parsed"))
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "address_family": [
+ {
+ "advertise_best_external": True,
+ "safi": "unicast",
+ "afi": "ipv4",
+ "allocate_label": {"all": True},
+ "bgp": {"attribute_download": True, "scan_time": 20},
+ "dynamic_med": 10,
+ "redistribute": [
+ {
+ "protocol": "application",
+ "metric": 10,
+ "id": "test1",
+ },
+ ],
+ },
+ ],
+ "as_number": "65536",
+ }
+
+ self.assertEqual(parsed_list, result["parsed"])
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_bgp_global.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_bgp_global.py
new file mode 100644
index 00000000..05480d09
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_bgp_global.py
@@ -0,0 +1,493 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from textwrap import dedent
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_bgp_global
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule
+
+
+class TestIosxrBgpGlobalModule(TestIosxrModule):
+ module = iosxr_bgp_global
+
+ def setUp(self):
+ super(TestIosxrBgpGlobalModule, self).setUp()
+
+ self.mock_get_resource_connection = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection = self.mock_get_resource_connection.start()
+
+ self.mock_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.bgp_global.bgp_global."
+ "Bgp_globalFacts.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ def tearDown(self):
+ super(TestIosxrBgpGlobalModule, self).tearDown()
+ self.get_resource_connection.stop()
+ self.get_config.stop()
+
+ def test_iosxr_bgp_global_merged_idempotent(self):
+ run_cfg = dedent(
+ """\
+ router bgp 65536
+ bgp confederation identifier 4
+ bgp router-id 192.0.2.10
+ bgp cluster-id 5
+ default-metric 4
+ socket send-buffer-size 4098
+ bgp bestpath med confed
+ socket receive-buffer-size 514
+ neighbor 192.0.2.11
+ remote-as 65537
+ cluster-id 3
+ neighbor 192.0.2.14
+ remote-as 65538
+ bfd fast-detect strict-mode
+ bfd multiplier 6
+ bfd minimum-interval 20
+ vrf vrf1
+ default-metric 5
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ default_metric=4,
+ socket=dict(
+ receive_buffer_size=514,
+ send_buffer_size=4098,
+ ),
+ bgp=dict(
+ confederation=dict(identifier=4),
+ bestpath=dict(med=dict(confed=True)),
+ cluster_id=5,
+ router_id="192.0.2.10",
+ ),
+ neighbors=[
+ dict(
+ neighbor="192.0.2.11",
+ cluster_id=3,
+ remote_as="65537",
+ ),
+ dict(
+ neighbor="192.0.2.14",
+ remote_as="65538",
+ bfd=dict(
+ multiplier=6,
+ minimum_interval=20,
+ fast_detect=dict(strict_mode=True),
+ ),
+ ),
+ ],
+ vrfs=[dict(vrf="vrf1", default_metric=5)],
+ ),
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_bgp_global_merged(self):
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ default_metric=4,
+ socket=dict(
+ receive_buffer_size=514,
+ send_buffer_size=4098,
+ ),
+ bgp=dict(
+ confederation=dict(identifier=4),
+ bestpath=dict(med=dict(confed=True)),
+ cluster_id=5,
+ router_id="192.0.2.10",
+ ),
+ neighbors=[
+ dict(
+ neighbor="192.0.2.11",
+ cluster_id=3,
+ remote_as="65537",
+ ),
+ dict(
+ neighbor="192.0.2.14",
+ remote_as="65538",
+ bfd=dict(
+ multiplier=6,
+ minimum_interval=20,
+ fast_detect=dict(strict_mode=True),
+ ),
+ ),
+ ],
+ vrfs=[dict(vrf="vrf1", default_metric=5)],
+ ),
+ state="merged",
+ ),
+ )
+ commands = [
+ "router bgp 65536",
+ "bgp cluster-id 5",
+ "bgp router-id 192.0.2.10",
+ "bgp bestpath med confed",
+ "bgp confederation identifier 4",
+ "default-metric 4",
+ "socket receive-buffer-size 514",
+ "socket send-buffer-size 4098",
+ "neighbor 192.0.2.11",
+ "cluster-id 3",
+ "remote-as 65537",
+ "neighbor 192.0.2.14",
+ "bfd fast-detect strict-mode",
+ "bfd minimum-interval 20",
+ "bfd multiplier 6",
+ "remote-as 65538",
+ "vrf vrf1",
+ "default-metric 5",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_bgp_global_replaced(self):
+ run_cfg = dedent(
+ """\
+ router bgp 65536
+ bgp confederation identifier 4
+ bgp router-id 192.0.2.10
+ bgp cluster-id 5
+ default-metric 4
+ socket send-buffer-size 4098
+ bgp bestpath med confed
+ socket receive-buffer-size 514
+ neighbor 192.0.2.11
+ remote-as 65537
+ cluster-id 3
+ neighbor 192.0.2.14
+ remote-as 65538
+ bfd fast-detect strict-mode
+ bfd multiplier 6
+ bfd minimum-interval 20
+ vrf vrf1
+ default-metric 5
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ default_metric=5,
+ socket=dict(
+ receive_buffer_size=514,
+ send_buffer_size=4098,
+ ),
+ bgp=dict(
+ confederation=dict(identifier=4),
+ bestpath=dict(med=dict(confed=True)),
+ cluster_id=5,
+ router_id="192.0.2.10",
+ ),
+ neighbors=[
+ dict(
+ neighbor="192.0.2.13",
+ remote_as="65538",
+ bfd=dict(
+ multiplier=6,
+ minimum_interval=20,
+ fast_detect=dict(strict_mode=True),
+ ),
+ ),
+ ],
+ vrfs=[dict(vrf="vrf1", default_metric=5)],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "router bgp 65536",
+ "no neighbor 192.0.2.11",
+ "no neighbor 192.0.2.14",
+ "default-metric 5",
+ "neighbor 192.0.2.13",
+ "bfd fast-detect strict-mode",
+ "bfd minimum-interval 20",
+ "bfd multiplier 6",
+ "remote-as 65538",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_bgp_global_replaced_idempotent(self):
+ run_cfg = dedent(
+ """\
+ router bgp 65536
+ bgp confederation identifier 4
+ bgp router-id 192.0.2.10
+ bgp cluster-id 5
+ default-metric 4
+ socket send-buffer-size 4098
+ bgp bestpath med confed
+ socket receive-buffer-size 514
+ neighbor 192.0.2.11
+ remote-as 65537
+ cluster-id 3
+ neighbor 192.0.2.14
+ remote-as 65538
+ bfd fast-detect strict-mode
+ bfd multiplier 6
+ bfd minimum-interval 20
+ vrf vrf1
+ default-metric 5
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ default_metric=4,
+ socket=dict(
+ receive_buffer_size=514,
+ send_buffer_size=4098,
+ ),
+ bgp=dict(
+ confederation=dict(identifier=4),
+ bestpath=dict(med=dict(confed=True)),
+ cluster_id=5,
+ router_id="192.0.2.10",
+ ),
+ neighbors=[
+ dict(
+ neighbor="192.0.2.11",
+ cluster_id=3,
+ remote_as="65537",
+ ),
+ dict(
+ neighbor="192.0.2.14",
+ remote_as="65538",
+ bfd=dict(
+ multiplier=6,
+ minimum_interval=20,
+ fast_detect=dict(strict_mode=True),
+ ),
+ ),
+ ],
+ vrfs=[dict(vrf="vrf1", default_metric=5)],
+ ),
+ state="replaced",
+ ),
+ )
+
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_bgp_global_deleted(self):
+ run_cfg = dedent(
+ """\
+ router bgp 65536
+ bgp confederation identifier 4
+ bgp router-id 192.0.2.10
+ bgp cluster-id 5
+ default-metric 4
+ socket send-buffer-size 4098
+ bgp bestpath med confed
+ socket receive-buffer-size 514
+ neighbor 192.0.2.11
+ remote-as 65537
+ cluster-id 3
+ neighbor 192.0.2.14
+ remote-as 65538
+ bfd fast-detect strict-mode
+ bfd multiplier 6
+ bfd minimum-interval 20
+ vrf vrf1
+ default-metric 5
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(config=dict(as_number="65536"), state="deleted"))
+
+ commands = [
+ "router bgp 65536",
+ "no bgp cluster-id 5",
+ "no bgp router-id 192.0.2.10",
+ "no bgp bestpath med confed",
+ "no bgp confederation identifier 4",
+ "no default-metric 4",
+ "no socket receive-buffer-size 514",
+ "no socket send-buffer-size 4098",
+ "no neighbor 192.0.2.11",
+ "no neighbor 192.0.2.14",
+ "no vrf vrf1",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_bgp_global_deleted_idempotent(self):
+ run_cfg = dedent(
+ """\
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(config=dict(as_number="65536"), state="deleted"))
+
+ result = self.execute_module(changed=False)
+ self.assertEqual(result["commands"], [])
+
+ def test_iosxr_bgp_global_rendered(self):
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ default_metric=4,
+ socket=dict(
+ receive_buffer_size=514,
+ send_buffer_size=4098,
+ ),
+ bgp=dict(
+ confederation=dict(identifier=4),
+ bestpath=dict(med=dict(confed=True)),
+ cluster_id=5,
+ router_id="192.0.2.10",
+ ),
+ neighbors=[
+ dict(
+ neighbor="192.0.2.11",
+ cluster_id=3,
+ remote_as="65537",
+ ),
+ dict(
+ neighbor="192.0.2.14",
+ remote_as="65538",
+ bfd=dict(
+ multiplier=6,
+ minimum_interval=20,
+ fast_detect=dict(set=True),
+ ),
+ ),
+ ],
+ vrfs=[dict(vrf="vrf1", default_metric=5)],
+ ),
+ state="rendered",
+ ),
+ )
+
+ commands = [
+ "router bgp 65536",
+ "bgp cluster-id 5",
+ "bgp router-id 192.0.2.10",
+ "bgp bestpath med confed",
+ "bgp confederation identifier 4",
+ "default-metric 4",
+ "socket receive-buffer-size 514",
+ "socket send-buffer-size 4098",
+ "neighbor 192.0.2.11",
+ "cluster-id 3",
+ "remote-as 65537",
+ "neighbor 192.0.2.14",
+ "bfd fast-detect",
+ "bfd minimum-interval 20",
+ "bfd multiplier 6",
+ "remote-as 65538",
+ "vrf vrf1",
+ "default-metric 5",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_bgp_global_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="router bgp 65536\n bgp confederation identifier 4\n "
+ "bgp router-id 192.0.2.10\n bgp cluster-id 5\n default-metric 4\n "
+ "socket send-buffer-size 4098\n bgp bestpath med confed\n "
+ "socket receive-buffer-size 514\n neighbor 192.0.2.11\n remote-as 65537\n "
+ "cluster-id 3\n !\n neighbor 192.0.2.14\n remote-as 65538\n description test nbr description\n"
+ " bfd fast-detect strict-mode\n "
+ " bfd multiplier 6\n bfd minimum-interval 20\n !\n!",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "as_number": "65536",
+ "bgp": {
+ "confederation": {"identifier": 4},
+ "cluster_id": "5",
+ "router_id": "192.0.2.10",
+ "bestpath": {"med": {"confed": True}},
+ },
+ "default_metric": 4,
+ "socket": {"send_buffer_size": 4098, "receive_buffer_size": 514},
+ "neighbors": [
+ {"neighbor_address": "192.0.2.11", "remote_as": 65537, "cluster_id": "3"},
+ {
+ "neighbor_address": "192.0.2.14",
+ "remote_as": 65538,
+ "description": "test nbr description",
+ },
+ ],
+ "bfd": {"multiplier": 6, "minimum_interval": 20},
+ }
+
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_bgp_global_purged(self):
+ run_cfg = dedent(
+ """\
+ router bgp 65536
+ bgp confederation identifier 4
+ bgp router-id 192.0.2.10
+ bgp cluster-id 5
+ default-metric 4
+ socket send-buffer-size 4098
+ bgp bestpath med confed
+ socket receive-buffer-size 514
+ neighbor 192.0.2.11
+ remote-as 65537
+ cluster-id 3
+ neighbor 192.0.2.14
+ remote-as 65538
+ bfd fast-detect strict-mode
+ bfd multiplier 6
+ bfd minimum-interval 20
+ vrf vrf1
+ default-metric 5
+ """,
+ )
+
+ self.get_config.return_value = run_cfg
+
+ set_module_args(dict(state="purged"))
+ commands = ["no router bgp 65536"]
+
+ result = self.execute_module(changed=True)
+ self.assertEqual(set(result["commands"]), set(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_bgp_neighbor_address_family.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_bgp_neighbor_address_family.py
new file mode 100644
index 00000000..d6fd0610
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_bgp_neighbor_address_family.py
@@ -0,0 +1,826 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from textwrap import dedent
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_bgp_neighbor_address_family
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule
+
+
+class TestIosxrBgpNeighborAddressFamilyModule(TestIosxrModule):
+ module = iosxr_bgp_neighbor_address_family
+
+ def setUp(self):
+ super(TestIosxrBgpNeighborAddressFamilyModule, self).setUp()
+
+ self.mock_get_resource_connection = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection = self.mock_get_resource_connection.start()
+
+ self.mock_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.bgp_neighbor_address_family.bgp_neighbor_address_family."
+ "Bgp_neighbor_address_familyFacts.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ def tearDown(self):
+ super(TestIosxrBgpNeighborAddressFamilyModule, self).tearDown()
+ self.get_resource_connection.stop()
+ self.get_config.stop()
+
+ def test_iosxr_bgp_nbr_af_merged_idempotent(self):
+ run_cfg = dedent(
+ """\
+ router bgp 1
+ bgp router-id 1.2.3.4
+ neighbor 1.1.1.1
+ remote-as 5
+ address-family ipv4 unicast
+ origin-as validation disable
+ bestpath origin-as allow invalid
+ aigp
+ aigp send med
+ send-community-ebgp
+ multipath
+ allowas-in 4
+ maximum-prefix 10 20 restart 10
+ as-override
+ capability orf prefix both
+ send-extended-community-ebgp
+ default-originate
+ next-hop-self
+ send-community-gshut-ebgp
+ soft-reconfiguration inbound
+ send-multicast-attributes
+ remove-private-AS inbound entire-aspath
+ route-policy test1 in
+ route-policy test1 out
+ next-hop-unchanged multipath
+ vrf vrf1
+ rd auto
+ address-family ipv4 unicast
+ neighbor 1.2.1.2
+ remote-as 5
+ address-family ipv4 unicast
+ multipath
+ capability orf prefix both
+ default-originate
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="1",
+ vrfs=[
+ dict(
+ vrf="vrf1",
+ neighbors=[
+ dict(
+ neighbor_address="1.2.1.2",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ multipath=True,
+ default_originate=dict(set=True),
+ capability_orf_prefix="both",
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ neighbors=[
+ dict(
+ neighbor_address="1.1.1.1",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ multipath=True,
+ default_originate=dict(set=True),
+ capability_orf_prefix="both",
+ send_multicast_attributes=dict(set=True),
+ soft_reconfiguration=dict(inbound=dict(set=True)),
+ send_community_gshut_ebgp=dict(set=True),
+ send_extended_community_ebgp=dict(set=True),
+ send_community_ebgp=dict(set=True),
+ origin_as=dict(validation=dict(disable=True)),
+ remove_private_AS=dict(
+ set=True,
+ inbound=True,
+ entire_aspath=True,
+ ),
+ route_policy=dict(inbound="test1", outbound="test1"),
+ maximum_prefix=dict(
+ max_limit=10,
+ threshold_value=20,
+ restart=10,
+ ),
+ next_hop_self=dict(set=True),
+ next_hop_unchanged=dict(multipath=True),
+ aigp=dict(set=True, send_med=dict(set=True)),
+ as_override=dict(set=True),
+ allowas_in=dict(value=4),
+ bestpath_origin_as_allow_invalid=True,
+ long_lived_graceful_restart=dict(
+ stale_time=dict(send=20, accept=30),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_bgp_nbr_af_merged(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="1",
+ vrfs=[
+ dict(
+ vrf="vrf1",
+ neighbors=[
+ dict(
+ neighbor_address="1.2.1.2",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ multipath=True,
+ default_originate=dict(set=True),
+ capability_orf_prefix="both",
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ neighbors=[
+ dict(
+ neighbor_address="1.1.1.1",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ multipath=True,
+ default_originate=dict(set=True),
+ capability_orf_prefix="both",
+ send_multicast_attributes=dict(set=True),
+ soft_reconfiguration=dict(inbound=dict(set=True)),
+ send_community_gshut_ebgp=dict(set=True),
+ send_extended_community_ebgp=dict(set=True),
+ send_community_ebgp=dict(set=True),
+ origin_as=dict(validation=dict(disable=True)),
+ remove_private_AS=dict(
+ set=True,
+ inbound=True,
+ entire_aspath=True,
+ ),
+ route_policy=dict(inbound="test1", outbound="test1"),
+ maximum_prefix=dict(
+ max_limit=10,
+ threshold_value=20,
+ restart=10,
+ ),
+ next_hop_self=dict(set=True),
+ next_hop_unchanged=dict(multipath=True),
+ aigp=dict(set=True, send_med=dict(set=True)),
+ as_override=dict(set=True),
+ bestpath_origin_as_allow_invalid=True,
+ long_lived_graceful_restart=dict(
+ stale_time=dict(send=20, accept=30),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+ commands = [
+ "router bgp 1",
+ "neighbor 1.1.1.1",
+ "address-family ipv4 unicast",
+ "aigp",
+ "aigp send med",
+ "as-override",
+ "bestpath origin-as allow invalid",
+ "capability orf prefix both",
+ "default-originate",
+ "maximum-prefix 10 20 restart 10",
+ "multipath",
+ "next-hop-self",
+ "next-hop-unchanged multipath",
+ "origin-as validation disable",
+ "remove-private-AS inbound entire-aspath",
+ "route-policy test1 in",
+ "route-policy test1 out",
+ "send-community-ebgp",
+ "send-community-gshut-ebgp",
+ "send-extended-community-ebgp",
+ "send-multicast-attributes",
+ "soft-reconfiguration inbound",
+ "vrf vrf1",
+ "neighbor 1.2.1.2",
+ "address-family ipv4 unicast",
+ "capability orf prefix both",
+ "default-originate",
+ "multipath",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_bgp_nbr_af_replaced(self):
+ run_cfg = dedent(
+ """\
+ router bgp 1
+ bgp router-id 1.2.3.4
+ neighbor 1.1.1.1
+ remote-as 5
+ address-family ipv4 unicast
+ origin-as validation disable
+ bestpath origin-as allow invalid
+ aigp
+ aigp send med
+ send-community-ebgp
+ multipath
+ allowas-in 4
+ maximum-prefix 10 20 restart 10
+ as-override
+ capability orf prefix both
+ send-extended-community-ebgp
+ default-originate
+ next-hop-self
+ send-community-gshut-ebgp
+ soft-reconfiguration inbound
+ send-multicast-attributes
+ remove-private-AS inbound entire-aspath
+ next-hop-unchanged multipath
+ vrf vrf1
+ rd auto
+ address-family ipv4 unicast
+ neighbor 1.2.1.2
+ remote-as 5
+ address-family ipv4 unicast
+ multipath
+ capability orf prefix both
+ default-originate
+ route-policy test2 in
+ route-policy test2 out
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="1",
+ vrfs=[
+ dict(
+ vrf="vrf1",
+ neighbors=[
+ dict(
+ neighbor_address="1.2.1.2",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ multipath=True,
+ default_originate=dict(set=True),
+ route_policy=dict(inbound="test1", outbound="test1"),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "router bgp 1",
+ "vrf vrf1",
+ "neighbor 1.2.1.2",
+ "address-family ipv4 unicast",
+ "no capability orf prefix both",
+ "route-policy test1 in",
+ "route-policy test1 out",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_bgp_nbr_af_replaced_idempotent(self):
+ run_cfg = dedent(
+ """\
+ router bgp 1
+ bgp router-id 1.2.3.4
+ neighbor 1.1.1.1
+ remote-as 5
+ address-family ipv4 unicast
+ origin-as validation disable
+ bestpath origin-as allow invalid
+ aigp
+ aigp send med
+ send-community-ebgp
+ multipath
+ allowas-in 4
+ maximum-prefix 10 20 restart 10
+ as-override
+ capability orf prefix both
+ send-extended-community-ebgp
+ default-originate
+ next-hop-self
+ send-community-gshut-ebgp
+ soft-reconfiguration inbound
+ send-multicast-attributes
+ remove-private-AS inbound entire-aspath
+ next-hop-unchanged multipath
+ vrf vrf1
+ rd auto
+ address-family ipv4 unicast
+ neighbor 1.2.1.2
+ remote-as 5
+ address-family ipv4 unicast
+ multipath
+ capability orf prefix both
+ default-originate
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="1",
+ vrfs=[
+ dict(
+ vrf="vrf1",
+ neighbors=[
+ dict(
+ neighbor_address="1.2.1.2",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ multipath=True,
+ default_originate=dict(set=True),
+ capability_orf_prefix="both",
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_bgp_nbr_af_deleted(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ router bgp 1
+ bgp router-id 1.2.3.4
+ neighbor 1.1.1.1
+ remote-as 5
+ address-family ipv4 unicast
+ origin-as validation disable
+ bestpath origin-as allow invalid
+ aigp
+ aigp send med
+ send-community-ebgp
+ multipath
+ allowas-in 4
+ maximum-prefix 10 20 restart 10
+ as-override
+ capability orf prefix both
+ send-extended-community-ebgp
+ default-originate
+ next-hop-self
+ send-community-gshut-ebgp
+ soft-reconfiguration inbound
+ send-multicast-attributes
+ remove-private-AS inbound entire-aspath
+ next-hop-unchanged multipath
+ vrf vrf1
+ rd auto
+ address-family ipv4 unicast
+ neighbor 1.2.1.2
+ remote-as 5
+ address-family ipv4 unicast
+ multipath
+ capability orf prefix both
+ default-originate
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(config=dict(), state="deleted"))
+ commands = [
+ "router bgp 1",
+ "neighbor 1.1.1.1",
+ "no address-family ipv4 unicast",
+ "vrf vrf1",
+ "neighbor 1.2.1.2",
+ "no address-family ipv4 unicast",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_bgp_nbr_af_deleted_idempotent(self):
+ run_cfg = dedent(
+ """\
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(config=dict(as_number="1"), state="deleted"))
+
+ result = self.execute_module(changed=False)
+ self.assertEqual(result["commands"], [])
+
+ def test_iosxr_bgp_nbr_af_rendered(self):
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="1",
+ vrfs=[
+ dict(
+ vrf="vrf1",
+ neighbors=[
+ dict(
+ neighbor_address="1.2.1.2",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ multipath=True,
+ default_originate=dict(set=True),
+ capability_orf_prefix="both",
+ as_override=dict(set=True),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ neighbors=[
+ dict(
+ neighbor_address="1.1.1.1",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ multipath=True,
+ default_originate=dict(set=True),
+ capability_orf_prefix="both",
+ send_multicast_attributes=dict(set=True),
+ soft_reconfiguration=dict(inbound=dict(set=True)),
+ send_community_gshut_ebgp=dict(set=True),
+ send_extended_community_ebgp=dict(set=True),
+ send_community_ebgp=dict(set=True),
+ origin_as=dict(validation=dict(disable=True)),
+ remove_private_AS=dict(
+ set=True,
+ inbound=True,
+ entire_aspath=True,
+ ),
+ maximum_prefix=dict(
+ max_limit=10,
+ threshold_value=20,
+ restart=10,
+ ),
+ next_hop_self=dict(set=True),
+ next_hop_unchanged=dict(multipath=True),
+ aigp=dict(set=True, send_med=dict(set=True)),
+ as_override=dict(set=True),
+ allowas_in=dict(value=4),
+ bestpath_origin_as_allow_invalid=True,
+ long_lived_graceful_restart=dict(
+ stale_time=dict(send=20, accept=30),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="rendered",
+ ),
+ )
+ commands = [
+ "router bgp 1",
+ "neighbor 1.1.1.1",
+ "address-family ipv4 unicast",
+ "aigp",
+ "aigp send med",
+ "allowas-in 4",
+ "as-override",
+ "bestpath origin-as allow invalid",
+ "capability orf prefix both",
+ "default-originate",
+ "maximum-prefix 10 20 restart 10",
+ "multipath",
+ "next-hop-self",
+ "next-hop-unchanged multipath",
+ "origin-as validation disable",
+ "remove-private-AS inbound entire-aspath",
+ "send-community-ebgp",
+ "send-community-gshut-ebgp",
+ "send-extended-community-ebgp",
+ "send-multicast-attributes",
+ "soft-reconfiguration inbound",
+ "vrf vrf1",
+ "neighbor 1.2.1.2",
+ "address-family ipv4 unicast",
+ "as-override",
+ "capability orf prefix both",
+ "default-originate",
+ "multipath",
+ ]
+
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_bgp_global_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="router bgp 1\n bgp router-id 1.2.1.3\n neighbor 1.1.1.1\n "
+ "remote-as 6\n address-family ipv4 unicast\n origin-as validation disable\n "
+ "bestpath origin-as allow invalid\n weight 0\n send-community-ebgp\n "
+ " multipath\n allowas-in 3\n maximum-prefix 1 1 discard-extra-paths\n"
+ " capability orf prefix both\n "
+ "send-extended-community-ebgp\n long-lived-graceful-restart capable\n"
+ " next-hop-self\n "
+ "remove-private-AS\n send-community-gshut-ebgp inheritance-disable\n "
+ " send-multicast-attributes\n "
+ "remove-private-AS inbound entire-aspath\n "
+ "next-hop-unchanged multipath\n !\n "
+ "!\n !",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "as_number": "1",
+ "neighbors": [
+ {
+ "address_family": [
+ {
+ "afi": "ipv4",
+ "allowas_in": {"value": 3},
+ "bestpath_origin_as_allow_invalid": True,
+ "capability_orf_prefix": "both",
+ "long_lived_graceful_restart": {"capable": True},
+ "multipath": True,
+ "next_hop_self": {"set": True},
+ "next_hop_unchanged": {"multipath": True},
+ "origin_as": {"validation": {"disable": True}},
+ "remove_private_AS": {
+ "entire_aspath": True,
+ "inbound": True,
+ "set": True,
+ },
+ "safi": "unicast",
+ "send_community_ebgp": {"set": True},
+ "send_community_gshut_ebgp": {"inheritance_disable": True},
+ "send_extended_community_ebgp": {"set": True},
+ "send_multicast_attributes": {"set": True},
+ "weight": 0,
+ },
+ ],
+ "neighbor_address": "1.1.1.1",
+ },
+ ],
+ }
+
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_bgp_add_fam_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="router bgp 1\n bgp router-id 1.2.1.3\n neighbor 1.1.1.1\n "
+ "remote-as 6\n address-family vpnv4 unicast\n origin-as validation disable\n "
+ "bestpath origin-as allow invalid\n weight 0\n send-community-ebgp\n "
+ " multipath\n allowas-in 3\n maximum-prefix 1 1 discard-extra-paths\n"
+ " capability orf prefix both\n "
+ "next-hop-unchanged multipath\n !\n "
+ "!\n !",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "as_number": "1",
+ "neighbors": [
+ {
+ "neighbor_address": "1.1.1.1",
+ "address_family": [
+ {
+ "afi": "vpnv4",
+ "safi": "unicast",
+ "origin_as": {"validation": {"disable": True}},
+ "bestpath_origin_as_allow_invalid": True,
+ "weight": 0,
+ "send_community_ebgp": {"set": True},
+ "multipath": True,
+ "allowas_in": {"value": 3},
+ "capability_orf_prefix": "both",
+ "next_hop_unchanged": {"multipath": True},
+ },
+ ],
+ },
+ ],
+ }
+
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_bgp_nbr_af_afi_replaced(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="1",
+ neighbors=[
+ dict(
+ neighbor_address="1.1.1.1",
+ address_family=[
+ dict(
+ afi="vpnv4",
+ safi="flowspec",
+ multipath=True,
+ default_originate=dict(set=True),
+ capability_orf_prefix="both",
+ send_multicast_attributes=dict(set=True),
+ soft_reconfiguration=dict(inbound=dict(set=True)),
+ send_community_gshut_ebgp=dict(set=True),
+ send_extended_community_ebgp=dict(set=True),
+ send_community_ebgp=dict(set=True),
+ origin_as=dict(validation=dict(disable=True)),
+ remove_private_AS=dict(
+ set=True,
+ inbound=True,
+ entire_aspath=True,
+ ),
+ route_policy=dict(inbound="test1", outbound="test1"),
+ maximum_prefix=dict(
+ max_limit=10,
+ threshold_value=20,
+ restart=10,
+ ),
+ next_hop_self=dict(set=True),
+ next_hop_unchanged=dict(multipath=True),
+ aigp=dict(set=True, send_med=dict(set=True)),
+ as_override=dict(set=True),
+ bestpath_origin_as_allow_invalid=True,
+ long_lived_graceful_restart=dict(
+ stale_time=dict(send=20, accept=30),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "address-family vpnv4 flowspec",
+ "aigp",
+ "aigp send med",
+ "as-override",
+ "bestpath origin-as allow invalid",
+ "capability orf prefix both",
+ "default-originate",
+ "maximum-prefix 10 20 restart 10",
+ "multipath",
+ "neighbor 1.1.1.1",
+ "next-hop-self",
+ "next-hop-unchanged multipath",
+ "origin-as validation disable",
+ "remove-private-AS inbound entire-aspath",
+ "route-policy test1 in",
+ "route-policy test1 out",
+ "router bgp 1",
+ "send-community-ebgp",
+ "send-community-gshut-ebgp",
+ "send-extended-community-ebgp",
+ "send-multicast-attributes",
+ "soft-reconfiguration inbound",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_bgp_nbr_af_overridden(self):
+ run_cfg = dedent(
+ """\
+ router bgp 1
+ bgp router-id 1.2.3.4
+ neighbor 1.1.1.1
+ remote-as 5
+ address-family ipv4 unicast
+ origin-as validation disable
+ bestpath origin-as allow invalid
+ aigp
+ aigp send med
+ send-community-ebgp
+ multipath
+ allowas-in 4
+ maximum-prefix 10 20 restart 10
+ as-override
+ capability orf prefix both
+ send-extended-community-ebgp
+ default-originate
+ next-hop-self
+ send-community-gshut-ebgp
+ soft-reconfiguration inbound
+ send-multicast-attributes
+ remove-private-AS inbound entire-aspath
+ next-hop-unchanged multipath
+ vrf vrf1
+ rd auto
+ address-family ipv4 unicast
+ neighbor 1.2.1.2
+ remote-as 5
+ address-family ipv4 unicast
+ multipath
+ capability orf prefix both
+ default-originate
+ route-policy test2 in
+ route-policy test2 out
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="1",
+ vrfs=[
+ dict(
+ vrf="vrf1",
+ neighbors=[
+ dict(
+ neighbor_address="1.2.1.2",
+ address_family=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ multipath=True,
+ default_originate=dict(set=True),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="overridden",
+ ),
+ )
+ commands = [
+ "router bgp 1",
+ "vrf vrf1",
+ "neighbor 1.2.1.2",
+ "address-family ipv4 unicast",
+ "no capability orf prefix both",
+ "no route-policy test2 in",
+ "no route-policy test2 out",
+ "neighbor 1.1.1.1",
+ "no address-family ipv4 unicast",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_command.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_command.py
new file mode 100644
index 00000000..feb70876
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_command.py
@@ -0,0 +1,128 @@
+# (c) 2016 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_command
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrCommandModule(TestIosxrModule):
+
+ module = iosxr_command
+
+ def setUp(self):
+ super(TestIosxrCommandModule, self).setUp()
+
+ self.mock_run_commands = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_command.run_commands",
+ )
+ self.run_commands = self.mock_run_commands.start()
+
+ def tearDown(self):
+ super(TestIosxrCommandModule, self).tearDown()
+
+ self.mock_run_commands.stop()
+
+ def load_fixtures(self, commands=None):
+ def load_from_file(*args, **kwargs):
+ module, commands = args
+ output = list()
+
+ for item in commands:
+ try:
+ command = item["command"]
+ except Exception:
+ command = item
+ filename = str(command).replace(" ", "_")
+ output.append(load_fixture(filename))
+ return output
+
+ self.run_commands.side_effect = load_from_file
+
+ def test_iosxr_command_simple(self):
+ set_module_args(dict(commands=["show version"]))
+ result = self.execute_module()
+ self.assertEqual(len(result["stdout"]), 1)
+ self.assertTrue(
+ result["stdout"][0].startswith("Cisco IOS XR Software"),
+ )
+
+ def test_iosxr_command_multiple(self):
+ set_module_args(dict(commands=["show version", "show version"]))
+ result = self.execute_module()
+ self.assertEqual(len(result["stdout"]), 2)
+ self.assertTrue(
+ result["stdout"][0].startswith("Cisco IOS XR Software"),
+ )
+
+ def test_iosxr_command_wait_for(self):
+ wait_for = 'result[0] contains "Cisco IOS"'
+ set_module_args(dict(commands=["show version"], wait_for=wait_for))
+ self.execute_module()
+
+ def test_iosxr_command_wait_for_fails(self):
+ wait_for = 'result[0] contains "test string"'
+ set_module_args(dict(commands=["show version"], wait_for=wait_for))
+ self.execute_module(failed=True)
+ self.assertEqual(self.run_commands.call_count, 10)
+
+ def test_iosxr_command_retries(self):
+ wait_for = 'result[0] contains "test string"'
+ set_module_args(
+ dict(commands=["show version"], wait_for=wait_for, retries=2),
+ )
+ self.execute_module(failed=True)
+ self.assertEqual(self.run_commands.call_count, 2)
+
+ def test_iosxr_command_match_any(self):
+ wait_for = [
+ 'result[0] contains "Cisco IOS"',
+ 'result[0] contains "test string"',
+ ]
+ set_module_args(
+ dict(commands=["show version"], wait_for=wait_for, match="any"),
+ )
+ self.execute_module()
+
+ def test_iosxr_command_match_all(self):
+ wait_for = [
+ 'result[0] contains "Cisco IOS"',
+ 'result[0] contains "XR Software"',
+ ]
+ set_module_args(
+ dict(commands=["show version"], wait_for=wait_for, match="all"),
+ )
+ self.execute_module()
+
+ def test_iosxr_command_match_all_failure(self):
+ wait_for = [
+ 'result[0] contains "Cisco IOS"',
+ 'result[0] contains "test string"',
+ ]
+ commands = ["show version", "show version"]
+ set_module_args(
+ dict(commands=commands, wait_for=wait_for, match="all"),
+ )
+ self.execute_module(failed=True)
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_config.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_config.py
new file mode 100644
index 00000000..bbfdcb3e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_config.py
@@ -0,0 +1,313 @@
+#
+# (c) 2016 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.cliconf.iosxr import Cliconf
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_config
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import MagicMock, patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrConfigModule(TestIosxrModule):
+
+ module = iosxr_config
+
+ def setUp(self):
+ super(TestIosxrConfigModule, self).setUp()
+
+ self.patcher_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_config.get_config",
+ )
+ self.mock_get_config = self.patcher_get_config.start()
+
+ self.patcher_exec_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_config.load_config",
+ )
+ self.mock_exec_command = self.patcher_exec_command.start()
+
+ self.mock_get_connection = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_config.get_connection",
+ )
+ self.get_connection = self.mock_get_connection.start()
+
+ self.conn = self.get_connection()
+ self.conn.edit_config = MagicMock()
+
+ self.cliconf_obj = Cliconf(MagicMock())
+ self.running_config = load_fixture("iosxr_config_config.cfg")
+
+ def tearDown(self):
+ super(TestIosxrConfigModule, self).tearDown()
+
+ self.patcher_get_config.stop()
+ self.patcher_exec_command.stop()
+ self.mock_get_connection.stop()
+
+ def load_fixtures(self, commands=None):
+ config_file = "iosxr_config_config.cfg"
+ self.mock_get_config.return_value = load_fixture(config_file)
+ self.mock_exec_command.return_value = "dummy diff"
+
+ def test_iosxr_config_unchanged(self):
+ src = load_fixture("iosxr_config_config.cfg")
+ set_module_args(dict(src=src))
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(src, src),
+ )
+ self.execute_module()
+
+ def test_iosxr_config_src(self):
+ src = load_fixture("iosxr_config_src.cfg")
+ set_module_args(dict(src=src))
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(src, self.running_config),
+ )
+ commands = [
+ "hostname foo",
+ "interface GigabitEthernet0/0",
+ "no ip address",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_config_backup(self):
+ set_module_args(dict(backup=True))
+ result = self.execute_module()
+ self.assertIn("__backup__", result)
+
+ def test_iosxr_config_lines_wo_parents(self):
+ lines = ["hostname foo"]
+ set_module_args(dict(lines=lines))
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(
+ "\n".join(lines),
+ self.running_config,
+ ),
+ )
+ commands = ["hostname foo"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_config_lines_w_parents(self):
+ lines = ["shutdown"]
+ parents = ["interface GigabitEthernet0/0"]
+ set_module_args(dict(lines=lines, parents=parents))
+ module = MagicMock()
+ module.params = {"lines": lines, "parents": parents, "src": None}
+ candidate_config = iosxr_config.get_candidate(module)
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(
+ candidate_config,
+ self.running_config,
+ ),
+ )
+ commands = ["interface GigabitEthernet0/0", "shutdown"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_config_before(self):
+ lines = ["hostname foo"]
+ set_module_args(dict(lines=lines, before=["test1", "test2"]))
+ commands = ["test1", "test2", "hostname foo"]
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(
+ "\n".join(lines),
+ self.running_config,
+ ),
+ )
+ self.execute_module(changed=True, commands=commands, sort=False)
+
+ def test_iosxr_config_after(self):
+ lines = ["hostname foo"]
+ set_module_args(dict(lines=lines, after=["test1", "test2"]))
+ commands = ["hostname foo", "test1", "test2"]
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(
+ "\n".join(lines),
+ self.running_config,
+ ),
+ )
+ self.execute_module(changed=True, commands=commands, sort=False)
+
+ def test_iosxr_config_before_after_no_change(self):
+ lines = ["hostname router"]
+ set_module_args(
+ dict(
+ lines=lines,
+ before=["test1", "test2"],
+ after=["test3", "test4"],
+ ),
+ )
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(
+ "\n".join(lines),
+ self.running_config,
+ ),
+ )
+ self.execute_module()
+
+ def test_iosxr_config_config(self):
+ config = "hostname localhost"
+ lines = ["hostname router"]
+ set_module_args(dict(lines=["hostname router"], config=config))
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff("\n".join(lines), config),
+ )
+ commands = ["hostname router"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_config_replace_block(self):
+ lines = ["description test string", "test string"]
+ parents = ["interface GigabitEthernet0/0"]
+ set_module_args(dict(lines=lines, replace="block", parents=parents))
+ commands = parents + lines
+
+ module = MagicMock()
+ module.params = {"lines": lines, "parents": parents, "src": None}
+ candidate_config = iosxr_config.get_candidate(module)
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(
+ candidate_config,
+ self.running_config,
+ diff_replace="block",
+ path=parents,
+ ),
+ )
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_config_force(self):
+ lines = ["hostname router"]
+ set_module_args(dict(lines=lines, force=True))
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(
+ "\n".join(lines),
+ self.running_config,
+ diff_match="none",
+ ),
+ )
+ self.execute_module(changed=True, commands=lines)
+
+ def test_iosxr_config_admin(self):
+ lines = ["username admin", "group root-system", "secret P@ssw0rd"]
+ set_module_args(dict(lines=lines, admin=True))
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(
+ "\n".join(lines),
+ self.running_config,
+ ),
+ )
+ self.execute_module(changed=True, commands=lines)
+
+ def test_iosxr_config_match_none(self):
+ lines = ["ip address 1.2.3.4 255.255.255.0", "description test string"]
+ parents = ["interface GigabitEthernet0/0"]
+ set_module_args(dict(lines=lines, parents=parents, match="none"))
+ commands = parents + lines
+ module = MagicMock()
+ module.params = {"lines": lines, "parents": parents, "src": None}
+ candidate_config = iosxr_config.get_candidate(module)
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(
+ candidate_config,
+ self.running_config,
+ diff_match="none",
+ path=parents,
+ ),
+ )
+
+ self.execute_module(changed=True, commands=commands, sort=False)
+
+ def test_iosxr_config_match_strict(self):
+ lines = [
+ "ip address 1.2.3.4 255.255.255.0",
+ "description test string",
+ "shutdown",
+ ]
+ parents = ["interface GigabitEthernet0/0"]
+ set_module_args(dict(lines=lines, parents=parents, match="strict"))
+ commands = parents + ["shutdown"]
+ module = MagicMock()
+ module.params = {"lines": lines, "parents": parents, "src": None}
+ candidate_config = iosxr_config.get_candidate(module)
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(
+ candidate_config,
+ self.running_config,
+ diff_match="strict",
+ path=parents,
+ ),
+ )
+
+ self.execute_module(changed=True, commands=commands, sort=False)
+
+ def test_iosxr_config_match_exact(self):
+ lines = [
+ "ip address 1.2.3.4 255.255.255.0",
+ "description test string",
+ "shutdown",
+ ]
+ parents = ["interface GigabitEthernet0/0"]
+ set_module_args(dict(lines=lines, parents=parents, match="exact"))
+ commands = parents + lines
+ module = MagicMock()
+ module.params = {"lines": lines, "parents": parents, "src": None}
+ candidate_config = iosxr_config.get_candidate(module)
+ self.conn.get_diff = MagicMock(
+ return_value=self.cliconf_obj.get_diff(
+ candidate_config,
+ self.running_config,
+ diff_match="exact",
+ path=parents,
+ ),
+ )
+
+ self.execute_module(changed=True, commands=commands, sort=False)
+
+ def test_iosxr_config_src_and_lines_fails(self):
+ args = dict(src="foo", lines="foo")
+ set_module_args(args)
+ self.execute_module(failed=True)
+
+ def test_iosxr_config_src_and_parents_fails(self):
+ args = dict(src="foo", parents="foo")
+ set_module_args(args)
+ self.execute_module(failed=True)
+
+ def test_iosxr_config_match_exact_requires_lines(self):
+ args = dict(match="exact")
+ set_module_args(args)
+ self.execute_module(failed=True)
+
+ def test_iosxr_config_match_strict_requires_lines(self):
+ args = dict(match="strict")
+ set_module_args(args)
+ self.execute_module(failed=True)
+
+ def test_iosxr_config_replace_block_requires_lines(self):
+ args = dict(replace="block")
+ set_module_args(args)
+ self.execute_module(failed=True)
+
+ def test_iosxr_config_replace_config_requires_src(self):
+ args = dict(replace="config")
+ set_module_args(args)
+ self.execute_module(failed=True)
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_facts.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_facts.py
new file mode 100644
index 00000000..7848f798
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_facts.py
@@ -0,0 +1,120 @@
+# (c) 2016 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+import json
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_facts
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrFacts(TestIosxrModule):
+
+ module = iosxr_facts
+
+ def setUp(self):
+ super(TestIosxrFacts, self).setUp()
+
+ self.mock_run_commands = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.legacy.base.run_commands",
+ )
+ self.run_commands = self.mock_run_commands.start()
+
+ self.mock_get_resource_connection = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ )
+ self.get_resource_connection = self.mock_get_resource_connection.start()
+
+ self.mock_get_capabilities = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.legacy.base.get_capabilities",
+ )
+ self.get_capabilities = self.mock_get_capabilities.start()
+ self.get_capabilities.return_value = {
+ "device_info": {
+ "network_os": "iosxr",
+ "network_os_hostname": "iosxr01",
+ "network_os_image": "bootflash:disk0/xrvr-os-mbi-6.1.3/mbixrvr-rp.vm",
+ "network_os_version": "6.1.3[Default]",
+ },
+ "network_api": "cliconf",
+ }
+
+ def tearDown(self):
+ super(TestIosxrFacts, self).tearDown()
+
+ self.mock_run_commands.stop()
+ self.mock_get_capabilities.stop()
+ self.mock_get_resource_connection.stop()
+
+ def load_fixtures(self, commands=None):
+ def load_from_file(*args, **kwargs):
+ module, commands = args
+ output = list()
+
+ for item in commands:
+ try:
+ obj = json.loads(item)
+ command = obj["command"]
+ except ValueError:
+ command = item
+ filename = str(command).replace(" ", "_")
+ filename = filename.replace("/", "7")
+ filename = filename.replace("|", "_")
+ output.append(load_fixture(filename))
+ return output
+
+ self.run_commands.side_effect = load_from_file
+
+ def test_iosxr_facts_gather_subset_default(self):
+ set_module_args(dict())
+ result = self.execute_module()
+ ansible_facts = result["ansible_facts"]
+ self.assertIn("default", ansible_facts["ansible_net_gather_subset"][0])
+ self.assertEqual(
+ [],
+ ansible_facts["ansible_net_gather_network_resources"],
+ )
+ self.assertEqual("iosxr", ansible_facts["ansible_net_system"])
+ self.assertEqual(
+ True,
+ True if ansible_facts.get("ansible_net_version") else False,
+ )
+ self.assertEqual(
+ True,
+ True if ansible_facts.get("ansible_net_python_version") else False,
+ )
+ self.assertEqual(
+ True,
+ True if ansible_facts.get("ansible_net_api") else False,
+ )
+
+ def test_iosxr_facts_gather_subset_config(self):
+ set_module_args({"gather_subset": "config"})
+ result = self.execute_module()
+ ansible_facts = result["ansible_facts"]
+ self.assertIn("default", ansible_facts["ansible_net_gather_subset"])
+ self.assertIn("config", ansible_facts["ansible_net_gather_subset"])
+ self.assertEqual("iosxr01", ansible_facts["ansible_net_hostname"])
+ self.assertIn("ansible_net_config", ansible_facts)
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_interfaces.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_interfaces.py
new file mode 100644
index 00000000..4b7a0bcd
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_interfaces.py
@@ -0,0 +1,288 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_interfaces
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrInterfacesModule(TestIosxrModule):
+ module = iosxr_interfaces
+
+ def setUp(self):
+ super(TestIosxrInterfacesModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.interfaces.interfaces.InterfacesFacts.get_config",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrInterfacesModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def _prepare(self):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_interface_config.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_interfaces_merged_idempotent(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ description="Configured and Merged by Ansible-Network",
+ mtu=110,
+ enabled=True,
+ duplex="half",
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ description="Configured and Merged by Ansible-Network",
+ mtu=2800,
+ speed=100,
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_interfaces_merged(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ description="Configured and Merged by Ansible-Network",
+ mtu=110,
+ enabled=True,
+ duplex="half",
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ description="Configured and Merged by Ansible-Network",
+ mtu=2800,
+ enabled=False,
+ duplex="full",
+ speed=100,
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "description Configured and Merged by Ansible-Network",
+ "mtu 110",
+ "duplex half",
+ "no shutdown",
+ "interface GigabitEthernet0/0/0/1",
+ "description Configured and Merged by Ansible-Network",
+ "mtu 2800",
+ "speed 100",
+ "duplex full",
+ "shutdown",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_interfaces_replaced(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ description="Configured and Replaced by Ansible-Network",
+ mtu=110,
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ description="Configured and Replaced by Ansible-Network",
+ speed=100,
+ ),
+ ],
+ state="replaced",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "description Configured and Replaced by Ansible-Network",
+ "no duplex",
+ "interface GigabitEthernet0/0/0/1",
+ "description Configured and Replaced by Ansible-Network",
+ "no mtu",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_interfaces_deleted(self):
+ self._prepare()
+ set_module_args(dict(state="deleted"))
+
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "no description",
+ "no mtu",
+ "no duplex",
+ "interface GigabitEthernet0/0/0/1",
+ "no description",
+ "no speed",
+ "no mtu",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_interfaces_rendered(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ description="Configured and Merged by Ansible-Network",
+ mtu=110,
+ enabled=True,
+ duplex="half",
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ description="Configured and Merged by Ansible-Network",
+ mtu=2800,
+ enabled=False,
+ duplex="full",
+ speed=100,
+ ),
+ ],
+ state="rendered",
+ ),
+ )
+
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "description Configured and Merged by Ansible-Network",
+ "mtu 110",
+ "duplex half",
+ "no shutdown",
+ "interface GigabitEthernet0/0/0/1",
+ "description Configured and Merged by Ansible-Network",
+ "mtu 2800",
+ "speed 100",
+ "duplex full",
+ "shutdown",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_interfaces_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="interface GigabitEthernet0/0/0/0\n description Configured and Merged by Ansible-Network\n "
+ "mtu 110\n duplex half\ninterface GigabitEthernet0/0/0/1\n "
+ "description Configured and Merged by Ansible-Network\n no shutdown\n mtu 2800\n speed 100",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = [
+ {
+ "description": "Configured and Merged by Ansible-Network",
+ "duplex": "half",
+ "enabled": True,
+ "mtu": 110,
+ "name": "GigabitEthernet0/0/0/0",
+ },
+ {
+ "description": "Configured and Merged by Ansible-Network",
+ "enabled": True,
+ "mtu": 2800,
+ "name": "GigabitEthernet0/0/0/1",
+ "speed": 100,
+ },
+ ]
+
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_interfaces_overridden(self):
+ self.maxDiff = None
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ description="Configured and Overridden by Ansible-Network",
+ mtu=2000,
+ enabled=False,
+ duplex="full",
+ speed=100,
+ ),
+ ],
+ state="overridden",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "no description",
+ "no mtu",
+ "no duplex",
+ "interface GigabitEthernet0/0/0/1",
+ "description Configured and Overridden by Ansible-Network",
+ "mtu 2000",
+ "duplex full",
+ "shutdown",
+ ]
+
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_l2_interfaces.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_l2_interfaces.py
new file mode 100644
index 00000000..10053878
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_l2_interfaces.py
@@ -0,0 +1,246 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_l2_interfaces
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrL2InterfacesModule(TestIosxrModule):
+ module = iosxr_l2_interfaces
+
+ def setUp(self):
+ super(TestIosxrL2InterfacesModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+ self.mock_get_os_version = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.config.l2_interfaces.l2_interfaces.get_os_version",
+ )
+ self.get_os_version = self.mock_get_os_version.start()
+ self.get_os_version.return_value = "7.0.2"
+ self.mock_get_os_version1 = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.l2_interfaces.l2_interfaces.get_os_version",
+ )
+ self.get_os_version1 = self.mock_get_os_version1.start()
+ self.get_os_version1.return_value = "7.0.2"
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.l2_interfaces.l2_interfaces.L2_InterfacesFacts.get_config",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrL2InterfacesModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_get_config.stop()
+ self.mock_get_os_version.stop()
+ self.get_os_version1.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def _prepare(self):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_l2_interface_config.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_l2_interfaces_merged_idempotent(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ l2transport=True,
+ l2protocol=[dict(cpsv="tunnel")],
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/3.900",
+ encapsulation=dict(dot1q=20, second_dot1q=40),
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_l2_interfaces_merged(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ l2transport=True,
+ l2protocol=[dict(cpsv="tunnel")],
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/3.900",
+ encapsulation=dict(dot1q=20, second_dot1q=40),
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/1",
+ "l2transport l2protocol cpsv tunnel",
+ "interface GigabitEthernet0/0/0/3.900",
+ "encapsulation dot1q 20 second-dot1q 40",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_l2_interfaces_replaced(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ l2transport=True,
+ l2protocol=[dict(cpsv="drop")],
+ ),
+ ],
+ state="replaced",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/1",
+ "l2transport l2protocol cpsv drop",
+ "no l2transport",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_l2_interfaces_deleted(self):
+ self._prepare()
+ set_module_args(dict(state="deleted"))
+
+ commands = [
+ "interface GigabitEthernet0/0/0/1",
+ "no l2transport",
+ "interface GigabitEthernet0/0/0/3.900",
+ "no encapsulation dot1q",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_l2_interfaces_rendered(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ l2transport=True,
+ l2protocol=[dict(cpsv="tunnel")],
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/3.900",
+ encapsulation=dict(dot1q=20, second_dot1q=40),
+ ),
+ ],
+ state="rendered",
+ ),
+ )
+
+ commands = [
+ "interface GigabitEthernet0/0/0/1",
+ "l2transport l2protocol cpsv tunnel",
+ "interface GigabitEthernet0/0/0/3.900",
+ "encapsulation dot1q 20 second-dot1q 40",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_l2_interfaces_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="interface GigabitEthernet0/0/0/1\n l2transport\n l2protocol cpsv tunnel\n "
+ "propagate remote-status\n !",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ print(result["parsed"])
+ parsed_list = [
+ {
+ "name": "GigabitEthernet0/0/0/1",
+ "l2transport": True,
+ "l2protocol": [{"cpsv": "tunnel"}],
+ "propagate": True,
+ },
+ ]
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_l2_interfaces_overridden(self):
+ self.maxDiff = None
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/4",
+ l2transport=True,
+ l2protocol=[dict(cpsv="tunnel")],
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/3.900",
+ encapsulation=dict(dot1q=40, second_dot1q=60),
+ ),
+ ],
+ state="overridden",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/4",
+ "l2transport l2protocol cpsv tunnel",
+ "interface GigabitEthernet0/0/0/3.900",
+ "encapsulation dot1q 40 second-dot1q 60",
+ "interface GigabitEthernet0/0/0/1",
+ "no l2transport",
+ ]
+
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_l3_interfaces.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_l3_interfaces.py
new file mode 100644
index 00000000..5fab9f7e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_l3_interfaces.py
@@ -0,0 +1,255 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_l3_interfaces
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrL3InterfacesModule(TestIosxrModule):
+ module = iosxr_l3_interfaces
+
+ def setUp(self):
+ super(TestIosxrL3InterfacesModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.l3_interfaces.l3_interfaces.L3_InterfacesFacts.get_config",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrL3InterfacesModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def _prepare(self):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_l3_interface_config.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_l3_interfaces_merged_idempotent(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ ipv4=[dict(address="198.51.100.1/24")],
+ ipv6=[dict(address="2001:db8::/32")],
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ ipv4=[
+ dict(address="192.0.2.1/24"),
+ dict(address="192.0.2.2/24", secondary=True),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_l3_interfaces_merged(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ ipv4=[dict(address="198.51.100.1/24")],
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ ipv4=[
+ dict(address="192.0.2.1/24"),
+ dict(address="192.0.2.2/24", secondary=True),
+ ],
+ ipv6=[dict(address="2001:db8:0:3::/64")],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "ipv4 address 198.51.100.1 255.255.255.0",
+ "interface GigabitEthernet0/0/0/1",
+ "ipv4 address 192.0.2.2 255.255.255.0 secondary",
+ "ipv4 address 192.0.2.1 255.255.255.0",
+ "ipv6 address 2001:db8:0:3::/64",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_l3_interfaces_replaced(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ ipv4=[
+ dict(address="203.0.113.27/24"),
+ dict(address="203.0.114.1/24", secondary=True),
+ ],
+ ),
+ ],
+ state="replaced",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "no ipv6 address",
+ "ipv4 address 203.0.113.27 255.255.255.0",
+ "ipv4 address 203.0.114.1 255.255.255.0 secondary",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_l3_interfaces_deleted(self):
+ self._prepare()
+ set_module_args(dict(state="deleted"))
+
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "no ipv4 address",
+ "no ipv6 address",
+ "interface GigabitEthernet0/0/0/1",
+ "no ipv4 address",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_l3_interfaces_rendered(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ ipv4=[dict(address="198.51.100.1/24")],
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ ipv4=[
+ dict(address="192.0.2.1/24"),
+ dict(address="192.0.2.2/24", secondary=True),
+ ],
+ ipv6=[dict(address="2001:db8:0:3::/64")],
+ ),
+ ],
+ state="rendered",
+ ),
+ )
+
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "ipv4 address 198.51.100.1 255.255.255.0",
+ "interface GigabitEthernet0/0/0/1",
+ "ipv4 address 192.0.2.2 255.255.255.0 secondary",
+ "ipv4 address 192.0.2.1 255.255.255.0",
+ "ipv6 address 2001:db8:0:3::/64",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_l3_interfaces_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="interface GigabitEthernet0/0/0/0\nipv4 address 198.51.100.1 255.255.255.0\n"
+ "ipv6 address 2001:db8::/32\ninterface GigabitEthernet0/0/0/1\nipv4 address"
+ " 192.0.2.1 255.255.255.0\nipv4 address 192.0.2.2 255.255.255.0 secondary\n",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ print(result["parsed"])
+ parsed_list = [
+ {
+ "name": "GigabitEthernet0/0/0/0",
+ "ipv4": [{"address": "198.51.100.1 255.255.255.0"}],
+ "ipv6": [{"address": "2001:db8::/32"}],
+ },
+ {
+ "name": "GigabitEthernet0/0/0/1",
+ "ipv4": [
+ {"address": "192.0.2.1 255.255.255.0"},
+ {"address": "192.0.2.2 255.255.255.0", "secondary": True},
+ ],
+ },
+ ]
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_l3_interfaces_overridden(self):
+ self.maxDiff = None
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ ipv4=[dict(address="198.51.102.1/24")],
+ ipv6=[dict(address="2001:db8:1::/64")],
+ ),
+ ],
+ state="overridden",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "no ipv4 address",
+ "no ipv6 address",
+ "interface GigabitEthernet0/0/0/1",
+ "no ipv4 address",
+ "ipv4 address 198.51.102.1 255.255.255.0",
+ "ipv6 address 2001:db8:1::/64",
+ ]
+
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lacp.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lacp.py
new file mode 100644
index 00000000..e4c9c467
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lacp.py
@@ -0,0 +1,93 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_lacp
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrLacpModule(TestIosxrModule):
+ module = iosxr_lacp
+
+ def setUp(self):
+ super(TestIosxrLacpModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.lacp.lacp.LacpFacts.get_config",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrLacpModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def _prepare(self):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_lacp_config.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_lacp_merged(self):
+ set_module_args(
+ dict(
+ config=dict(
+ system=dict(
+ priority=12,
+ mac=dict(address="00c1.4c00.bd15"),
+ ),
+ ),
+ state="merged",
+ ),
+ )
+ commands = [
+ "lacp system mac 00c1.4c00.bd15",
+ "lacp system priority 12",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lacp_interfaces.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lacp_interfaces.py
new file mode 100644
index 00000000..55358a06
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lacp_interfaces.py
@@ -0,0 +1,263 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_lacp_interfaces
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrLacpInterfacesModule(TestIosxrModule):
+ module = iosxr_lacp_interfaces
+
+ def setUp(self):
+ super(TestIosxrLacpInterfacesModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.lacp_interfaces.lacp_interfaces.Lacp_interfacesFacts.get_config",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrLacpInterfacesModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def _prepare(self):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_lacp_interfaces_config.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_lacp_interfaces_merged_idempotent(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="Bundle-Ether10",
+ churn_logging="actor",
+ collector_max_delay=100,
+ switchover_suppress_flaps=500,
+ ),
+ dict(
+ name="Bundle-Ether11",
+ system=dict(mac="00c2.4c00.bd15"),
+ ),
+ dict(name="GigabitEthernet0/0/0/1", period=200),
+ ],
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_lacp_interfaces_merged(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="Bundle-Ether10",
+ churn_logging="actor",
+ collector_max_delay=100,
+ switchover_suppress_flaps=500,
+ ),
+ dict(
+ name="Bundle-Ether11",
+ system=dict(mac="00c2.4c00.bd15"),
+ ),
+ dict(name="GigabitEthernet0/0/0/1", period=100),
+ ],
+ state="merged",
+ ),
+ )
+ commands = [
+ "interface Bundle-Ether10",
+ "lacp churn logging actor",
+ "lacp switchover suppress-flaps 500",
+ "lacp collector-max-delay 100",
+ "interface Bundle-Ether11",
+ "lacp system mac 00c2.4c00.bd15",
+ "interface GigabitEthernet0/0/0/1",
+ "lacp period 100",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_lacp_interfaces_replaced(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(name="Bundle-Ether10", churn_logging="partner"),
+ dict(name="GigabitEthernet0/0/0/1", period=300),
+ ],
+ state="replaced",
+ ),
+ )
+ commands = [
+ "interface Bundle-Ether10",
+ "no lacp switchover suppress-flaps 500",
+ "no lacp collector-max-delay 100",
+ "lacp churn logging partner",
+ "interface GigabitEthernet0/0/0/1",
+ "lacp period 300",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_lacp_interfaces_deleted(self):
+ self._prepare()
+ set_module_args(dict(state="deleted"))
+
+ commands = [
+ "interface Bundle-Ether10",
+ "no lacp switchover suppress-flaps 500",
+ "no lacp collector-max-delay 100",
+ "no lacp churn logging actor",
+ "interface Bundle-Ether11",
+ "no lacp system mac 00c2.4c00.bd15",
+ "interface GigabitEthernet0/0/0/1",
+ "no lacp period 200",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_lag_interfaces_rendered(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="Bundle-Ether10",
+ churn_logging="actor",
+ collector_max_delay=100,
+ switchover_suppress_flaps=500,
+ ),
+ dict(
+ name="Bundle-Ether11",
+ system=dict(mac="00c2.4c00.bd15"),
+ ),
+ dict(name="GigabitEthernet0/0/0/1", period=100),
+ ],
+ state="rendered",
+ ),
+ )
+
+ commands = [
+ "interface Bundle-Ether10",
+ "lacp churn logging actor",
+ "lacp switchover suppress-flaps 500",
+ "lacp collector-max-delay 100",
+ "interface Bundle-Ether11",
+ "lacp system mac 00c2.4c00.bd15",
+ "interface GigabitEthernet0/0/0/1",
+ "lacp period 100",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_lacp_interfaces_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="interface Bundle-Ether10\r\n lacp churn logging actor\r\n lacp"
+ " switchover suppress-flaps 500\r\n "
+ "lacp collector-max-delay 100\r\n!\r\ninterface "
+ "Bundle-Ether11\r\n lacp system mac 00c2.4c00.bd15\r"
+ "\n!\r\ninterface MgmtEth0/RP0/CPU0/0\r\n ipv4 address"
+ " 192.0.2.11 255.255.255.0\r\n!\r\ninterface "
+ "GigabitEthernet0/0/0/1\r\n lacp period 200\r\n!",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ print(result["parsed"])
+ parsed_list = [
+ {
+ "churn_logging": "actor",
+ "collector_max_delay": 100,
+ "name": "Bundle-Ether10",
+ "switchover_suppress_flaps": 500,
+ },
+ {"name": "Bundle-Ether11", "system": {"mac": "00c2.4c00.bd15"}},
+ {"name": "GigabitEthernet0/0/0/1", "period": 200},
+ ]
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_lag_interfaces_overridden(self):
+ self.maxDiff = None
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="Bundle-Ether12",
+ churn_logging="both",
+ collector_max_delay=100,
+ switchover_suppress_flaps=500,
+ ),
+ dict(name="GigabitEthernet0/0/0/1", period=300),
+ ],
+ state="overridden",
+ ),
+ )
+ commands = [
+ "interface Bundle-Ether10",
+ "no lacp switchover suppress-flaps 500",
+ "no lacp collector-max-delay 100",
+ "no lacp churn logging actor",
+ "interface Bundle-Ether11",
+ "no lacp system mac 00c2.4c00.bd15",
+ "interface Bundle-Ether12",
+ "lacp churn logging both",
+ "lacp collector-max-delay 100",
+ "lacp switchover suppress-flaps 500",
+ "interface GigabitEthernet0/0/0/1",
+ "lacp period 300",
+ ]
+
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lag_interfaces.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lag_interfaces.py
new file mode 100644
index 00000000..b0d68fc6
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lag_interfaces.py
@@ -0,0 +1,375 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_lag_interfaces
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrLagInterfacesModule(TestIosxrModule):
+ module = iosxr_lag_interfaces
+
+ def setUp(self):
+ super(TestIosxrLagInterfacesModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.lag_interfaces.lag_interfaces.Lag_interfacesFacts.get_config",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrLagInterfacesModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def _prepare(self):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_lag_interface_config.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_lag_interfaces_merged_idempotent(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="Bundle-Ether10",
+ mode="active",
+ members=[
+ dict(
+ member="GigabitEthernet0/0/0/0",
+ mode="inherit",
+ ),
+ dict(
+ member="GigabitEthernet0/0/0/1",
+ mode="passive",
+ ),
+ ],
+ links=dict(max_active=10, min_active=2),
+ ),
+ dict(
+ name="Bundle-Ether11",
+ mode="active",
+ members=[
+ dict(
+ member="GigabitEthernet0/0/0/8",
+ mode="passive",
+ ),
+ dict(
+ member="GigabitEthernet0/0/0/9",
+ mode="passive",
+ ),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_lag_interfaces_merged(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="Bundle-Ether10",
+ mode="active",
+ members=[
+ dict(
+ member="GigabitEthernet0/0/0/0",
+ mode="inherit",
+ ),
+ dict(
+ member="GigabitEthernet0/0/0/1",
+ mode="passive",
+ ),
+ ],
+ links=dict(max_active=10, min_active=2),
+ ),
+ dict(
+ name="Bundle-Ether11",
+ mode="active",
+ members=[
+ dict(
+ member="GigabitEthernet0/0/0/8",
+ mode="passive",
+ ),
+ dict(
+ member="GigabitEthernet0/0/0/9",
+ mode="passive",
+ ),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ commands = [
+ "interface Bundle-Ether10",
+ "bundle minimum-active links 2",
+ "bundle maximum-active links 10",
+ "lacp mode active",
+ "interface GigabitEthernet0/0/0/1",
+ "bundle id 10 mode passive",
+ "interface GigabitEthernet0/0/0/0",
+ "bundle id 10 mode inherit",
+ "interface Bundle-Ether11",
+ "lacp mode active",
+ "interface GigabitEthernet0/0/0/8",
+ "bundle id 11 mode passive",
+ "interface GigabitEthernet0/0/0/9",
+ "bundle id 11 mode passive",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_lag_interfaces_replaced(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="Bundle-Ether10",
+ mode="passive",
+ members=[
+ dict(
+ member="GigabitEthernet0/0/0/0",
+ mode="passive",
+ ),
+ ],
+ ),
+ dict(name="Bundle-Ether12", mode="active"),
+ ],
+ state="replaced",
+ ),
+ )
+ commands = [
+ "interface Bundle-Ether10",
+ "no bundle maximum-active links 10",
+ "no bundle minimum-active links 2",
+ "lacp mode passive",
+ "interface GigabitEthernet0/0/0/1",
+ "no bundle id",
+ "interface GigabitEthernet0/0/0/0",
+ "bundle id 10 mode passive",
+ "interface Bundle-Ether12",
+ "lacp mode active",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_lag_interfaces_deleted(self):
+ self._prepare()
+ set_module_args(dict(state="deleted"))
+
+ commands = [
+ "interface Bundle-Ether10",
+ "no bundle maximum-active links 10",
+ "no bundle minimum-active links 2",
+ "no lacp mode active",
+ "interface GigabitEthernet0/0/0/0",
+ "no bundle id",
+ "interface GigabitEthernet0/0/0/1",
+ "no bundle id",
+ "interface Bundle-Ether11",
+ "no lacp mode active",
+ "interface GigabitEthernet0/0/0/8",
+ "no bundle id",
+ "interface GigabitEthernet0/0/0/9",
+ "no bundle id",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_lag_interfaces_rendered(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="Bundle-Ether10",
+ mode="active",
+ members=[
+ dict(
+ member="GigabitEthernet0/0/0/0",
+ mode="passive",
+ ),
+ dict(
+ member="GigabitEthernet0/0/0/1",
+ mode="passive",
+ ),
+ ],
+ links=dict(max_active=10, min_active=2),
+ ),
+ dict(
+ name="Bundle-Ether11",
+ mode="active",
+ members=[
+ dict(
+ member="GigabitEthernet0/0/0/8",
+ mode="passive",
+ ),
+ dict(
+ member="GigabitEthernet0/0/0/9",
+ mode="passive",
+ ),
+ ],
+ ),
+ ],
+ state="rendered",
+ ),
+ )
+
+ commands = [
+ "interface Bundle-Ether10",
+ "bundle minimum-active links 2",
+ "bundle maximum-active links 10",
+ "lacp mode active",
+ "interface GigabitEthernet0/0/0/1",
+ "bundle id 10 mode passive",
+ "interface GigabitEthernet0/0/0/0",
+ "bundle id 10 mode passive",
+ "interface Bundle-Ether11",
+ "lacp mode active",
+ "interface GigabitEthernet0/0/0/8",
+ "bundle id 11 mode passive",
+ "interface GigabitEthernet0/0/0/9",
+ "bundle id 11 mode passive",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_lag_interfaces_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="interface Bundle-Ether10\r\n lacp mode active\r\n bundle maximum-active "
+ "links 10\r\n bundle minimum-active links 2\r\n!\r\ninterface Bundle-Ether11"
+ "\r\nlacp mode active\r\n!\r\ninterface GigabitEthernet0/0/0/0\r\n description "
+ '"GigabitEthernet - 0"\r\n bundle id 10 mode inherit\r\n!\r\ninterface '
+ "GigabitEthernet0/0/0/1"
+ '\r\n description "GigabitEthernet - 2"\r\n bundle id 10 mode passive\r\n!\r\n'
+ 'interface GigabitEthernet0/0/0/8\r\n description "GigabitEthernet - 8"'
+ "\r\n bundle id 11 mode passive"
+ "\r\n!\r\ninterface GigabitEthernet0/0/0/9\r\n description "
+ '"GigabitEthernet - 9"\r\n bundle id 11 mode passive\r\n!',
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ print(result["parsed"])
+ parsed_list = [
+ {
+ "links": {"max_active": 10, "min_active": 2},
+ "members": [
+ {"member": "GigabitEthernet0/0/0/0", "mode": "inherit"},
+ {"member": "GigabitEthernet0/0/0/1", "mode": "passive"},
+ ],
+ "mode": "active",
+ "name": "Bundle-Ether10",
+ },
+ {
+ "members": [
+ {"member": "GigabitEthernet0/0/0/8", "mode": "passive"},
+ {"member": "GigabitEthernet0/0/0/9", "mode": "passive"},
+ ],
+ "mode": "active",
+ "name": "Bundle-Ether11",
+ },
+ ]
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_lag_interfaces_overridden(self):
+ self.maxDiff = None
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="Bundle-Ether11",
+ mode="active",
+ members=[
+ dict(
+ member="GigabitEthernet0/0/0/0",
+ mode="active",
+ ),
+ dict(
+ member="GigabitEthernet0/0/0/1",
+ mode="active",
+ ),
+ ],
+ links=dict(max_active=10, min_active=5),
+ ),
+ ],
+ state="overridden",
+ ),
+ )
+ commands = [
+ "interface Bundle-Ether10",
+ "no bundle maximum-active links 10",
+ "no bundle minimum-active links 2",
+ "no lacp mode active",
+ "interface GigabitEthernet0/0/0/0",
+ "no bundle id",
+ "interface GigabitEthernet0/0/0/1",
+ "no bundle id",
+ "interface Bundle-Ether11",
+ "bundle minimum-active links 5",
+ "bundle maximum-active links 10",
+ "interface GigabitEthernet0/0/0/8",
+ "no bundle id",
+ "interface GigabitEthernet0/0/0/9",
+ "no bundle id",
+ "interface GigabitEthernet0/0/0/0",
+ "bundle id 11 mode active",
+ "interface GigabitEthernet0/0/0/1",
+ "bundle id 11 mode active",
+ ]
+
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lldp_global.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lldp_global.py
new file mode 100644
index 00000000..65f749ec
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lldp_global.py
@@ -0,0 +1,206 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_lldp_global
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrLldpModule(TestIosxrModule):
+ module = iosxr_lldp_global
+
+ def setUp(self):
+ super(TestIosxrLldpModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.lldp_global.lldp_global.Lldp_globalFacts.get_config",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrLldpModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def _prepare(self):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_lldp_global_config.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_lldp_global_merged_idempotent(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=dict(
+ holdtime=100,
+ reinit=2,
+ timer=3000,
+ subinterfaces=True,
+ tlv_select=dict(
+ management_address=False,
+ system_description=False,
+ ),
+ ),
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_lldp_global_merged(self):
+ set_module_args(
+ dict(
+ config=dict(
+ holdtime=100,
+ reinit=2,
+ timer=3000,
+ subinterfaces=True,
+ tlv_select=dict(
+ management_address=False,
+ system_description=False,
+ ),
+ ),
+ state="merged",
+ ),
+ )
+ commands = [
+ "lldp reinit 2",
+ "lldp holdtime 100",
+ "lldp timer 3000",
+ "lldp subinterfaces enable",
+ "lldp tlv-select system-description disable",
+ "lldp tlv-select management-address disable",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_lldp_global_replaced(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=dict(
+ holdtime=100,
+ tlv_select=dict(
+ management_address=False,
+ system_description=False,
+ port_description=False,
+ ),
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "no lldp reinit 2",
+ "no lldp subinterfaces enable",
+ "no lldp timer 3000",
+ "lldp tlv-select port-description disable",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_lldp_global_deleted(self):
+ self._prepare()
+ set_module_args(dict(state="deleted"))
+
+ commands = [
+ "no lldp holdtime 100",
+ "no lldp reinit 2",
+ "no lldp subinterfaces enable",
+ "no lldp timer 3000",
+ "no lldp tlv-select management-address disable",
+ "no lldp tlv-select system-description disable",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_lldp_global_rendered(self):
+ set_module_args(
+ dict(
+ config=dict(
+ holdtime=100,
+ reinit=2,
+ timer=3000,
+ subinterfaces=True,
+ tlv_select=dict(
+ management_address=False,
+ system_description=False,
+ ),
+ ),
+ state="rendered",
+ ),
+ )
+
+ commands = [
+ "lldp reinit 2",
+ "lldp holdtime 100",
+ "lldp timer 3000",
+ "lldp subinterfaces enable",
+ "lldp tlv-select system-description disable",
+ "lldp tlv-select management-address disable",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_lag_interfaces_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="lldp reinit 2\nlldp holdtime 100\nlldp timer 3000\nlldp subinterfaces\
+ enable\nlldp tlv-select system-description disable\nlldp tlv-select management-address\
+ disable\n",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "holdtime": 100,
+ "reinit": 2,
+ "timer": 3000,
+ "tlv_select": {"system_description": False},
+ }
+ self.assertEqual(parsed_list, result["parsed"])
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lldp_interfaces.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lldp_interfaces.py
new file mode 100644
index 00000000..78b6d79f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_lldp_interfaces.py
@@ -0,0 +1,206 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_lldp_interfaces
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrLldpInterfacesModule(TestIosxrModule):
+ module = iosxr_lldp_interfaces
+
+ def setUp(self):
+ super(TestIosxrLldpInterfacesModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.lldp_interfaces.lldp_interfaces.Lldp_interfacesFacts.get_config",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrLldpInterfacesModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def _prepare(self):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_lldp_interfaces_config.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_lldp_interfaces_merged_idempotent(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[
+ dict(name="GigabitEthernet0/0/0/0", transmit=False),
+ dict(name="GigabitEthernet0/0/0/1", receive=False),
+ ],
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_lldp_interfaces_merged(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(name="GigabitEthernet0/0/0/0", transmit=False),
+ dict(name="GigabitEthernet0/0/0/1", receive=False),
+ ],
+ state="merged",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "lldp transmit disable",
+ "interface GigabitEthernet0/0/0/1",
+ "lldp receive disable",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_lldp_interfaces_replaced(self):
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[dict(name="GigabitEthernet0/0/0/1", transmit=False)],
+ state="replaced",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/1",
+ "no lldp receive disable",
+ "no lldp destination mac-address ieee-nearest-non-tmpr-bridge",
+ "lldp transmit disable",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_lldp_interfaces_deleted(self):
+ self._prepare()
+ set_module_args(dict(state="deleted"))
+
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "no lldp transmit disable",
+ "no lldp destination mac-address ieee-nearest-bridge",
+ "interface GigabitEthernet0/0/0/1",
+ "no lldp destination mac-address ieee-nearest-non-tmpr-bridge",
+ "no lldp receive disable",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_lldp_interfaces_rendered(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(name="GigabitEthernet0/0/0/0", transmit=False),
+ dict(name="GigabitEthernet0/0/0/1", receive=False),
+ ],
+ state="rendered",
+ ),
+ )
+
+ commands = [
+ "interface GigabitEthernet0/0/0/0",
+ "lldp transmit disable",
+ "interface GigabitEthernet0/0/0/1",
+ "lldp receive disable",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_lldp_interfaces_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="interface TenGigE0/0/0/0\r\n ipv4 address 192.0.2.11 255.255.255.192\r\n!\r\ninterface preconfigure "
+ "GigabitEthernet0/0/0/0\r\n lldp\r\n transmit disable\r\n destination mac-address\r\n "
+ "ieee-nearest-bridge\r\n !\r\n !\r\n!\r\ninterface preconfigure GigabitEthernet0/0/0/1\r\n lldp\r\n "
+ "receive disable\r\n destination mac-address\r\n ieee-nearest-non-tmpr-bridge\r\n",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ print(result["parsed"])
+ parsed_list = [
+ {"name": "TenGigE0/0/0/0"},
+ {
+ "destination": {"mac_address": "ieee-nearest-bridge"},
+ "name": "GigabitEthernet0/0/0/0",
+ "transmit": False,
+ },
+ {
+ "destination": {"mac_address": "ieee-nearest-non-tmpr-bridge"},
+ "name": "GigabitEthernet0/0/0/1",
+ "receive": False,
+ },
+ ]
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_lldp_interfaces_overridden(self):
+ self.maxDiff = None
+ self._prepare()
+ set_module_args(
+ dict(
+ config=[dict(name="GigabitEthernet0/0/0/0", transmit=False)],
+ state="overridden",
+ ),
+ )
+ commands = [
+ "interface GigabitEthernet0/0/0/1",
+ "no lldp destination mac-address ieee-nearest-non-tmpr-bridge",
+ "no lldp receive disable",
+ "interface GigabitEthernet0/0/0/0",
+ "no lldp destination mac-address ieee-nearest-bridge",
+ ]
+
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_logging_global.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_logging_global.py
new file mode 100644
index 00000000..bffee2b1
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_logging_global.py
@@ -0,0 +1,1263 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from textwrap import dedent
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_logging_global
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule
+
+
+class TestIosxrLoggingGlobalModule(TestIosxrModule):
+ module = iosxr_logging_global
+
+ def setUp(self):
+ super(TestIosxrLoggingGlobalModule, self).setUp()
+
+ self.mock_get_resource_connection = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection = self.mock_get_resource_connection.start()
+
+ self.mock_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.logging_global.logging_global."
+ "Logging_globalFacts.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ def tearDown(self):
+ super(TestIosxrLoggingGlobalModule, self).tearDown()
+ self.get_resource_connection.stop()
+ self.get_config.stop()
+
+ def test_iosxr_logging_global_merged_idempotent(self):
+ run_cfg = dedent(
+ """\
+ logging tls-server test
+ vrf test
+ trustpoint test2
+ tls-hostname test2
+ !
+ logging file test path test maxfilesize 1024 severity info
+ logging file test2 path test1 maxfilesize 1024 severity debugging
+ logging ipv4 dscp af11
+ logging ipv6 precedence routine
+ logging trap informational
+ logging events filter
+ match test
+ match test1
+ !
+ logging events threshold 10
+ logging events buffer-size 1024
+ logging events display-location
+ logging events level warnings
+ logging format rfc5424
+ logging archive
+ device disk0
+ severity alerts
+ file-size 1
+ frequency daily
+ archive-size 1
+ archive-length 1
+ !
+ logging console warning
+ logging console discriminator
+ match1 test
+ nomatch1 test3
+ !
+ logging history size 10
+ logging monitor errors
+ logging monitor discriminator
+ match1 test1
+ !
+ logging buffered 2097152
+ logging buffered warnings
+ logging buffered discriminator
+ match2 test
+ !
+ logging 1.1.1.1 vrf default severity critical port default
+ logging correlator rule test type stateful
+ reissue-nonbistate
+ timeout 5
+ reparent
+ context-correlation
+ !
+ logging correlator rule test1 type nonstateful
+ timeout 6
+ context-correlation
+ !
+ logging correlator ruleset test
+ rulename test
+ rulename test1
+ !
+ logging correlator buffer-size 1024
+ logging localfilesize 1024
+ logging source-interface GigabitEthernet0/0/0/0 vrf test
+ logging hostnameprefix test
+ logging suppress duplicates
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ archive=dict(
+ archive_length=1,
+ archive_size=1,
+ device="disk0",
+ file_size=1,
+ frequency="daily",
+ severity="alerts",
+ ),
+ buffered=dict(
+ size=2097152,
+ severity="warnings",
+ discriminator=[
+ dict(match_params="match2", name="test"),
+ ],
+ ),
+ console=dict(
+ severity="warning",
+ discriminator=[
+ dict(match_params="match1", name="test"),
+ dict(match_params="nomatch1", name="test3"),
+ ],
+ ),
+ correlator=dict(
+ buffer_size=1024,
+ rule_sets=[
+ dict(name="test", rulename=["test1", "test"]),
+ ],
+ rules=[
+ dict(
+ rule_name="test",
+ rule_type="stateful",
+ timeout=5,
+ context_correlation=True,
+ reissue_nonbistate=True,
+ reparent=True,
+ ),
+ dict(
+ rule_name="test1",
+ rule_type="nonstateful",
+ timeout=6,
+ context_correlation=True,
+ ),
+ ],
+ ),
+ events=dict(
+ severity="warnings",
+ display_location=True,
+ buffer_size=1024,
+ filter_match=["test1", "test"],
+ threshold=10,
+ ),
+ format=True,
+ files=[
+ dict(
+ maxfilesize=1024,
+ name="test",
+ path="test",
+ severity="info",
+ ),
+ dict(
+ maxfilesize=1024,
+ name="test2",
+ path="test1",
+ severity="debugging",
+ ),
+ ],
+ history=dict(size=10),
+ hostnameprefix="test",
+ hosts=[
+ dict(
+ host="1.1.1.1",
+ port="default",
+ severity="critical",
+ vrf="default",
+ ),
+ ],
+ ipv6=dict(precedence="routine"),
+ ipv4=dict(dscp="af11"),
+ localfilesize=1024,
+ monitor=dict(
+ severity="errors",
+ discriminator=[
+ dict(match_params="match1", name="test1"),
+ ],
+ ),
+ source_interfaces=[
+ dict(interface="GigabitEthernet0/0/0/0", vrf="test"),
+ ],
+ suppress=dict(duplicates=True),
+ tls_servers=[
+ dict(
+ name="test",
+ tls_hostname="test2",
+ trustpoint="test2",
+ vrf="test",
+ ),
+ ],
+ trap=dict(severity="informational"),
+ ),
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_logging_global_merged(self):
+ set_module_args(
+ dict(
+ config=dict(
+ archive=dict(
+ archive_length=1,
+ archive_size=1,
+ device="disk0",
+ file_size=1,
+ frequency="daily",
+ severity="alerts",
+ ),
+ buffered=dict(
+ size=2097152,
+ severity="warnings",
+ discriminator=[
+ dict(match_params="match2", name="test"),
+ ],
+ ),
+ console=dict(
+ severity="warning",
+ discriminator=[
+ dict(match_params="match1", name="test"),
+ dict(match_params="nomatch1", name="test3"),
+ ],
+ ),
+ correlator=dict(
+ buffer_size=1024,
+ rule_sets=[
+ dict(name="test", rulename=["test1", "test"]),
+ ],
+ rules=[
+ dict(
+ rule_name="test",
+ rule_type="stateful",
+ timeout=5,
+ context_correlation=True,
+ reissue_nonbistate=True,
+ reparent=True,
+ ),
+ dict(
+ rule_name="test1",
+ rule_type="nonstateful",
+ timeout=6,
+ context_correlation=True,
+ ),
+ ],
+ ),
+ events=dict(
+ severity="warnings",
+ display_location=True,
+ buffer_size=1024,
+ filter_match=["test1", "test"],
+ threshold=10,
+ ),
+ format=True,
+ files=[
+ dict(
+ maxfilesize=1024,
+ name="test",
+ path="test",
+ severity="info",
+ ),
+ dict(
+ maxfilesize=1024,
+ name="test2",
+ path="test1",
+ severity="debugging",
+ ),
+ ],
+ history=dict(state="disabled", size=10),
+ hostnameprefix="test",
+ hosts=[
+ dict(
+ host="1.1.1.1",
+ port="default",
+ severity="critical",
+ vrf="default",
+ ),
+ ],
+ ipv6=dict(precedence="routine"),
+ ipv4=dict(dscp="af11"),
+ localfilesize=1024,
+ monitor=dict(
+ severity="errors",
+ discriminator=[
+ dict(match_params="match1", name="test1"),
+ ],
+ ),
+ source_interfaces=[
+ dict(interface="GigabitEthernet0/0/0/0", vrf="test"),
+ ],
+ suppress=dict(duplicates=True),
+ tls_servers=[
+ dict(
+ name="test",
+ tls_hostname="test2",
+ trustpoint="test2",
+ vrf="test",
+ ),
+ ],
+ trap=dict(severity="informational"),
+ ),
+ state="merged",
+ ),
+ )
+ commands = [
+ "logging archive device disk0",
+ "logging archive frequency daily",
+ "logging archive severity alerts",
+ "logging archive archive-size 1",
+ "logging archive archive-length 1",
+ "logging archive file-size 1",
+ "logging buffered 2097152",
+ "logging buffered warnings",
+ "logging console warning",
+ "logging correlator buffer-size 1024",
+ "logging events threshold 10",
+ "logging events buffer-size 1024",
+ "logging events display-location",
+ "logging events level warnings",
+ "logging hostnameprefix test",
+ "logging format rfc5424",
+ "logging ipv4 dscp af11",
+ "logging ipv6 precedence routine",
+ "logging localfilesize 1024",
+ "logging suppress duplicates",
+ "logging monitor errors",
+ "logging history size 10",
+ "logging history disable",
+ "logging trap informational",
+ "logging 1.1.1.1 vrf default severity critical port default",
+ "logging file test path test maxfilesize 1024 severity info",
+ "logging file test2 path test1 maxfilesize 1024 severity debugging",
+ "logging source-interface GigabitEthernet0/0/0/0 vrf test",
+ "logging tls-server test tls-hostname test2",
+ "logging tls-server test trustpoint test2",
+ "logging tls-server test vrf test",
+ "logging correlator ruleset test rulename test1",
+ "logging correlator ruleset test rulename test",
+ "logging correlator rule test type stateful timeout 5",
+ "logging correlator rule test type stateful reissue-nonbistate",
+ "logging correlator rule test type stateful reparent",
+ "logging correlator rule test type stateful context-correlation",
+ "logging correlator rule test1 type nonstateful timeout 6",
+ "logging correlator rule test1 type nonstateful context-correlation",
+ "logging events filter match test1",
+ "logging events filter match test",
+ "logging buffered discriminator match2 test",
+ "logging monitor discriminator match1 test1",
+ "logging console discriminator match1 test",
+ "logging console discriminator nomatch1 test3",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_logging_global_deleted(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ logging tls-server test
+ vrf test
+ trustpoint test2
+ tls-hostname test2
+ !
+ logging file test path test maxfilesize 1024 severity info
+ logging file test2 path test1 maxfilesize 1024 severity debugging
+ logging ipv4 dscp af11
+ logging ipv6 precedence routine
+ logging trap informational
+ logging events filter
+ match test
+ match test1
+ !
+ logging events threshold 10
+ logging events buffer-size 1024
+ logging events display-location
+ logging events level warnings
+ logging format rfc5424
+ logging archive
+ device disk0
+ severity alerts
+ file-size 1
+ frequency daily
+ archive-size 1
+ archive-length 1
+ !
+ logging console warning
+ logging console discriminator
+ match1 test
+ nomatch1 test3
+ !
+ logging history size 10
+ logging history disable
+ logging monitor errors
+ logging monitor discriminator
+ match1 test1
+ !
+ logging buffered 2097152
+ logging buffered warnings
+ logging buffered discriminator
+ match2 test
+ !
+ logging 1.1.1.1 vrf default severity critical port default
+ logging correlator rule test type stateful
+ reissue-nonbistate
+ timeout 5
+ reparent
+ context-correlation
+ !
+ logging correlator rule test1 type nonstateful
+ timeout 6
+ context-correlation
+ !
+ logging correlator ruleset test
+ rulename test
+ rulename test1
+ !
+ logging correlator buffer-size 1024
+ logging localfilesize 1024
+ logging source-interface GigabitEthernet0/0/0/0 vrf test
+ logging hostnameprefix test
+ logging suppress duplicates
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(state="deleted"))
+ commands = [
+ "no logging archive device disk0",
+ "no logging archive frequency daily",
+ "no logging archive severity alerts",
+ "no logging archive archive-size 1",
+ "no logging archive archive-length 1",
+ "no logging archive file-size 1",
+ "no logging buffered 2097152",
+ "no logging buffered warnings",
+ "no logging console warning",
+ "no logging correlator buffer-size 1024",
+ "no logging events threshold 10",
+ "no logging events buffer-size 1024",
+ "no logging events display-location",
+ "no logging events level warnings",
+ "no logging hostnameprefix test",
+ "no logging format rfc5424",
+ "no logging ipv4 dscp af11",
+ "no logging ipv6 precedence routine",
+ "no logging localfilesize 1024",
+ "no logging suppress duplicates",
+ "no logging monitor errors",
+ "no logging history size 10",
+ "no logging history disable",
+ "no logging trap informational",
+ "no logging 1.1.1.1 vrf default severity critical port default",
+ "no logging file test path test maxfilesize 1024 severity info",
+ "no logging file test2 path test1 maxfilesize 1024 severity debugging",
+ "no logging source-interface GigabitEthernet0/0/0/0 vrf test",
+ "no logging tls-server test",
+ "no logging correlator ruleset test rulename test",
+ "no logging correlator ruleset test rulename test1",
+ "no logging correlator rule test type stateful timeout 5",
+ "no logging correlator rule test type stateful reissue-nonbistate",
+ "no logging correlator rule test type stateful reparent",
+ "no logging correlator rule test type stateful context-correlation",
+ "no logging correlator rule test1 type nonstateful timeout 6",
+ "no logging correlator rule test1 type nonstateful context-correlation",
+ "no logging events filter match test",
+ "no logging events filter match test1",
+ "no logging buffered discriminator match2 test",
+ "no logging monitor discriminator match1 test1",
+ "no logging console discriminator match1 test",
+ "no logging console discriminator nomatch1 test3",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_logging_global_replaced(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ logging tls-server test
+ vrf test
+ trustpoint test2
+ tls-hostname test2
+ !
+ logging file test path test maxfilesize 1024 severity info
+ logging file test2 path test1 maxfilesize 1024 severity debugging
+ logging ipv4 dscp af11
+ logging ipv6 precedence routine
+ logging trap informational
+ logging events filter
+ match test
+ match test1
+ !
+ logging events threshold 10
+ logging events buffer-size 1024
+ logging events display-location
+ logging events level warnings
+ logging format rfc5424
+ logging archive
+ device disk0
+ severity alerts
+ file-size 1
+ frequency daily
+ archive-size 1
+ archive-length 1
+ !
+ logging console warning
+ logging console discriminator
+ match1 test
+ nomatch1 test3
+ !
+ logging history size 10
+ logging history disable
+ logging monitor errors
+ logging monitor discriminator
+ match1 test1
+ !
+ logging buffered 2097152
+ logging buffered warnings
+ logging buffered discriminator
+ match2 test
+ !
+ logging 1.1.1.1 vrf default severity critical port default
+ logging correlator rule test type stateful
+ reissue-nonbistate
+ timeout 5
+ reparent
+ context-correlation
+ !
+ logging correlator rule test1 type nonstateful
+ timeout 6
+ context-correlation
+ !
+ logging correlator ruleset test
+ rulename test
+ rulename test1
+ !
+ logging correlator buffer-size 1024
+ logging localfilesize 1024
+ logging source-interface GigabitEthernet0/0/0/0 vrf test
+ logging hostnameprefix test
+ logging suppress duplicates
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ archive=dict(
+ archive_length=1,
+ archive_size=1,
+ device="disk0",
+ file_size=1,
+ severity="alerts",
+ ),
+ buffered=dict(size=2097152, severity="warnings"),
+ console=dict(
+ severity="warning",
+ discriminator=[
+ dict(match_params="match1", name="test1"),
+ ],
+ ),
+ correlator=dict(
+ buffer_size=1024,
+ rules=[
+ dict(
+ rule_name="test",
+ rule_type="stateful",
+ timeout=6,
+ context_correlation=True,
+ reissue_nonbistate=True,
+ reparent=True,
+ ),
+ ],
+ ),
+ events=dict(
+ severity="warnings",
+ display_location=True,
+ buffer_size=1024,
+ filter_match=["test1"],
+ threshold=12,
+ ),
+ format=True,
+ files=[
+ dict(
+ maxfilesize=1024,
+ name="test",
+ path="test1",
+ severity="info",
+ ),
+ ],
+ history=dict(state="disabled", size=10),
+ hostnameprefix="test",
+ hosts=[
+ dict(
+ host="1.1.1.2",
+ port="default",
+ severity="critical",
+ vrf="default",
+ ),
+ ],
+ ipv6=dict(precedence="routine"),
+ ipv4=dict(dscp="af11"),
+ localfilesize=1024,
+ source_interfaces=[
+ dict(interface="GigabitEthernet0/0/0/0", vrf="test"),
+ ],
+ tls_servers=[
+ dict(
+ name="test",
+ tls_hostname="test2",
+ trustpoint="test3",
+ vrf="test",
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "logging console discriminator match1 test1",
+ "logging correlator rule test type stateful timeout 6",
+ "logging events threshold 12",
+ "logging 1.1.1.2 vrf default severity critical port default",
+ "logging file test path test1 maxfilesize 1024 severity info",
+ "logging tls-server test trustpoint test3",
+ "no logging 1.1.1.1 vrf default severity critical port default",
+ "no logging archive frequency daily",
+ "no logging buffered discriminator match2 test",
+ "no logging console discriminator match1 test",
+ "no logging console discriminator nomatch1 test3",
+ "no logging correlator rule test1 type nonstateful context-correlation",
+ "no logging correlator rule test1 type nonstateful timeout 6",
+ "no logging correlator ruleset test rulename test",
+ "no logging correlator ruleset test rulename test1",
+ "no logging events filter match test",
+ "no logging file test2 path test1 maxfilesize 1024 severity debugging",
+ "no logging monitor discriminator match1 test1",
+ "no logging monitor errors",
+ "no logging suppress duplicates",
+ "no logging trap informational",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_logging_global_rendered(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ config=dict(
+ archive=dict(
+ archive_length=1,
+ archive_size=1,
+ device="disk0",
+ file_size=1,
+ frequency="daily",
+ severity="alerts",
+ ),
+ buffered=dict(
+ size=2097152,
+ severity="warnings",
+ discriminator=[
+ dict(match_params="match2", name="test"),
+ ],
+ ),
+ console=dict(
+ severity="warning",
+ discriminator=[
+ dict(match_params="match1", name="test"),
+ dict(match_params="nomatch1", name="test3"),
+ ],
+ ),
+ correlator=dict(
+ buffer_size=1024,
+ rule_sets=[
+ dict(name="test", rulename=["test1", "test"]),
+ ],
+ rules=[
+ dict(
+ rule_name="test",
+ rule_type="stateful",
+ timeout=5,
+ context_correlation=True,
+ reissue_nonbistate=True,
+ reparent=True,
+ ),
+ dict(
+ rule_name="test1",
+ rule_type="nonstateful",
+ timeout=6,
+ context_correlation=True,
+ ),
+ ],
+ ),
+ events=dict(
+ severity="warnings",
+ display_location=True,
+ buffer_size=1024,
+ filter_match=["test1", "test"],
+ threshold=10,
+ ),
+ format=True,
+ files=[
+ dict(
+ maxfilesize=1024,
+ name="test",
+ path="test",
+ severity="info",
+ ),
+ dict(
+ maxfilesize=1024,
+ name="test2",
+ path="test1",
+ severity="debugging",
+ ),
+ ],
+ history=dict(state="disabled", size=10),
+ hostnameprefix="test",
+ hosts=[
+ dict(
+ host="1.1.1.1",
+ port="default",
+ severity="critical",
+ vrf="default",
+ ),
+ ],
+ ipv6=dict(precedence="routine"),
+ ipv4=dict(dscp="af11"),
+ localfilesize=1024,
+ monitor=dict(
+ severity="errors",
+ discriminator=[
+ dict(match_params="match1", name="test1"),
+ ],
+ ),
+ source_interfaces=[
+ dict(interface="GigabitEthernet0/0/0/0", vrf="test"),
+ ],
+ suppress=dict(duplicates=True),
+ tls_servers=[
+ dict(
+ name="test",
+ tls_hostname="test2",
+ trustpoint="test2",
+ vrf="test",
+ ),
+ ],
+ trap=dict(severity="informational"),
+ ),
+ state="rendered",
+ ),
+ )
+ commands = [
+ "logging archive device disk0",
+ "logging archive frequency daily",
+ "logging archive severity alerts",
+ "logging archive archive-size 1",
+ "logging archive archive-length 1",
+ "logging archive file-size 1",
+ "logging buffered 2097152",
+ "logging buffered warnings",
+ "logging console warning",
+ "logging correlator buffer-size 1024",
+ "logging events threshold 10",
+ "logging events buffer-size 1024",
+ "logging events display-location",
+ "logging events level warnings",
+ "logging hostnameprefix test",
+ "logging format rfc5424",
+ "logging ipv4 dscp af11",
+ "logging ipv6 precedence routine",
+ "logging localfilesize 1024",
+ "logging suppress duplicates",
+ "logging monitor errors",
+ "logging history size 10",
+ "logging history disable",
+ "logging trap informational",
+ "logging 1.1.1.1 vrf default severity critical port default",
+ "logging file test path test maxfilesize 1024 severity info",
+ "logging file test2 path test1 maxfilesize 1024 severity debugging",
+ "logging source-interface GigabitEthernet0/0/0/0 vrf test",
+ "logging tls-server test tls-hostname test2",
+ "logging tls-server test trustpoint test2",
+ "logging tls-server test vrf test",
+ "logging correlator ruleset test rulename test1",
+ "logging correlator ruleset test rulename test",
+ "logging correlator rule test type stateful timeout 5",
+ "logging correlator rule test type stateful reissue-nonbistate",
+ "logging correlator rule test type stateful reparent",
+ "logging correlator rule test type stateful context-correlation",
+ "logging correlator rule test1 type nonstateful timeout 6",
+ "logging correlator rule test1 type nonstateful context-correlation",
+ "logging events filter match test1",
+ "logging events filter match test",
+ "logging buffered discriminator match2 test",
+ "logging monitor discriminator match1 test1",
+ "logging console discriminator match1 test",
+ "logging console discriminator nomatch1 test3",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_logging_global_overridden(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ logging tls-server test
+ vrf test
+ trustpoint test2
+ tls-hostname test2
+ !
+ logging file test path test maxfilesize 1024 severity info
+ logging file test2 path test1 maxfilesize 1024 severity debugging
+ logging ipv4 dscp af11
+ logging ipv6 precedence routine
+ logging trap informational
+ logging events filter
+ match test
+ match test1
+ !
+ logging events threshold 10
+ logging events buffer-size 1024
+ logging events display-location
+ logging events level warnings
+ logging format rfc5424
+ logging archive
+ device disk0
+ severity alerts
+ file-size 1
+ frequency daily
+ archive-size 1
+ archive-length 1
+ !
+ logging console warning
+ logging console discriminator
+ match1 test
+ nomatch1 test3
+ !
+ logging history size 10
+ logging history disable
+ logging monitor errors
+ logging monitor discriminator
+ match1 test1
+ !
+ logging buffered 2097152
+ logging buffered warnings
+ logging buffered discriminator
+ match2 test
+ !
+ logging 1.1.1.1 vrf default severity critical port default
+ logging correlator rule test type stateful
+ reissue-nonbistate
+ timeout 5
+ reparent
+ context-correlation
+ !
+ logging correlator rule test1 type nonstateful
+ timeout 6
+ context-correlation
+ !
+ logging correlator ruleset test
+ rulename test
+ rulename test1
+ !
+ logging correlator buffer-size 1024
+ logging localfilesize 1024
+ logging source-interface GigabitEthernet0/0/0/0 vrf test
+ logging hostnameprefix test
+ logging suppress duplicates
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ archive=dict(
+ archive_length=1,
+ archive_size=1,
+ device="disk0",
+ file_size=1,
+ severity="alerts",
+ ),
+ buffered=dict(size=2097152, severity="warnings"),
+ console=dict(
+ severity="warning",
+ discriminator=[
+ dict(match_params="match1", name="test1"),
+ ],
+ ),
+ correlator=dict(
+ buffer_size=1024,
+ rules=[
+ dict(
+ rule_name="test",
+ rule_type="stateful",
+ timeout=6,
+ context_correlation=True,
+ reissue_nonbistate=True,
+ reparent=True,
+ ),
+ ],
+ ),
+ events=dict(
+ severity="warnings",
+ display_location=True,
+ buffer_size=1024,
+ filter_match=["test1"],
+ threshold=12,
+ ),
+ format=True,
+ files=[
+ dict(
+ maxfilesize=1024,
+ name="test",
+ path="test1",
+ severity="info",
+ ),
+ ],
+ history=dict(state="disabled", size=10),
+ hostnameprefix="test",
+ hosts=[
+ dict(
+ host="1.1.1.2",
+ port="default",
+ severity="critical",
+ vrf="default",
+ ),
+ ],
+ ipv6=dict(precedence="routine"),
+ ipv4=dict(dscp="af11"),
+ localfilesize=1024,
+ source_interfaces=[
+ dict(interface="GigabitEthernet0/0/0/0", vrf="test"),
+ ],
+ tls_servers=[
+ dict(
+ name="test",
+ tls_hostname="test2",
+ trustpoint="test3",
+ vrf="test",
+ ),
+ ],
+ ),
+ state="overridden",
+ ),
+ )
+ commands = [
+ "logging console discriminator match1 test1",
+ "logging correlator rule test type stateful timeout 6",
+ "logging events threshold 12",
+ "logging 1.1.1.2 vrf default severity critical port default",
+ "logging file test path test1 maxfilesize 1024 severity info",
+ "logging tls-server test trustpoint test3",
+ "no logging 1.1.1.1 vrf default severity critical port default",
+ "no logging archive frequency daily",
+ "no logging buffered discriminator match2 test",
+ "no logging console discriminator match1 test",
+ "no logging console discriminator nomatch1 test3",
+ "no logging correlator rule test1 type nonstateful context-correlation",
+ "no logging correlator rule test1 type nonstateful timeout 6",
+ "no logging correlator ruleset test rulename test",
+ "no logging correlator ruleset test rulename test1",
+ "no logging events filter match test",
+ "no logging file test2 path test1 maxfilesize 1024 severity debugging",
+ "no logging monitor discriminator match1 test1",
+ "no logging monitor errors",
+ "no logging suppress duplicates",
+ "no logging trap informational",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_logging_global_gathered(self):
+ run_cfg = dedent(
+ """\
+ logging tls-server test
+ vrf test
+ trustpoint test2
+ tls-hostname test2
+ !
+ logging file test path test maxfilesize 1024 severity info
+ logging ipv4 dscp af11
+ logging ipv6 precedence routine
+ logging trap informational
+ logging events filter
+ match test
+ !
+ logging events threshold 10
+ logging events buffer-size 1024
+ logging events display-location
+ logging events level warnings
+ logging format rfc5424
+ logging archive
+ device disk0
+ severity alerts
+ file-size 1
+ frequency daily
+ archive-size 1
+ archive-length 1
+ !
+ logging console warning
+ logging console discriminator
+ match1 test
+ !
+ logging history size 10
+ logging history disable
+ logging monitor errors
+ logging monitor discriminator
+ match1 test1
+ !
+ logging buffered 2097152
+ logging buffered warnings
+ logging buffered discriminator
+ match2 test
+ !
+ logging 1.1.1.1 vrf default severity critical port default
+ logging correlator rule test type stateful
+ reissue-nonbistate
+ timeout 5
+ reparent
+ context-correlation
+ !
+ logging correlator ruleset test
+ rulename test
+ !
+ logging correlator buffer-size 1024
+ logging localfilesize 1024
+ logging source-interface GigabitEthernet0/0/0/0 vrf test
+ logging hostnameprefix test
+ logging suppress duplicates
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(state="gathered"))
+ gathered = {
+ "archive": {
+ "archive_length": 1,
+ "archive_size": 1,
+ "device": "disk0",
+ "file_size": 1,
+ "frequency": "daily",
+ "severity": "alerts",
+ },
+ "buffered": {
+ "discriminator": [{"match_params": "match2", "name": "test"}],
+ "severity": "warnings",
+ "size": 2097152,
+ },
+ "console": {
+ "discriminator": [{"match_params": "match1", "name": "test"}],
+ "severity": "warning",
+ },
+ "correlator": {
+ "buffer_size": 1024,
+ "rule_sets": [{"name": "test", "rulename": ["test"]}],
+ "rules": [
+ {
+ "context_correlation": True,
+ "reissue_nonbistate": True,
+ "reparent": True,
+ "rule_name": "test",
+ "rule_type": "stateful",
+ "timeout": 5,
+ },
+ ],
+ },
+ "events": {
+ "buffer_size": 1024,
+ "display_location": True,
+ "filter_match": ["test"],
+ "severity": "warnings",
+ "threshold": 10,
+ },
+ "files": [
+ {
+ "maxfilesize": 1024,
+ "name": "test",
+ "path": "test",
+ "severity": "info",
+ },
+ ],
+ "format": True,
+ "history": {"state": "disabled", "size": 10},
+ "hostnameprefix": "test",
+ "hosts": [
+ {
+ "host": "1.1.1.1",
+ "port": "default",
+ "severity": "critical",
+ "vrf": "default",
+ },
+ ],
+ "ipv4": {"dscp": "af11"},
+ "ipv6": {"precedence": "routine"},
+ "localfilesize": 1024,
+ "monitor": {
+ "discriminator": [{"match_params": "match1", "name": "test1"}],
+ "severity": "errors",
+ },
+ "source_interfaces": [
+ {"interface": "GigabitEthernet0/0/0/0", "vrf": "test"},
+ ],
+ "suppress": {"duplicates": True},
+ "tls_servers": [
+ {
+ "name": "test",
+ "tls_hostname": "test2",
+ "trustpoint": "test2",
+ "vrf": "test",
+ },
+ ],
+ "trap": {"severity": "informational"},
+ }
+ result = self.execute_module(changed=False)
+ self.assertEqual(gathered, result["gathered"])
+
+ def test_iosxr_logging_global_parsed(self):
+ set_module_args(
+ dict(
+ running_config="logging tls-server test\n vrf test\n trustpoint test2\n tls-hostname test2"
+ "\n!\nlogging file test path test maxfilesize 1024 severity info\nlogging ipv4 dscp"
+ " af11\nlogging ipv6 precedence routine\nlogging trap informational\nlogging events"
+ " filter\n match test1\n!\nlogging events threshold "
+ "10\nlogging events buffer-size 1024\nlogging events display-location"
+ "\nlogging events level warnings"
+ "\nlogging format rfc5424\nlogging archive\n device disk0"
+ "\n severity alerts\n file-size 1\n frequency "
+ "daily\n archive-size 1\n archive-length 1\n!\nlogging console "
+ "warning\nlogging console discriminator\n "
+ "match1 test\n!\nlogging history size "
+ "10\nlogging history disable\nlogging monitor errors"
+ "\nlogging monitor discriminator\n match1 test1\n!"
+ "\nlogging buffered 2097152\nlogging buffered warnings\n"
+ "logging buffered discriminator\n match2 test\n!\nlogging "
+ "1.1.1.1 vrf default severity critical port default"
+ "\nlogging correlator rule test type stateful\n reissue-nonbistate\n "
+ "timeout 5\n reparent\n context-correlation\n!"
+ "\n!\nlogging correlator ruleset test\n rulename test1"
+ "\n!\nlogging correlator buffer-size 1024\nlogging "
+ "localfilesize 1024\nlogging source-interface"
+ " GigabitEthernet0/0/0/0 vrf test\nlogging hostnameprefix "
+ "test\nlogging suppress duplicates",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "archive": {
+ "archive_length": 1,
+ "archive_size": 1,
+ "device": "disk0",
+ "file_size": 1,
+ "frequency": "daily",
+ "severity": "alerts",
+ },
+ "buffered": {
+ "discriminator": [{"match_params": "match2", "name": "test"}],
+ "severity": "warnings",
+ "size": 2097152,
+ },
+ "console": {
+ "discriminator": [{"match_params": "match1", "name": "test"}],
+ "severity": "warning",
+ },
+ "correlator": {
+ "buffer_size": 1024,
+ "rule_sets": [{"name": "test", "rulename": ["test1"]}],
+ "rules": [
+ {
+ "context_correlation": True,
+ "reissue_nonbistate": True,
+ "reparent": True,
+ "rule_name": "test",
+ "rule_type": "stateful",
+ "timeout": 5,
+ },
+ ],
+ },
+ "events": {
+ "buffer_size": 1024,
+ "display_location": True,
+ "filter_match": ["test1"],
+ "severity": "warnings",
+ "threshold": 10,
+ },
+ "files": [
+ {
+ "maxfilesize": 1024,
+ "name": "test",
+ "path": "test",
+ "severity": "info",
+ },
+ ],
+ "format": True,
+ "history": {"state": "disabled", "size": 10},
+ "hostnameprefix": "test",
+ "hosts": [
+ {
+ "host": "1.1.1.1",
+ "port": "default",
+ "severity": "critical",
+ "vrf": "default",
+ },
+ ],
+ "ipv4": {"dscp": "af11"},
+ "ipv6": {"precedence": "routine"},
+ "localfilesize": 1024,
+ "monitor": {
+ "discriminator": [{"match_params": "match1", "name": "test1"}],
+ "severity": "errors",
+ },
+ "source_interfaces": [
+ {"interface": "GigabitEthernet0/0/0/0", "vrf": "test"},
+ ],
+ "suppress": {"duplicates": True},
+ "tls_servers": [
+ {
+ "name": "test",
+ "tls_hostname": "test2",
+ "trustpoint": "test2",
+ "vrf": "test",
+ },
+ ],
+ "trap": {"severity": "informational"},
+ }
+
+ self.assertEqual(parsed_list, result["parsed"])
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_n540.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_n540.py
new file mode 100644
index 00000000..d2820cfa
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_n540.py
@@ -0,0 +1,96 @@
+#
+# (c) 2022 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 os import path
+
+from ansible.module_utils._text import to_bytes, to_text
+from mock import MagicMock
+
+from ansible_collections.cisco.iosxr.plugins.cliconf import iosxr
+from ansible_collections.cisco.iosxr.tests.unit.compat import unittest
+
+
+class TestPluginCLIConfIOSXR(unittest.TestCase):
+ """Test class for IOSXR CLI Conf Methods"""
+
+ def setUp(self):
+ self._mock_connection = MagicMock()
+ self._prepare()
+ self._cliconf = iosxr.Cliconf(self._mock_connection)
+ self.maxDiff = None
+
+ def _prepare(self, platform="iosxr"):
+ b_FIXTURE_DIR = b"%s/fixtures/cliconf_ncs540/%s" % (
+ to_bytes(
+ path.dirname(path.abspath(__file__)),
+ errors="surrogate_or_strict",
+ ),
+ to_bytes(platform),
+ )
+
+ def _connection_side_effect(*args, **kwargs):
+ try:
+ if args:
+ value = args[0]
+ else:
+ value = kwargs.get("command")
+ if b"|" in value:
+ value = value.replace(b"|", b"")
+ fixture_path = path.abspath(
+ b"%s/%s" % (b_FIXTURE_DIR, b"_".join(value.split(b" "))),
+ )
+ with open(fixture_path, "rb") as file_desc:
+ return to_text(file_desc.read())
+ except (OSError, IOError):
+ if args:
+ value = args[0]
+ return value
+ elif kwargs.get("command"):
+ value = kwargs.get("command")
+ return value
+ return "NO-OP"
+
+ self._mock_connection.send.side_effect = _connection_side_effect
+
+ def tearDown(self):
+ pass
+
+ def test_get_device_info_iosxr(self):
+ """Test get_device_info for nxos"""
+ device_info = self._cliconf.get_device_info()
+
+ mock_device_info = {
+ "network_os_version": "7.5.2 LNT",
+ "network_os": "iosxr",
+ "network_os_hostname": "iosxr01",
+ "network_os_model": "N540X-6Z18G-SYS-A",
+ }
+
+ self.assertEqual(device_info, mock_device_info)
+
+ def test_get_command_output_iosxr(self):
+ """Test _get_command_with_output for iosxr"""
+ self._prepare()
+ cmd = self._cliconf.get_command_output("show running-config hostname")
+
+ self.assertEqual(cmd, "hostname iosxr01")
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_netconf.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_netconf.py
new file mode 100644
index 00000000..bbd61050
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_netconf.py
@@ -0,0 +1,115 @@
+# (c) 2017 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_netconf
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule
+
+
+class TestIosxrNetconfModule(TestIosxrModule):
+
+ module = iosxr_netconf
+
+ def setUp(self):
+ super(TestIosxrNetconfModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_netconf.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_netconf.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ def tearDown(self):
+ super(TestIosxrNetconfModule, self).tearDown()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+
+ def test_iosxr_disable_netconf_service(self):
+ self.get_config.return_value = """
+ netconf-yang agent
+ ssh
+ !
+ ssh server netconf vrf default
+ """
+ self.load_config.return_value = "dummy diff"
+ set_module_args(
+ dict(netconf_port=830, netconf_vrf="default", state="absent"),
+ )
+ result = self.execute_module(changed=True)
+ self.assertEqual(
+ result["commands"],
+ [
+ "no netconf-yang agent ssh",
+ "no ssh server netconf port 830",
+ "no ssh server netconf vrf default",
+ ],
+ )
+
+ def test_iosxr_enable_netconf_service(self):
+ self.get_config.return_value = ""
+ self.load_config.return_value = "dummy diff"
+ set_module_args(
+ dict(netconf_port=830, netconf_vrf="default", state="present"),
+ )
+ result = self.execute_module(changed=True)
+ self.assertEqual(
+ result["commands"],
+ [
+ "netconf-yang agent ssh",
+ "ssh server netconf port 830",
+ "ssh server netconf vrf default",
+ ],
+ )
+
+ def test_iosxr_change_netconf_port(self):
+ self.get_config.return_value = """
+ netconf-yang agent
+ ssh
+ !
+ ssh server netconf vrf default
+ """
+ self.load_config.return_value = "dummy diff"
+ set_module_args(dict(netconf_port=9000, state="present"))
+ result = self.execute_module(changed=True)
+ self.assertEqual(result["commands"], ["ssh server netconf port 9000"])
+
+ def test_iosxr_change_netconf_vrf(self):
+ self.get_config.return_value = """
+ netconf-yang agent
+ ssh
+ !
+ ssh server netconf vrf default
+ """
+ self.load_config.return_value = "dummy diff"
+ set_module_args(dict(netconf_vrf="new_default", state="present"))
+ result = self.execute_module(changed=True)
+ self.assertEqual(
+ result["commands"],
+ ["ssh server netconf vrf new_default"],
+ )
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ntp_global.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ntp_global.py
new file mode 100644
index 00000000..702e2a00
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ntp_global.py
@@ -0,0 +1,902 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from textwrap import dedent
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_ntp_global
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule
+
+
+class TestIosxrNtpGlobalModule(TestIosxrModule):
+ module = iosxr_ntp_global
+
+ def setUp(self):
+ super(TestIosxrNtpGlobalModule, self).setUp()
+
+ self.mock_get_resource_connection = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection = self.mock_get_resource_connection.start()
+
+ self.mock_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.ntp_global.ntp_global."
+ "Ntp_globalFacts.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ def tearDown(self):
+ super(TestIosxrNtpGlobalModule, self).tearDown()
+ self.get_resource_connection.stop()
+ self.get_config.stop()
+
+ def test_iosxr_ntp_global_merged_idempotent(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ ntp
+ max-associations 10
+ interface GigabitEthernet0/0/0/0 vrf siteB
+ multicast key 1
+ !
+ interface GigabitEthernet0/0/0/0
+ broadcast client
+ multicast client 224.0.0.8
+ multicast destination 224.0.0.8
+ !
+ authentication-key 1 md5 encrypted testkey
+ authentication-key 2 md5 encrypted 071B245F5A5B
+ authenticate
+ trusted-key 1
+ trusted-key 2
+ ipv4 dscp af11
+ ipv6 precedence routine
+ peer vrf siteC 192.0.2.1 iburst
+ server vrf siteD 192.0.2.2 burst
+ server 192.0.2.2 version 2 key 1 minpoll 4 maxpoll 5 prefer burst iburst source GigabitEthernet0/0/0/0
+ drift file apphost
+ drift aging time 0
+ master 1
+ access-group vrf siteA ipv4 peer PeerAcl2
+ access-group vrf siteA ipv4 serve ServeAcl2
+ access-group ipv4 peer PeerAcl1
+ access-group ipv4 serve ServeAcl1
+ access-group ipv4 serve-only ServeOnlyAcl1
+ access-group ipv4 query-only QueryOnlyAcl1
+ access-group ipv6 peer PeerAcl2
+ source vrf siteE GigabitEthernet0/0/0/0
+ source GigabitEthernet0/0/0/0
+ passive
+ broadcastdelay 1
+ update-calendar
+ log-internal-sync
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ access_group=dict(
+ ipv4=dict(
+ peer="PeerAcl1",
+ query_only="QueryOnlyAcl1",
+ serve="ServeAcl1",
+ serve_only="ServeOnlyAcl1",
+ ),
+ ipv6=dict(peer="PeerAcl2"),
+ vrfs=[
+ dict(
+ ipv4=dict(peer="PeerAcl2", serve="ServeAcl2"),
+ name="siteA",
+ ),
+ ],
+ ),
+ authenticate=True,
+ authentication_keys=[
+ dict(id=1, key="testkey", encryption=True),
+ dict(id=2, key="071B245F5A5B", encryption=True),
+ ],
+ broadcastdelay=1,
+ drift=dict(aging_time=0, file="apphost"),
+ interfaces=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ multicast_client="224.0.0.8",
+ multicast_destination="224.0.0.8",
+ broadcast_client=True,
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ multicast_key=1,
+ vrf="siteB",
+ ),
+ ],
+ ipv4=dict(dscp="af11"),
+ ipv6=dict(precedence="routine"),
+ log_internal_sync=True,
+ master=dict(stratum=1),
+ max_associations=10,
+ passive=True,
+ peers=[dict(iburst=True, peer="192.0.2.1", vrf="siteC")],
+ servers=[
+ dict(burst=True, server="192.0.2.2", vrf="siteD"),
+ dict(
+ iburst=True,
+ burst=True,
+ server="192.0.2.2",
+ key_id=1,
+ maxpoll=5,
+ minpoll=4,
+ prefer=True,
+ source="GigabitEthernet0/0/0/0",
+ version=2,
+ ),
+ ],
+ source_interface="GigabitEthernet0/0/0/0",
+ source_vrfs=[
+ dict(name="GigabitEthernet0/0/0/0", vrf="siteE"),
+ ],
+ trusted_keys=[dict(key_id=1), dict(key_id=2)],
+ update_calendar=True,
+ ),
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_ntp_global_merged(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ config=dict(
+ access_group=dict(
+ ipv4=dict(
+ peer="PeerAcl1",
+ query_only="QueryOnlyAcl1",
+ serve="ServeAcl1",
+ serve_only="ServeOnlyAcl1",
+ ),
+ ipv6=dict(peer="PeerAcl2"),
+ vrfs=[
+ dict(
+ ipv4=dict(peer="PeerAcl2", serve="ServeAcl2"),
+ name="siteA",
+ ),
+ ],
+ ),
+ authenticate=True,
+ authentication_keys=[
+ dict(id=1, key="testkey", encryption=True),
+ dict(id=2, key="071B245F5A5B", encryption=True),
+ ],
+ broadcastdelay=1,
+ drift=dict(aging_time=0, file="apphost"),
+ interfaces=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ multicast_client="224.0.0.8",
+ multicast_destination="224.0.0.8",
+ broadcast_client=True,
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ multicast_key=1,
+ vrf="siteB",
+ ),
+ ],
+ ipv4=dict(dscp="af11"),
+ ipv6=dict(precedence="routine"),
+ log_internal_sync=True,
+ master=dict(stratum=1),
+ max_associations=10,
+ passive=True,
+ peers=[dict(iburst=True, peer="192.0.2.1", vrf="siteC")],
+ servers=[
+ dict(burst=True, server="192.0.2.2", vrf="siteD"),
+ dict(
+ iburst=True,
+ burst=True,
+ server="192.0.2.2",
+ key_id=1,
+ maxpoll=5,
+ minpoll=4,
+ prefer=True,
+ source="GigabitEthernet0/0/0/0",
+ version=2,
+ ),
+ ],
+ source_interface="GigabitEthernet0/0/0/0",
+ source_vrfs=[
+ dict(name="GigabitEthernet0/0/0/0", vrf="siteE"),
+ ],
+ trusted_keys=[dict(key_id=1), dict(key_id=2)],
+ update_calendar=True,
+ ),
+ state="merged",
+ ),
+ )
+ commands = [
+ "ntp authentication-key 1 md5 encrypted testkey",
+ "ntp authentication-key 2 md5 encrypted 071B245F5A5B",
+ "ntp peer vrf siteC 192.0.2.1 iburst",
+ "ntp server vrf siteD 192.0.2.2 burst",
+ "ntp server 192.0.2.2 burst iburst key 1 minpoll 4 maxpoll 5 prefer version 2 source GigabitEthernet0/0/0/0",
+ "ntp trusted-key 1",
+ "ntp trusted-key 2",
+ "ntp interface GigabitEthernet0/0/0/0 broadcast client",
+ "ntp interface GigabitEthernet0/0/0/0 multicast destination 224.0.0.8",
+ "ntp interface GigabitEthernet0/0/0/0 multicast client 224.0.0.8",
+ "ntp interface GigabitEthernet0/0/0/0 vrf siteB multicast key 1",
+ "ntp vrf siteE source GigabitEthernet0/0/0/0",
+ "ntp access-group vrf siteA ipv4 serve ServeAcl2",
+ "ntp access-group vrf siteA ipv4 peer PeerAcl2",
+ "ntp access-group ipv4 peer PeerAcl1",
+ "ntp access-group ipv4 serve ServeAcl1",
+ "ntp access-group ipv4 serve-only ServeOnlyAcl1",
+ "ntp access-group ipv4 query-only QueryOnlyAcl1",
+ "ntp access-group ipv6 peer PeerAcl2",
+ "ntp authenticate",
+ "ntp log-internal-sync",
+ "ntp broadcastdelay 1",
+ "ntp drift aging time 0",
+ "ntp drift file apphost",
+ "ntp ipv4 dscp af11",
+ "ntp ipv6 precedence routine",
+ "ntp max-associations 10",
+ "ntp master 1",
+ "ntp passive",
+ "ntp update-calendar",
+ "ntp source GigabitEthernet0/0/0/0",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ntp_global_deleted(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ ntp
+ max-associations 10
+ interface GigabitEthernet0/0/0/0 vrf siteB
+ multicast key 1
+ !
+ interface GigabitEthernet0/0/0/0
+ broadcast client
+ multicast client 224.0.0.8
+ multicast destination 224.0.0.8
+ !
+ authentication-key 1 md5 encrypted testkey
+ authentication-key 2 md5 encrypted 071B245F5A5B
+ authenticate
+ trusted-key 1
+ trusted-key 2
+ ipv4 dscp af11
+ ipv6 precedence routine
+ peer vrf siteC 192.0.2.1 iburst
+ server vrf siteD 192.0.2.2 burst
+ server 192.0.2.2 version 2 key 1 minpoll 4 maxpoll 5 prefer burst iburst source GigabitEthernet0/0/0/0
+ drift file apphost
+ drift aging time 0
+ master 1
+ access-group vrf siteA ipv4 peer PeerAcl3
+ access-group vrf siteA ipv4 serve ServeAcl2
+ access-group ipv4 peer PeerAcl1
+ access-group ipv4 serve ServeAcl1
+ access-group ipv4 serve-only ServeOnlyAcl1
+ access-group ipv4 query-only QueryOnlyAcl1
+ access-group ipv6 peer PeerAcl2
+ source vrf siteE GigabitEthernet0/0/0/0
+ source GigabitEthernet0/0/0/0
+ passive
+ broadcastdelay 1
+ update-calendar
+ log-internal-sync
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(state="deleted"))
+ commands = [
+ "no ntp authentication-key 1 md5 encrypted testkey",
+ "no ntp authentication-key 2 md5 encrypted 071B245F5A5B",
+ "no ntp peer vrf siteC 192.0.2.1 iburst",
+ "no ntp server vrf siteD 192.0.2.2 burst",
+ "no ntp server 192.0.2.2 burst iburst key 1 minpoll 4 maxpoll 5 prefer version 2 source GigabitEthernet0/0/0/0",
+ "no ntp trusted-key 1",
+ "no ntp trusted-key 2",
+ "no ntp interface GigabitEthernet0/0/0/0 vrf siteB",
+ "no ntp interface GigabitEthernet0/0/0/0",
+ "no ntp vrf siteE source GigabitEthernet0/0/0/0",
+ "no ntp access-group vrf siteA ipv4 serve ServeAcl2",
+ "no ntp access-group vrf siteA ipv4 peer PeerAcl3",
+ "no ntp access-group ipv4 peer PeerAcl1",
+ "no ntp access-group ipv4 serve ServeAcl1",
+ "no ntp access-group ipv4 serve-only ServeOnlyAcl1",
+ "no ntp access-group ipv4 query-only QueryOnlyAcl1",
+ "no ntp access-group ipv6 peer PeerAcl2",
+ "no ntp authenticate",
+ "no ntp log-internal-sync",
+ "no ntp broadcastdelay 1",
+ "no ntp drift aging time 0",
+ "no ntp drift file apphost",
+ "no ntp ipv4 dscp af11",
+ "no ntp ipv6 precedence routine",
+ "no ntp max-associations 10",
+ "no ntp master 1",
+ "no ntp passive",
+ "no ntp update-calendar",
+ "no ntp source GigabitEthernet0/0/0/0",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ntp_global_replaced(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ ntp
+ max-associations 10
+ interface GigabitEthernet0/0/0/0 vrf siteB
+ multicast key 1
+ !
+ interface GigabitEthernet0/0/0/0
+ broadcast client
+ multicast client 224.0.0.8
+ multicast destination 224.0.0.8
+ !
+ authentication-key 1 md5 encrypted testkey
+ authentication-key 2 md5 encrypted 071B245F5A5B
+ authenticate
+ trusted-key 1
+ trusted-key 2
+ ipv4 dscp af11
+ ipv6 precedence routine
+ peer vrf siteC 192.0.2.1 iburst
+ server vrf siteD 192.0.2.2 burst
+ server 192.0.2.2 version 2 key 1 minpoll 4 maxpoll 5 prefer burst iburst source GigabitEthernet0/0/0/0
+ drift file apphost
+ drift aging time 0
+ master 1
+ access-group vrf siteA ipv4 peer PeerAcl3
+ access-group vrf siteA ipv4 serve ServeAcl2
+ access-group ipv4 peer PeerAcl1
+ access-group ipv4 serve ServeAcl1
+ access-group ipv4 serve-only ServeOnlyAcl1
+ access-group ipv4 query-only QueryOnlyAcl1
+ access-group ipv6 peer PeerAcl2
+ source vrf siteE GigabitEthernet0/0/0/0
+ source GigabitEthernet0/0/0/0
+ passive
+ broadcastdelay 1
+ update-calendar
+ log-internal-sync
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ access_group=dict(
+ ipv4=dict(
+ peer="PeerAcl1",
+ query_only="QueryOnlyAcl2",
+ serve="ServeAcl1",
+ serve_only="ServeOnlyAcl1",
+ ),
+ ipv6=dict(peer="PeerAcl2"),
+ vrfs=[
+ dict(
+ ipv4=dict(peer="PeerAcl2", serve="ServeAcl2"),
+ name="siteA",
+ ),
+ ],
+ ),
+ authenticate=True,
+ authentication_keys=[
+ dict(id=1, key="testkey1", encryption=True),
+ dict(id=2, key="071B245F5A5B", encryption=True),
+ ],
+ broadcastdelay=1,
+ drift=dict(aging_time=0, file="apphost"),
+ interfaces=[
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ multicast_client="224.0.0.8",
+ multicast_destination="224.0.0.8",
+ broadcast_client=True,
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ multicast_key=1,
+ vrf="siteB",
+ ),
+ ],
+ ipv4=dict(dscp="af12"),
+ ipv6=dict(precedence="routine"),
+ log_internal_sync=True,
+ master=dict(stratum=1),
+ max_associations=10,
+ passive=True,
+ peers=[dict(iburst=True, peer="192.0.2.1", vrf="siteC")],
+ servers=[
+ dict(burst=True, server="192.0.2.3", vrf="siteD"),
+ dict(
+ iburst=True,
+ burst=True,
+ server="192.0.2.2",
+ key_id=1,
+ maxpoll=5,
+ minpoll=4,
+ prefer=True,
+ source="GigabitEthernet0/0/0/1",
+ version=2,
+ ),
+ ],
+ source_interface="GigabitEthernet0/0/0/0",
+ source_vrfs=[
+ dict(name="GigabitEthernet0/0/0/0", vrf="siteE"),
+ ],
+ trusted_keys=[dict(key_id=1), dict(key_id=2)],
+ update_calendar=True,
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "no ntp server vrf siteD 192.0.2.2 burst",
+ "no ntp interface GigabitEthernet0/0/0/0",
+ "ntp authentication-key 1 md5 encrypted testkey1",
+ "ntp server vrf siteD 192.0.2.3 burst",
+ "ntp server 192.0.2.2 burst iburst key 1 minpoll 4 maxpoll 5 prefer version 2 source GigabitEthernet0/0/0/1",
+ "ntp interface GigabitEthernet0/0/0/1 broadcast client",
+ "ntp interface GigabitEthernet0/0/0/1 multicast destination 224.0.0.8",
+ "ntp interface GigabitEthernet0/0/0/1 multicast client 224.0.0.8",
+ "ntp access-group ipv4 query-only QueryOnlyAcl2",
+ "ntp access-group vrf siteA ipv4 peer PeerAcl2",
+ "ntp access-group vrf siteA ipv4 serve ServeAcl2",
+ "ntp ipv4 dscp af12",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_logging_global_rendered(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ config=dict(
+ access_group=dict(
+ ipv4=dict(
+ peer="PeerAcl1",
+ query_only="QueryOnlyAcl1",
+ serve="ServeAcl1",
+ serve_only="ServeOnlyAcl1",
+ ),
+ ipv6=dict(peer="PeerAcl2"),
+ vrfs=[
+ dict(
+ ipv4=dict(peer="PeerAcl2", serve="ServeAcl2"),
+ name="siteA",
+ ),
+ ],
+ ),
+ authenticate=True,
+ authentication_keys=[
+ dict(id=1, key="testkey", encryption=True),
+ dict(id=2, key="071B245F5A5B", encryption=True),
+ ],
+ broadcastdelay=1,
+ drift=dict(aging_time=0, file="apphost"),
+ interfaces=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ multicast_client="224.0.0.8",
+ multicast_destination="224.0.0.8",
+ broadcast_client=True,
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ multicast_key=1,
+ vrf="siteB",
+ ),
+ ],
+ ipv4=dict(dscp="af11"),
+ ipv6=dict(precedence="routine"),
+ log_internal_sync=True,
+ master=dict(stratum=1),
+ max_associations=10,
+ passive=True,
+ peers=[dict(iburst=True, peer="192.0.2.1", vrf="siteC")],
+ servers=[
+ dict(burst=True, server="192.0.2.2", vrf="siteD"),
+ dict(
+ iburst=True,
+ burst=True,
+ server="192.0.2.2",
+ key_id=1,
+ maxpoll=5,
+ minpoll=4,
+ prefer=True,
+ source="GigabitEthernet0/0/0/0",
+ version=2,
+ ),
+ ],
+ source_interface="GigabitEthernet0/0/0/0",
+ source_vrfs=[
+ dict(name="GigabitEthernet0/0/0/0", vrf="siteE"),
+ ],
+ trusted_keys=[dict(key_id=1), dict(key_id=2)],
+ update_calendar=True,
+ ),
+ state="rendered",
+ ),
+ )
+ commands = [
+ "ntp authentication-key 1 md5 encrypted testkey",
+ "ntp authentication-key 2 md5 encrypted 071B245F5A5B",
+ "ntp peer vrf siteC 192.0.2.1 iburst",
+ "ntp server vrf siteD 192.0.2.2 burst",
+ "ntp server 192.0.2.2 burst iburst key 1 minpoll 4 maxpoll 5 prefer version 2 source GigabitEthernet0/0/0/0",
+ "ntp trusted-key 1",
+ "ntp trusted-key 2",
+ "ntp interface GigabitEthernet0/0/0/0 broadcast client",
+ "ntp interface GigabitEthernet0/0/0/0 multicast destination 224.0.0.8",
+ "ntp interface GigabitEthernet0/0/0/0 multicast client 224.0.0.8",
+ "ntp interface GigabitEthernet0/0/0/0 vrf siteB multicast key 1",
+ "ntp vrf siteE source GigabitEthernet0/0/0/0",
+ "ntp access-group vrf siteA ipv4 serve ServeAcl2",
+ "ntp access-group vrf siteA ipv4 peer PeerAcl2",
+ "ntp access-group ipv4 peer PeerAcl1",
+ "ntp access-group ipv4 serve ServeAcl1",
+ "ntp access-group ipv4 serve-only ServeOnlyAcl1",
+ "ntp access-group ipv4 query-only QueryOnlyAcl1",
+ "ntp access-group ipv6 peer PeerAcl2",
+ "ntp authenticate",
+ "ntp log-internal-sync",
+ "ntp broadcastdelay 1",
+ "ntp drift aging time 0",
+ "ntp drift file apphost",
+ "ntp ipv4 dscp af11",
+ "ntp ipv6 precedence routine",
+ "ntp max-associations 10",
+ "ntp master 1",
+ "ntp passive",
+ "ntp update-calendar",
+ "ntp source GigabitEthernet0/0/0/0",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_ntp_global_overridden(self):
+ run_cfg = dedent(
+ """\
+ ntp
+ max-associations 10
+ interface GigabitEthernet0/0/0/0 vrf siteB
+ multicast key 1
+ !
+ interface GigabitEthernet0/0/0/0
+ broadcast client
+ multicast client 224.0.0.8
+ multicast destination 224.0.0.8
+ !
+ authentication-key 1 md5 encrypted testkey
+ authentication-key 2 md5 encrypted 071B245F5A5B
+ authenticate
+ trusted-key 1
+ trusted-key 2
+ ipv4 dscp af11
+ ipv6 precedence routine
+ peer vrf siteC 192.0.2.1 iburst
+ server vrf siteD 192.0.2.2 burst
+ server 192.0.2.2 version 2 key 1 minpoll 4 maxpoll 5 prefer burst iburst source GigabitEthernet0/0/0/0
+ drift file apphost
+ drift aging time 0
+ master 1
+ access-group vrf siteA ipv4 peer PeerAcl3
+ access-group vrf siteA ipv4 serve ServeAcl2
+ access-group ipv4 peer PeerAcl1
+ access-group ipv4 serve ServeAcl1
+ access-group ipv4 serve-only ServeOnlyAcl1
+ access-group ipv4 query-only QueryOnlyAcl1
+ access-group ipv6 peer PeerAcl2
+ source vrf siteE GigabitEthernet0/0/0/0
+ source GigabitEthernet0/0/0/0
+ passive
+ broadcastdelay 1
+ update-calendar
+ log-internal-sync
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ access_group=dict(
+ ipv4=dict(
+ peer="PeerAcl1",
+ query_only="QueryOnlyAcl2",
+ serve="ServeAcl1",
+ serve_only="ServeOnlyAcl1",
+ ),
+ ipv6=dict(peer="PeerAcl2"),
+ vrfs=[
+ dict(
+ ipv4=dict(peer="PeerAcl2", serve="ServeAcl2"),
+ name="siteA",
+ ),
+ ],
+ ),
+ authenticate=True,
+ authentication_keys=[
+ dict(id=1, key="testkey1", encryption=True),
+ dict(id=2, key="071B245F5A5B", encryption=True),
+ ],
+ broadcastdelay=1,
+ drift=dict(aging_time=0, file="apphost"),
+ interfaces=[
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ multicast_client="224.0.0.8",
+ multicast_destination="224.0.0.8",
+ broadcast_client=True,
+ ),
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ multicast_key=1,
+ vrf="siteB",
+ ),
+ ],
+ ipv4=dict(dscp="af12"),
+ ipv6=dict(precedence="routine"),
+ log_internal_sync=True,
+ master=dict(stratum=1),
+ max_associations=10,
+ passive=True,
+ peers=[dict(iburst=True, peer="192.0.2.1", vrf="siteC")],
+ servers=[
+ dict(burst=True, server="192.0.2.3", vrf="siteD"),
+ dict(
+ iburst=True,
+ burst=True,
+ server="192.0.2.2",
+ key_id=1,
+ maxpoll=5,
+ minpoll=4,
+ prefer=True,
+ source="GigabitEthernet0/0/0/1",
+ version=2,
+ ),
+ ],
+ source_interface="GigabitEthernet0/0/0/0",
+ source_vrfs=[
+ dict(name="GigabitEthernet0/0/0/0", vrf="siteE"),
+ ],
+ trusted_keys=[dict(key_id=1), dict(key_id=2)],
+ update_calendar=True,
+ ),
+ state="overridden",
+ ),
+ )
+ commands = [
+ "no ntp server vrf siteD 192.0.2.2 burst",
+ "no ntp interface GigabitEthernet0/0/0/0",
+ "ntp authentication-key 1 md5 encrypted testkey1",
+ "ntp server vrf siteD 192.0.2.3 burst",
+ "ntp server 192.0.2.2 burst iburst key 1 minpoll 4 maxpoll 5 prefer version 2 source GigabitEthernet0/0/0/1",
+ "ntp interface GigabitEthernet0/0/0/1 broadcast client",
+ "ntp interface GigabitEthernet0/0/0/1 multicast destination 224.0.0.8",
+ "ntp interface GigabitEthernet0/0/0/1 multicast client 224.0.0.8",
+ "ntp access-group ipv4 query-only QueryOnlyAcl2",
+ "ntp access-group vrf siteA ipv4 peer PeerAcl2",
+ "ntp access-group vrf siteA ipv4 serve ServeAcl2",
+ "ntp ipv4 dscp af12",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ntp_global_gathered(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ ntp
+ max-associations 10
+ interface GigabitEthernet0/0/0/0
+ broadcast client
+ multicast client 224.0.0.8
+ multicast destination 224.0.0.8
+ !
+ authentication-key 1 md5 encrypted testkey
+ authentication-key 2 md5 encrypted 071B245F5A5B
+ authenticate
+ trusted-key 1
+ trusted-key 2
+ ipv4 dscp af11
+ ipv6 precedence routine
+ peer vrf siteC 192.0.2.1 iburst
+ server 192.0.2.2 version 2 key 1 minpoll 4 maxpoll 5 prefer burst iburst source GigabitEthernet0/0/0/0
+ drift file apphost
+ drift aging time 0
+ master 1
+ access-group vrf siteA ipv4 peer PeerAcl3
+ access-group vrf siteA ipv4 serve ServeAcl2
+ access-group ipv4 peer PeerAcl1
+ access-group ipv4 serve ServeAcl1
+ access-group ipv4 serve-only ServeOnlyAcl1
+ access-group ipv4 query-only QueryOnlyAcl1
+ access-group ipv6 peer PeerAcl2
+ source vrf siteE GigabitEthernet0/0/0/0
+ source GigabitEthernet0/0/0/0
+ passive
+ broadcastdelay 1
+ update-calendar
+ log-internal-sync
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ print(self.get_config.return_value)
+ set_module_args(dict(state="gathered"))
+ gathered = {
+ "max_associations": 10,
+ "interfaces": [
+ {
+ "name": "GigabitEthernet0/0/0/0",
+ "broadcast_client": True,
+ "multicast_client": "224.0.0.8",
+ "multicast_destination": "224.0.0.8",
+ },
+ ],
+ "authentication_keys": [
+ {"id": 1, "key": "testkey", "encryption": True},
+ {"id": 2, "key": "071B245F5A5B", "encryption": True},
+ ],
+ "authenticate": True,
+ "trusted_keys": [{"key_id": 1}, {"key_id": 2}],
+ "ipv4": {"dscp": "af11"},
+ "ipv6": {"precedence": "routine"},
+ "peers": [{"peer": "192.0.2.1", "vrf": "siteC", "iburst": True}],
+ "servers": [
+ {
+ "server": "192.0.2.2",
+ "burst": True,
+ "iburst": True,
+ "key_id": 1,
+ "minpoll": 4,
+ "maxpoll": 5,
+ "prefer": True,
+ "version": 2,
+ "source": "GigabitEthernet0/0/0/0",
+ },
+ ],
+ "drift": {"file": "apphost", "aging_time": 0},
+ "master": {"stratum": 1},
+ "access_group": {
+ "vrfs": [
+ {
+ "name": "siteA",
+ "ipv4": {"peer": "PeerAcl3", "serve": "ServeAcl2"},
+ },
+ ],
+ "ipv4": {
+ "peer": "PeerAcl1",
+ "serve": "ServeAcl1",
+ "serve_only": "ServeOnlyAcl1",
+ "query_only": "QueryOnlyAcl1",
+ },
+ "ipv6": {"peer": "PeerAcl2"},
+ },
+ "source_vrfs": [
+ {"name": "GigabitEthernet0/0/0/0", "vrf": "siteE"},
+ ],
+ "source_interface": "GigabitEthernet0/0/0/0",
+ "passive": True,
+ "broadcastdelay": 1,
+ "update_calendar": True,
+ "log_internal_sync": True,
+ }
+ result = self.execute_module(changed=False)
+ self.assertEqual(gathered, result["gathered"])
+
+ def test_iosxr_ntp_global_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="ntp\n max-associations 10\n interface GigabitEthernet0/0/0/0\n broadcast client\n"
+ " multicast client 224.0.0.8\n multicast destination 224.0.0.8\n !\n "
+ "authentication-key 1 md5 encrypted testkey\n authentication-key 2 md5 "
+ "encrypted 071B245F5A5B\n authenticate\n trusted-key 1\n trusted-key 2\n ipv4 dscp "
+ "af11\n ipv6 precedence routine\n peer vrf siteC 192.0.2.1 iburst\n"
+ " server 192.0.2.2 version 2 key 1 minpoll 4 maxpoll 5 prefer "
+ "burst iburst source GigabitEthernet0/0/0/0\n drift file apphost\n drift aging time 0\n"
+ " master 1\n access-group vrf siteA ipv4 peer PeerAcl3\n access-group vrf siteA "
+ "ipv4 serve ServeAcl2\n access-group ipv4 peer PeerAcl1\n access-group ipv4 serve "
+ "ServeAcl1\n access-group ipv4 serve-only ServeOnlyAcl1\n access-group ipv4 "
+ "query-only QueryOnlyAcl1\n access-group ipv6 peer PeerAcl2\n source vrf siteE "
+ "GigabitEthernet0/0/0/0\n source GigabitEthernet0/0/0/0\n"
+ " passive\n broadcastdelay "
+ "1\n update-calendar\n log-internal-sync\n!",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "max_associations": 10,
+ "interfaces": [
+ {
+ "name": "GigabitEthernet0/0/0/0",
+ "broadcast_client": True,
+ "multicast_client": "224.0.0.8",
+ "multicast_destination": "224.0.0.8",
+ },
+ ],
+ "authentication_keys": [
+ {"id": 1, "key": "testkey", "encryption": True},
+ {"id": 2, "key": "071B245F5A5B", "encryption": True},
+ ],
+ "authenticate": True,
+ "trusted_keys": [{"key_id": 1}, {"key_id": 2}],
+ "ipv4": {"dscp": "af11"},
+ "ipv6": {"precedence": "routine"},
+ "peers": [{"peer": "192.0.2.1", "vrf": "siteC", "iburst": True}],
+ "servers": [
+ {
+ "server": "192.0.2.2",
+ "burst": True,
+ "iburst": True,
+ "key_id": 1,
+ "minpoll": 4,
+ "maxpoll": 5,
+ "prefer": True,
+ "version": 2,
+ "source": "GigabitEthernet0/0/0/0",
+ },
+ ],
+ "drift": {"file": "apphost", "aging_time": 0},
+ "master": {"stratum": 1},
+ "access_group": {
+ "vrfs": [{"name": "siteA", "ipv4": {"peer": "PeerAcl3"}}],
+ "ipv4": {
+ "peer": "PeerAcl1",
+ "serve": "ServeAcl1",
+ "serve_only": "ServeOnlyAcl1",
+ "query_only": "QueryOnlyAcl1",
+ },
+ "ipv6": {"peer": "PeerAcl2"},
+ },
+ "source_vrfs": [
+ {"name": "GigabitEthernet0/0/0/0", "vrf": "siteE"},
+ ],
+ "source_interface": "GigabitEthernet0/0/0/0",
+ "passive": True,
+ "broadcastdelay": 1,
+ "update_calendar": True,
+ "log_internal_sync": True,
+ }
+ self.assertEqual(parsed_list, result["parsed"])
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ospf_interfaces.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ospf_interfaces.py
new file mode 100644
index 00000000..8c976944
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ospf_interfaces.py
@@ -0,0 +1,359 @@
+#
+# (c) 2019, Ansible by Red Hat, inc
+# 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
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_ospf_interfaces
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrOspf_InterfacesModule(TestIosxrModule):
+ module = iosxr_ospf_interfaces
+
+ def setUp(self):
+ super(TestIosxrOspf_InterfacesModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+
+ self.mock_edit_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.providers.providers.CliProvider.edit_config",
+ )
+ self.edit_config = self.mock_edit_config.start()
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.ospf_interfaces.ospf_interfaces."
+ "Ospf_interfacesFacts.get_ospf_interfaces",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrOspf_InterfacesModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_edit_config.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def load_fixtures(self, commands=None):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_ospf_interfaces.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_ospf_interfaces_merged(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ type="gigabitethernet",
+ address_family=[
+ dict(
+ afi="ipv4",
+ processes=[
+ dict(
+ process_id="LAB1",
+ area=dict(area_id="0.0.0.3"),
+ ),
+ ],
+ cost=10,
+ authentication=dict(
+ message_digest=dict(keychain="iosxr"),
+ ),
+ ),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ commands = [
+ "router ospf LAB1 area 0.0.0.3 interface GigabitEthernet 0/0/0/1 cost 10",
+ "router ospf LAB1 area 0.0.0.3 interface GigabitEthernet 0/0/0/1 authentication message-digest",
+ "router ospf LAB1 area 0.0.0.3 interface GigabitEthernet 0/0/0/1 authentication message-digest keychain iosxr",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ospf_interfaces_merged_idempotent(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ type="gigabitethernet",
+ address_family=[
+ dict(
+ afi="ipv4",
+ processes=[
+ dict(
+ process_id="LAB3",
+ area=dict(area_id="0.0.0.3"),
+ ),
+ ],
+ cost=20,
+ authentication=dict(
+ message_digest=dict(keychain="cisco"),
+ ),
+ ),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_ospf_interfaces_replaced(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ type="gigabitethernet",
+ address_family=[
+ dict(
+ afi="ipv4",
+ processes=[
+ dict(
+ process_id="LAB3",
+ area=dict(area_id="0.0.0.3"),
+ ),
+ ],
+ cost=40,
+ authentication=dict(
+ message_digest=dict(keychain="ciscoiosxr"),
+ ),
+ ),
+ ],
+ ),
+ ],
+ state="replaced",
+ ),
+ )
+ commands = [
+ "router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0 cost 40",
+ "router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0 authentication message-digest",
+ "router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0 authentication message-digest keychain ciscoiosxr",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ospf_interfaces_replaced_idempotent(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ type="gigabitethernet",
+ address_family=[
+ dict(
+ afi="ipv4",
+ processes=[
+ dict(
+ process_id="LAB3",
+ area=dict(area_id="0.0.0.3"),
+ ),
+ ],
+ cost=20,
+ authentication=dict(
+ message_digest=dict(keychain="cisco"),
+ ),
+ ),
+ ],
+ ),
+ ],
+ state="replaced",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_ospf_interfaces_overridden(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/4",
+ type="gigabitethernet",
+ address_family=[
+ dict(
+ afi="ipv4",
+ processes=[
+ dict(
+ process_id="LAB4",
+ area=dict(area_id="0.0.0.4"),
+ ),
+ ],
+ cost=40,
+ authentication=dict(
+ message_digest=dict(keychain="iosxr"),
+ ),
+ ),
+ ],
+ ),
+ ],
+ state="overridden",
+ ),
+ )
+
+ commands = [
+ "no router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0",
+ "router ospf LAB4 area 0.0.0.4 interface GigabitEthernet 0/0/0/4 cost 40",
+ "router ospf LAB4 area 0.0.0.4 interface GigabitEthernet 0/0/0/4 authentication message-digest",
+ "router ospf LAB4 area 0.0.0.4 interface GigabitEthernet 0/0/0/4 authentication message-digest keychain iosxr",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ospf_interfaces_overridden_idempotent(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ type="gigabitethernet",
+ address_family=[
+ dict(
+ afi="ipv4",
+ processes=[
+ dict(
+ process_id="LAB3",
+ area=dict(area_id="0.0.0.3"),
+ ),
+ ],
+ cost=20,
+ authentication=dict(
+ message_digest=dict(keychain="cisco"),
+ ),
+ ),
+ ],
+ ),
+ ],
+ state="overridden",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_ospf_interfaces_deleted(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ type="gigabitethernet",
+ ),
+ ],
+ state="deleted",
+ ),
+ )
+ commands = [
+ "no router ospf LAB3 area 0.0.0.3 interface GigabitEthernet 0/0/0/0",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ospf_interfaces_deleted_idempotent(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ type="gigabitethernet",
+ ),
+ ],
+ state="deleted",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_ospf_interfaces_parsed(self):
+ set_module_args(
+ dict(
+ running_config="router ospf LAB3\n area 0.0.0.3\n interface GigabitEthernet0/0/0/0\n cost 20\n !\n !\n!",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = [
+ dict(
+ name="GigabitEthernet0/0/0/0",
+ type="gigabitethernet",
+ address_family=[
+ dict(
+ afi="ipv4",
+ processes=[
+ dict(
+ process_id="LAB3",
+ area=dict(area_id="0.0.0.3"),
+ ),
+ ],
+ cost=20,
+ ),
+ ],
+ ),
+ ]
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_ospf_interfaces_rendered(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="GigabitEthernet0/0/0/1",
+ type="gigabitethernet",
+ address_family=[
+ dict(
+ afi="ipv4",
+ processes=[
+ dict(
+ process_id="LAB1",
+ area=dict(area_id="0.0.0.3"),
+ ),
+ ],
+ cost=10,
+ authentication=dict(
+ message_digest=dict(keychain="iosxr"),
+ ),
+ ),
+ ],
+ ),
+ ],
+ state="rendered",
+ ),
+ )
+ commands = [
+ "router ospf LAB1 area 0.0.0.3 interface GigabitEthernet 0/0/0/1 cost 10",
+ "router ospf LAB1 area 0.0.0.3 interface GigabitEthernet 0/0/0/1 authentication message-digest",
+ "router ospf LAB1 area 0.0.0.3 interface GigabitEthernet 0/0/0/1 authentication message-digest keychain iosxr",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ospfv2.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ospfv2.py
new file mode 100644
index 00000000..6d00a825
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ospfv2.py
@@ -0,0 +1,277 @@
+#
+# (c) 2019, Ansible by Red Hat, inc
+# 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
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_ospfv2
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrOspfV2Module(TestIosxrModule):
+ module = iosxr_ospfv2
+
+ def setUp(self):
+ super(TestIosxrOspfV2Module, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+
+ self.mock_edit_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.providers.providers.CliProvider.edit_config",
+ )
+ self.edit_config = self.mock_edit_config.start()
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.ospfv2.ospfv2."
+ "Ospfv2Facts.get_ospfv2_data",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrOspfV2Module, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_edit_config.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def load_fixtures(self, commands=None):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_ospfv2.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_ospfv2_merged(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="300",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ log_adjacency_changes=dict(set=True),
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+ commands = [
+ "router ospf 300",
+ "cost 2",
+ "default-metric 10",
+ "area 11 default-cost 5",
+ "log adjacency changes",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ospfv2_merged_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="30",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_ospfv2_replaced(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="30",
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ dict(
+ process_id="40",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "router ospf 30",
+ "no default-metric 10",
+ "router ospf 40",
+ "cost 2",
+ "default-metric 10",
+ "area 11 default-cost 5",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ospfv2_replaced_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="30",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_ospfv2_overridden(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="40",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ log_adjacency_changes=dict(set=True),
+ ),
+ ],
+ ),
+ state="overridden",
+ ),
+ )
+
+ commands = [
+ "router ospf 30",
+ "no cost 2",
+ "no default-metric 10",
+ "no area 11 default-cost 5",
+ "router ospf 40",
+ "cost 2",
+ "default-metric 10",
+ "area 11 default-cost 5",
+ "log adjacency changes",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ospfv2_overridden_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="30",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ ),
+ state="overridden",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_ospfv2_deleted(self):
+ set_module_args(
+ dict(
+ config=dict(processes=[dict(process_id="30", cost=2)]),
+ state="deleted",
+ ),
+ )
+ commands = [
+ "router ospf 30",
+ "no cost 2",
+ "no default-metric 10",
+ "no area 11 default-cost 5",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ospfv2_parsed(self):
+ set_module_args(
+ dict(
+ running_config="router ospf 50\n cost 2\n area 11\n default-cost 5\n !\n!",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "processes": [
+ dict(
+ process_id="50",
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ }
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_ospfv2_rendered(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="60",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ log_adjacency_changes=dict(set=True),
+ ),
+ ],
+ ),
+ state="rendered",
+ ),
+ )
+ commands = [
+ "area 11 default-cost 5",
+ "cost 2",
+ "log adjacency changes",
+ "default-metric 10",
+ "router ospf 60",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ospfv3.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ospfv3.py
new file mode 100644
index 00000000..1b8e491f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ospfv3.py
@@ -0,0 +1,271 @@
+#
+# (c) 2019, Ansible by Red Hat, inc
+# 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
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_ospfv3
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrOspfV3Module(TestIosxrModule):
+ module = iosxr_ospfv3
+
+ def setUp(self):
+ super(TestIosxrOspfV3Module, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+
+ self.mock_edit_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.providers.providers.CliProvider.edit_config",
+ )
+ self.edit_config = self.mock_edit_config.start()
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.ospfv3.ospfv3."
+ "Ospfv3Facts.get_ospfv3_data",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrOspfV3Module, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_edit_config.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def load_fixtures(self, commands=None):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_ospfv3.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_ospfv3_merged(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="300",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+ commands = [
+ "router ospfv3 300",
+ "cost 2",
+ "default-metric 10",
+ "area 11 default-cost 5",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ospfv3_merged_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="30",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_ospfv3_replaced(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="30",
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ dict(
+ process_id="40",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "router ospfv3 30",
+ "no default-metric 10",
+ "router ospfv3 40",
+ "cost 2",
+ "default-metric 10",
+ "area 11 default-cost 5",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ospfv3_replaced_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="30",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_ospfv3_overridden(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="40",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ ),
+ state="overridden",
+ ),
+ )
+
+ commands = [
+ "router ospfv3 30",
+ "no cost 2",
+ "no default-metric 10",
+ "no area 11 default-cost 5",
+ "router ospfv3 40",
+ "cost 2",
+ "default-metric 10",
+ "area 11 default-cost 5",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ospfv3_overridden_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="30",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ ),
+ state="overridden",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_ospfv3_deleted(self):
+ set_module_args(
+ dict(
+ config=dict(processes=[dict(process_id="30", cost=2)]),
+ state="deleted",
+ ),
+ )
+ commands = [
+ "router ospfv3 30",
+ "no cost 2",
+ "no default-metric 10",
+ "no area 11 default-cost 5",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_ospfv3_parsed(self):
+ set_module_args(
+ dict(
+ running_config="router ospfv3 50\n cost 2\n area 11\n default-cost 5\n !\n!",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "processes": [
+ dict(
+ process_id="50",
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ }
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_ospfv3_rendered(self):
+ set_module_args(
+ dict(
+ config=dict(
+ processes=[
+ dict(
+ process_id="60",
+ default_metric=10,
+ cost=2,
+ areas=[dict(area_id="11", default_cost=5)],
+ ),
+ ],
+ ),
+ state="rendered",
+ ),
+ )
+ commands = [
+ "area 11 default-cost 5",
+ "cost 2",
+ "default-metric 10",
+ "router ospfv3 60",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), commands)
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ping.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ping.py
new file mode 100644
index 00000000..d0ceda0f
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_ping.py
@@ -0,0 +1,180 @@
+#
+# (c) 2022, Ansible by Red Hat, inc
+# 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
+
+from textwrap import dedent
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_ping
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule
+
+
+class TestIosxrPingModule(TestIosxrModule):
+ module = iosxr_ping
+
+ def setUp(self):
+ super(TestIosxrPingModule, self).setUp()
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.config.ping.ping.Ping.run_command",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrPingModule, self).tearDown()
+ self.mock_execute_show_command.stop()
+
+ def test_iosxr_ping_count(self):
+ self.execute_show_command.return_value = dedent(
+ """\
+ Type escape sequence to abort.
+ ending 2, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds:
+ !
+ Success rate is 100 percent (2/2), round-trip min/avg/max = 25/25/25 ms
+ """,
+ )
+ set_module_args(dict(count=2, dest="8.8.8.8"))
+ result = self.execute_module()
+ mock_res = {
+ "commands": "ping ipv4 8.8.8.8 count 2",
+ "packet_loss": "0%",
+ "packets_rx": 2,
+ "packets_tx": 2,
+ "rtt": {"min": 25, "avg": 25, "max": 25},
+ "changed": False,
+ }
+ self.assertEqual(result, mock_res)
+
+ def test_iosxr_ping_v6(self):
+ self.execute_show_command.return_value = dedent(
+ """\
+ Type escape sequence to abort.
+ ending 2, 100-byte ICMP Echos to 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff, timeout is 2 seconds:
+ !
+ Success rate is 100 percent (2/2), round-trip min/avg/max = 25/25/25 ms
+ """,
+ )
+ set_module_args(
+ dict(
+ count=2,
+ dest="2001:db8:ffff:ffff:ffff:ffff:ffff:ffff",
+ afi="ipv6",
+ ),
+ )
+ result = self.execute_module()
+ mock_res = {
+ "commands": "ping ipv6 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff count 2",
+ "packet_loss": "0%",
+ "packets_rx": 2,
+ "packets_tx": 2,
+ "rtt": {"min": 25, "avg": 25, "max": 25},
+ "changed": False,
+ }
+ self.assertEqual(result, mock_res)
+
+ def test_iosxr_ping_options_all(self):
+ self.execute_show_command.return_value = dedent(
+ """\
+ Type escape sequence to abort.
+ ending 2, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds:
+ !
+ Success rate is 100 percent (2/2), round-trip min/avg/max = 25/25/25 ms
+ """,
+ )
+ set_module_args(
+ {
+ "afi": "ipv4",
+ "count": 4,
+ "dest": "8.8.8.8",
+ "df_bit": True,
+ "size": "10",
+ "source": "Loopback88",
+ "state": "present",
+ "sweep": True,
+ "validate": True,
+ "vrf": "DummyVrf",
+ },
+ )
+ result = self.execute_module()
+ mock_res = {
+ "commands": "ping vrf DummyVrf ipv4 8.8.8.8 count 4 df-bit sweep validate size 10 source Loopback88",
+ "packet_loss": "0%",
+ "packets_rx": 2,
+ "packets_tx": 2,
+ "rtt": {"min": 25, "avg": 25, "max": 25},
+ "changed": False,
+ }
+ self.assertEqual(result, mock_res)
+
+ def test_iosxr_ping_state_absent_pass(self):
+ self.execute_show_command.return_value = dedent(
+ """\
+ Type escape sequence to abort.
+ ending 2, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds:
+ !
+ Success rate is 90 percent (2/2), round-trip min/avg/max = 25/25/25 ms
+ """,
+ )
+ set_module_args(dict(count=2, dest="8.8.8.8", state="absent"))
+ result = self.execute_module(failed=True)
+ mock_res = {
+ "msg": "Ping succeeded unexpectedly",
+ "commands": "ping ipv4 8.8.8.8 count 2",
+ "packet_loss": "10%",
+ "packets_rx": 2,
+ "packets_tx": 2,
+ "rtt": {"min": 25, "avg": 25, "max": 25},
+ "failed": True,
+ }
+ self.assertEqual(result, mock_res)
+
+ def test_iosxr_ping_state_absent_pass(self):
+ self.execute_show_command.return_value = dedent(
+ """\
+ Type escape sequence to abort.
+ Sending 5, 100-byte ICMP Echos to 192.0.2.1, timeout is 2 seconds:
+ .....
+ Success rate is 0 percent (0/5)
+ """,
+ )
+ set_module_args(dict(count=2, dest="192.0.2.1", state="absent"))
+ result = self.execute_module(failed=False)
+ print(result)
+ mock_res = {
+ "commands": "ping ipv4 192.0.2.1 count 2",
+ "packet_loss": "100%",
+ "packets_rx": 0,
+ "packets_tx": 5,
+ "rtt": {},
+ "changed": False,
+ }
+ self.assertEqual(result, mock_res)
+
+ def test_iosxr_ping_state_absent_present_fail(self):
+ self.execute_show_command.return_value = dedent(
+ """\
+ Type escape sequence to abort.
+ ending 2, 100-byte ICMP Echos to 8.8.8.8, timeout is 12 seconds:
+ !
+ Success rate is 0 percent (0/2), round-trip min/avg/max = 25/25/25 ms
+ """,
+ )
+ set_module_args(dict(count=2, dest="8.8.8.8", state="present"))
+ result = self.execute_module(failed=True)
+ mock_res = {
+ "msg": "Ping failed unexpectedly",
+ "commands": "ping ipv4 8.8.8.8 count 2",
+ "packet_loss": "100%",
+ "packets_rx": 0,
+ "packets_tx": 2,
+ "rtt": {"min": 25, "avg": 25, "max": 25},
+ "failed": True,
+ }
+ self.assertEqual(result, mock_res)
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_prefix_lists.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_prefix_lists.py
new file mode 100644
index 00000000..6dca5d92
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_prefix_lists.py
@@ -0,0 +1,442 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from textwrap import dedent
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_prefix_lists
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule
+
+
+class TestIosxrPrefixListsModule(TestIosxrModule):
+ module = iosxr_prefix_lists
+
+ def setUp(self):
+ super(TestIosxrPrefixListsModule, self).setUp()
+
+ self.mock_get_resource_connection = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection = self.mock_get_resource_connection.start()
+
+ self.mock_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.prefix_lists.prefix_lists."
+ "Prefix_listsFacts.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ def tearDown(self):
+ super(TestIosxrPrefixListsModule, self).tearDown()
+ self.get_resource_connection.stop()
+ self.get_config.stop()
+
+ def test_iosxr_prefix_lists_merged_idempotent(self):
+ run_cfg = dedent(
+ """ipv6 prefix-list test2\n 4 remark test\n!
+ \nipv4 prefix-list test1\n 3 remark test1\n 2 permit 10.0.0.0/24\n!
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv6",
+ prefix_lists=[
+ dict(
+ name="test2",
+ entries=[
+ dict(
+ sequence=4,
+ action="remark",
+ description="test",
+ ),
+ ],
+ ),
+ ],
+ ),
+ dict(
+ afi="ipv4",
+ prefix_lists=[
+ dict(
+ name="test1",
+ entries=[
+ dict(
+ sequence=3,
+ action="remark",
+ description="test1",
+ ),
+ dict(
+ sequence=2,
+ action="permit",
+ prefix="10.0.0.0/24",
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_prefix_lists_merged(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv6",
+ prefix_lists=[
+ dict(
+ name="test2",
+ entries=[
+ dict(
+ sequence=4,
+ action="remark",
+ description="test",
+ ),
+ ],
+ ),
+ ],
+ ),
+ dict(
+ afi="ipv4",
+ prefix_lists=[
+ dict(
+ name="test1",
+ entries=[
+ dict(
+ sequence=3,
+ action="remark",
+ description="test1",
+ ),
+ dict(
+ sequence=2,
+ action="permit",
+ prefix="10.0.0.0/24",
+ ),
+ ],
+ ),
+ dict(
+ name="test3",
+ entries=[
+ dict(
+ sequence=5,
+ action="permit",
+ eq="3",
+ prefix="32.0.0.0/8",
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ commands = [
+ "ipv6 prefix-list test2 4 remark test",
+ "ipv4 prefix-list test1 2 permit 10.0.0.0/24",
+ "ipv4 prefix-list test1 3 remark test1",
+ "ipv4 prefix-list test3 5 permit 32.0.0.0/8 eq 3",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_prefix_lists_replaced(self):
+ run_cfg = dedent(
+ """ipv6 prefix-list test2\n 4 remark test\n!
+ \nipv4 prefix-list test1\n 3 remark test1\n 2 permit 10.0.0.0/24\n!""",
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv4",
+ prefix_lists=[
+ dict(
+ name="test2",
+ entries=[
+ dict(
+ sequence=2,
+ action="permit",
+ prefix="10.0.0.0/24",
+ ),
+ ],
+ ),
+ dict(
+ name="test1",
+ entries=[
+ dict(
+ sequence=2,
+ action="permit",
+ prefix="10.0.0.0/24",
+ ),
+ ],
+ ),
+ dict(
+ name="test3",
+ entries=[
+ dict(
+ sequence=5,
+ action="permit",
+ eq="3",
+ prefix="32.0.0.0/8",
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="replaced",
+ ),
+ )
+ commands = [
+ "no ipv4 prefix-list test1 3 remark test1",
+ "ipv4 prefix-list test2 2 permit 10.0.0.0/24",
+ "ipv4 prefix-list test3 5 permit 32.0.0.0/8 eq 3",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_prefix_lists_replaced_idempotent(self):
+ run_cfg = dedent(
+ """ipv6 prefix-list test2\n 4 remark test\n!
+ \nipv4 prefix-list test1\n 3 remark test1\n 2 permit 10.0.0.0/24\n!""",
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv6",
+ prefix_lists=[
+ dict(
+ name="test2",
+ entries=[
+ dict(
+ sequence=4,
+ action="remark",
+ description="test",
+ ),
+ ],
+ ),
+ ],
+ ),
+ dict(
+ afi="ipv4",
+ prefix_lists=[
+ dict(
+ name="test1",
+ entries=[
+ dict(
+ sequence=3,
+ action="remark",
+ description="test1",
+ ),
+ dict(
+ sequence=2,
+ action="permit",
+ prefix="10.0.0.0/24",
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="replaced",
+ ),
+ )
+
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_prefix_list_deleted(self):
+ run_cfg = dedent(
+ """ipv6 prefix-list test2\n 4 remark test\n!
+ \nipv4 prefix-list test1\n 3 remark test1\n 2 permit 10.0.0.0/24\n!""",
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(state="deleted"))
+
+ commands = ["no ipv4 prefix-list test1", "no ipv6 prefix-list test2"]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_prefix_list_deleted_idempotent(self):
+ run_cfg = dedent(
+ """\
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(config=[], state="deleted"))
+
+ result = self.execute_module(changed=False)
+ self.assertEqual(result["commands"], [])
+
+ def test_iosxr_prefix_list_rendered(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv6",
+ prefix_lists=[
+ dict(
+ name="test2",
+ entries=[
+ dict(
+ sequence=4,
+ action="remark",
+ description="test",
+ ),
+ ],
+ ),
+ ],
+ ),
+ dict(
+ afi="ipv4",
+ prefix_lists=[
+ dict(
+ name="test1",
+ entries=[
+ dict(
+ sequence=3,
+ action="remark",
+ description="test1",
+ ),
+ dict(
+ sequence=2,
+ action="permit",
+ prefix="10.0.0.0/24",
+ ),
+ ],
+ ),
+ dict(
+ name="test3",
+ entries=[
+ dict(
+ sequence=5,
+ action="permit",
+ eq="3",
+ prefix="32.0.0.0/8",
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="rendered",
+ ),
+ )
+
+ commands = [
+ "ipv6 prefix-list test2 4 remark test",
+ "ipv4 prefix-list test1 2 permit 10.0.0.0/24",
+ "ipv4 prefix-list test1 3 remark test1",
+ "ipv4 prefix-list test3 5 permit 32.0.0.0/8 eq 3",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_prefix_list_parsed(self):
+ set_module_args(
+ dict(
+ running_config="ipv4 prefix-list test1\n 3 remark test1\n!",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = [
+ {
+ "afi": "ipv4",
+ "prefix_lists": [
+ {
+ "name": "test1",
+ "entries": [
+ {
+ "sequence": 3,
+ "action": "remark",
+ "description": "test1",
+ },
+ ],
+ },
+ ],
+ },
+ ]
+
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_iosxr_prefix_list_overridden(self):
+ run_cfg = dedent(
+ """ipv6 prefix-list test2\n 4 remark test\n!
+ \nipv4 prefix-list test1\n 3 remark test1\n 2 permit 10.0.0.0/24\n!
+ """,
+ )
+
+ self.get_config.return_value = run_cfg
+
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ afi="ipv4",
+ prefix_lists=[
+ dict(
+ name="test2",
+ entries=[
+ dict(
+ sequence=2,
+ action="permit",
+ prefix="10.0.0.0/24",
+ ),
+ ],
+ ),
+ dict(
+ name="test1",
+ entries=[
+ dict(
+ sequence=2,
+ action="permit",
+ prefix="10.0.0.0/24",
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="overridden",
+ ),
+ )
+ commands = [
+ "no ipv4 prefix-list test1 3 remark test1",
+ "ipv4 prefix-list test2 2 permit 10.0.0.0/24",
+ "no ipv6 prefix-list test2",
+ ]
+
+ result = self.execute_module(changed=True)
+ self.assertEqual(set(result["commands"]), set(commands))
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_snmp_server.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_snmp_server.py
new file mode 100644
index 00000000..14862519
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_snmp_server.py
@@ -0,0 +1,3612 @@
+# (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/>.
+
+# Make coding more python3-ish
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from textwrap import dedent
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_snmp_server
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule
+
+
+class TestIosxrSnmpServerModule(TestIosxrModule):
+ module = iosxr_snmp_server
+
+ def setUp(self):
+ super(TestIosxrSnmpServerModule, self).setUp()
+
+ self.mock_get_resource_connection = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base."
+ "get_resource_connection",
+ )
+ self.get_resource_connection = self.mock_get_resource_connection.start()
+
+ self.mock_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.snmp_server.snmp_server."
+ "Snmp_serverFacts.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ def tearDown(self):
+ super(TestIosxrSnmpServerModule, self).tearDown()
+ self.get_resource_connection.stop()
+ self.get_config.stop()
+
+ def test_iosxr_snmp_server_merged_idempotent(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ snmp-server vrf vrf1
+ host 1.1.1.1 traps test1
+ !
+ snmp-server drop report acl IPv4 test1
+ snmp-server drop unknown-user
+ snmp-server ipv4 dscp af11
+ snmp-server ipv6 precedence routine
+ snmp-server user u1 test2 v1 IPv4 test1 IPv6 test2 v4acl
+ snmp-server community test2 RW SystemOwner IPv4 test IPv6 test1
+ snmp-server group g2 v1 read test1 write test2 context test3 IPv4 test IPv6 test1
+ snmp-server queue-length 2
+ snmp-server trap-timeout 3
+ snmp-server trap throttle-time 12
+ snmp-server traps rf
+ snmp-server traps bfd
+ snmp-server traps bgp cbgp2
+ snmp-server traps pim neighbor-change
+ snmp-server traps pim invalid-message-received
+ snmp-server traps pim rp-mapping-change
+ snmp-server traps pim interface-state-change
+ snmp-server traps copy-complete
+ snmp-server traps hsrp
+ snmp-server traps ipsla
+ snmp-server traps msdp peer-state-change
+ snmp-server traps snmp linkup
+ snmp-server traps snmp linkdown
+ snmp-server traps snmp coldstart
+ snmp-server traps snmp warmstart
+ snmp-server traps snmp authentication
+ snmp-server traps vrrp events
+ snmp-server traps flash removal
+ snmp-server traps flash insertion
+ snmp-server traps ipsec tunnel stop
+ snmp-server traps ipsec tunnel start
+ snmp-server traps power
+ snmp-server traps config
+ snmp-server traps entity
+ snmp-server traps sensor
+ snmp-server traps selective-vrf-download role-change
+ snmp-server traps syslog
+ snmp-server traps system
+ snmp-server traps ospf lsa lsa-maxage
+ snmp-server traps ospf lsa lsa-originate
+ snmp-server traps ospf errors bad-packet
+ snmp-server traps ospf errors authentication-failure
+ snmp-server traps ospf errors config-error
+ snmp-server traps ospf errors virt-bad-packet
+ snmp-server traps ospf errors virt-authentication-failure
+ snmp-server traps ospf errors virt-config-error
+ snmp-server traps ospf retransmit packets
+ snmp-server traps ospf retransmit virt-packets
+ snmp-server traps ospf state-change if-state-change
+ snmp-server traps ospf state-change neighbor-state-change
+ snmp-server traps ospf state-change virtif-state-change
+ snmp-server traps ospf state-change virtneighbor-state-change
+ snmp-server traps rsvp all
+ snmp-server traps rsvp new-flow
+ snmp-server traps rsvp lost-flow
+ snmp-server traps l2tun sessions
+ snmp-server traps l2tun tunnel-up
+ snmp-server traps l2tun tunnel-down
+ snmp-server traps vpls all
+ snmp-server traps vpls status
+ snmp-server traps vpls full-clear
+ snmp-server traps vpls full-raise
+ snmp-server traps bulkstat collection
+ snmp-server traps diameter peerup
+ snmp-server traps diameter peerdown
+ snmp-server traps diameter protocolerror
+ snmp-server traps diameter permanentfail
+ snmp-server traps diameter transientfail
+ snmp-server traps l2vpn all
+ snmp-server traps l2vpn vc-up
+ snmp-server traps l2vpn vc-down
+ snmp-server traps bridgemib
+ snmp-server traps ospfv3 errors bad-packet
+ snmp-server traps ospfv3 errors config-error
+ snmp-server traps ospfv3 errors virt-config-error
+ snmp-server traps ospfv3 state-change neighbor-state-change
+ snmp-server traps ospfv3 state-change virtif-state-change
+ snmp-server traps ospfv3 state-change virtneighbor-state-change
+ snmp-server traps ospfv3 state-change restart-status-change
+ snmp-server traps ospfv3 state-change restart-helper-status-change
+ snmp-server traps ospfv3 state-change restart-virtual-helper-status-change
+ snmp-server traps subscriber session-agg node
+ snmp-server traps subscriber session-agg access-interface
+ snmp-server traps addrpool low
+ snmp-server traps addrpool high
+ snmp-server traps cisco-entity-ext
+ snmp-server traps entity-state operstatus
+ snmp-server traps entity-state switchover
+ snmp-server traps entity-redundancy all
+ snmp-server traps entity-redundancy status
+ snmp-server traps entity-redundancy switchover
+ snmp-server chassis-id test2
+ snmp-server contact t1
+ snmp-server location test1
+ snmp-server target list test host 1.1.1.2
+ snmp-server target list test2 vrf vrf2
+ snmp-server context c1
+ snmp-server context c2
+ snmp-server logging threshold oid-processing 1
+ snmp-server logging threshold pdu-processing 1
+ snmp-server mib bulkstat max-procmem-size 101
+ snmp-server mib bulkstat object-list test1
+ !
+ snmp-server mib bulkstat schema mib1
+ object-list test1
+ poll-interval 1
+ !
+ snmp-server mib bulkstat transfer-id test2
+ retry 1
+ buffer-size 1024
+ enable
+ format schemaASCII
+ retain 1
+ schema test2
+ !
+ snmp-server timeouts duplicate 0
+ snmp-server timeouts inQdrop 0
+ snmp-server timeouts subagent 1
+ snmp-server timeouts pdu stats 1
+ snmp-server timeouts threshold 0
+ snmp-server packetsize 490
+ snmp-server correlator rule rule1
+ timeout 5
+ !
+ snmp-server correlator ruleset rule1
+ !
+ snmp-server correlator buffer-size 1024
+ snmp-server trap-source GigabitEthernet0/0/0/2
+ snmp-server throttle-time 60
+ snmp-server community-map cm1 context c1 security-name s1 target-list t1
+ snmp-server inform retries 7
+ snmp-server overload-control 4 6
+ snmp-server ifmib internal cache max-duration 4
+ snmp-server mroutemib send-all-vrf
+ snmp-server notification-log-mib size 5
+ snmp-server notification-log-mib GlobalSize 5
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ vrfs=[
+ dict(
+ vrf="vrf1",
+ hosts=[
+ dict(
+ community="test1",
+ host="1.1.1.1",
+ traps=True,
+ ),
+ ],
+ ),
+ ],
+ users=[
+ dict(
+ Ipv4_acl="test1",
+ Ipv6_acl="test2",
+ group="test2",
+ user="u1",
+ v4_acl="v4acl",
+ ),
+ ],
+ timeouts=dict(
+ duplicate=0,
+ inQdrop=0,
+ pdu_stats=1,
+ subagent=1,
+ threshold=0,
+ ),
+ trap=dict(throttle_time=12),
+ targets=[
+ dict(name="test2", vrf="vrf2"),
+ dict(host="1.1.1.2", name="test"),
+ ],
+ ifmib=dict(internal_cache_max_duration=4),
+ inform=dict(retries=7),
+ chassis_id="test2",
+ packetsize=490,
+ queue_length=2,
+ throttle_time=60,
+ trap_source="GigabitEthernet0/0/0/2",
+ trap_timeout=3,
+ context=["c1", "c2"],
+ correlator=dict(
+ buffer_size=1024,
+ rule_sets=[dict(name="rule1")],
+ rules=[dict(rule_name="rule1", timeout=5)],
+ ),
+ communities=[
+ dict(
+ name="test2",
+ rw=True,
+ systemowner=True,
+ acl_v4="test",
+ acl_v6="test1",
+ ),
+ ],
+ community_maps=[
+ dict(
+ name="cm1",
+ context="c1",
+ target_list="t1",
+ security_name="s1",
+ ),
+ ],
+ drop=dict(report_IPv4="test1", unknown_user=True),
+ ipv6=dict(precedence="routine"),
+ ipv4=dict(dscp="af11"),
+ groups=[
+ dict(
+ Ipv4_acl="test",
+ Ipv6_acl="test1",
+ context="test3",
+ group="g2",
+ read="test1",
+ version="v1",
+ write="test2",
+ ),
+ ],
+ location="test1",
+ logging_threshold_oid_processing=1,
+ logging_threshold_pdu_processing=1,
+ mib_bulkstat_max_procmem_size=101,
+ mroutemib_send_all_vrf=True,
+ mib_object_lists=["test1"],
+ overload_control=dict(
+ overload_drop_time=4,
+ overload_throttle_rate=6,
+ ),
+ mib_schema=[
+ dict(
+ name="mib1",
+ object_list="test1",
+ poll_interval=1,
+ ),
+ ],
+ notification_log_mib=dict(GlobalSize=5, size=5),
+ mib_bulkstat_transfer_ids=[
+ dict(
+ buffer_size=1024,
+ enable=True,
+ format_schemaASCI=True,
+ name="test2",
+ retain=1,
+ retry=1,
+ schema="test2",
+ ),
+ ],
+ traps=dict(
+ diameter=dict(
+ peerdown=True,
+ peerup=True,
+ permanentfail=True,
+ protocolerror=True,
+ transientfail=True,
+ ),
+ entity=True,
+ entity_redundancy=dict(
+ all=True,
+ status=True,
+ switchover=True,
+ ),
+ entity_state=dict(operstatus=True, switchover=True),
+ flash=dict(insertion=True, removal=True),
+ hsrp=True,
+ ipsla=True,
+ ipsec=dict(start=True, stop=True),
+ bridgemib=True,
+ bulkstat_collection=True,
+ cisco_entity_ext=True,
+ config=True,
+ copy_complete=True,
+ addrpool=dict(high=True, low=True),
+ bfd=True,
+ bgp=dict(cbgp2=True),
+ l2tun=dict(
+ sessions=True,
+ tunnel_down=True,
+ tunnel_up=True,
+ ),
+ l2vpn=dict(all=True, vc_down=True, vc_up=True),
+ msdp_peer_state_change=True,
+ ospf=dict(
+ errors=dict(
+ authentication_failure=True,
+ bad_packet=True,
+ config_error=True,
+ virt_authentication_failure=True,
+ virt_bad_packet=True,
+ virt_config_error=True,
+ ),
+ lsa=dict(lsa_maxage=True, lsa_originate=True),
+ retransmit=dict(packets=True, virt_packets=True),
+ state_change=dict(
+ if_state_change=True,
+ neighbor_state_change=True,
+ virtif_state_change=True,
+ virtneighbor_state_change=True,
+ ),
+ ),
+ ospfv3=dict(
+ errors=dict(
+ bad_packet=True,
+ config_error=True,
+ virt_config_error=True,
+ ),
+ state_change=dict(
+ neighbor_state_change=True,
+ virtif_state_change=True,
+ virtneighbor_state_change=True,
+ restart_helper_status_change=True,
+ restart_status_change=True,
+ restart_virtual_helper_status_change=True,
+ ),
+ ),
+ pim=dict(
+ interface_state_change=True,
+ invalid_message_received=True,
+ neighbor_change=True,
+ rp_mapping_change=True,
+ ),
+ power=True,
+ rf=True,
+ rsvp=dict(all=True, lost_flow=True, new_flow=True),
+ selective_vrf_download_role_change=True,
+ sensor=True,
+ snmp=dict(
+ authentication=True,
+ coldstart=True,
+ linkdown=True,
+ linkup=True,
+ warmstart=True,
+ ),
+ subscriber=dict(
+ session_agg_access_interface=True,
+ session_agg_node=True,
+ ),
+ syslog=True,
+ system=True,
+ vpls=dict(
+ all=True,
+ full_clear=True,
+ full_raise=True,
+ status=True,
+ ),
+ vrrp_events=True,
+ ),
+ ),
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_snmp_server_merged(self):
+ self.maxDiff = None
+
+ set_module_args(
+ dict(
+ config=dict(
+ vrfs=[
+ dict(
+ vrf="vrf1",
+ hosts=[
+ dict(
+ community="test1",
+ host="1.1.1.1",
+ traps=True,
+ ),
+ ],
+ ),
+ ],
+ users=[
+ dict(
+ Ipv4_acl="test1",
+ Ipv6_acl="test2",
+ group="test2",
+ user="u1",
+ v4_acl="v4acl",
+ SystemOwner=True,
+ ),
+ ],
+ timeouts=dict(
+ duplicate=0,
+ inQdrop=0,
+ pdu_stats=1,
+ subagent=1,
+ threshold=0,
+ ),
+ trap=dict(throttle_time=12, link_ietf=True),
+ targets=[
+ dict(name="test2", vrf="vrf2"),
+ dict(host="1.1.1.2", name="test"),
+ ],
+ ifmib=dict(internal_cache_max_duration=4),
+ inform=dict(retries=7),
+ chassis_id="test2",
+ packetsize=490,
+ queue_length=2,
+ throttle_time=60,
+ trap_source="GigabitEthernet0/0/0/2",
+ trap_timeout=3,
+ context=["c1", "c2"],
+ correlator=dict(
+ buffer_size=1024,
+ rule_sets=[dict(name="rule1")],
+ rules=[dict(rule_name="rule1", timeout=5)],
+ ),
+ communities=[
+ dict(
+ name="test2",
+ ro=True,
+ sdrowner=True,
+ acl_v4="test",
+ acl_v6="test1",
+ ),
+ ],
+ community_maps=[
+ dict(
+ name="cm1",
+ context="c1",
+ target_list="t1",
+ security_name="s1",
+ ),
+ ],
+ drop=dict(report_IPv4="test1", unknown_user=True),
+ ipv6=dict(precedence="routine"),
+ ipv4=dict(dscp="af11"),
+ groups=[
+ dict(
+ Ipv4_acl="test",
+ Ipv6_acl="test1",
+ context="test3",
+ group="g2",
+ read="test1",
+ version="v1",
+ write="test2",
+ ),
+ ],
+ interfaces=[dict(name=" GigabitEthernet0/0/0/2")],
+ location="test1",
+ logging_threshold_oid_processing=1,
+ logging_threshold_pdu_processing=1,
+ mib_bulkstat_max_procmem_size=101,
+ mroutemib_send_all_vrf=True,
+ mib_object_lists=["test1"],
+ overload_control=dict(
+ overload_drop_time=4,
+ overload_throttle_rate=6,
+ ),
+ mib_schema=[
+ dict(
+ name="mib1",
+ object_list="test1",
+ poll_interval=1,
+ ),
+ ],
+ notification_log_mib=dict(GlobalSize=5, size=5),
+ mib_bulkstat_transfer_ids=[
+ dict(
+ buffer_size=1024,
+ enable=True,
+ format_schemaASCI=True,
+ name="test2",
+ retain=1,
+ retry=1,
+ schema="test2",
+ ),
+ ],
+ traps=dict(
+ diameter=dict(
+ peerdown=True,
+ peerup=True,
+ permanentfail=True,
+ protocolerror=True,
+ transientfail=True,
+ ),
+ entity=True,
+ entity_redundancy=dict(
+ all=True,
+ status=True,
+ switchover=True,
+ ),
+ entity_state=dict(operstatus=True, switchover=True),
+ flash=dict(insertion=True, removal=True),
+ hsrp=True,
+ ipsla=True,
+ ipsec=dict(start=True, stop=True),
+ bridgemib=True,
+ bulkstat_collection=True,
+ cisco_entity_ext=True,
+ config=True,
+ copy_complete=True,
+ addrpool=dict(high=True, low=True),
+ bfd=True,
+ bgp=dict(cbgp2=True),
+ l2tun=dict(
+ sessions=True,
+ tunnel_down=True,
+ tunnel_up=True,
+ ),
+ l2vpn=dict(all=True, vc_down=True, vc_up=True),
+ msdp_peer_state_change=True,
+ ospf=dict(
+ errors=dict(
+ authentication_failure=True,
+ bad_packet=True,
+ config_error=True,
+ virt_authentication_failure=True,
+ virt_bad_packet=True,
+ virt_config_error=True,
+ ),
+ lsa=dict(lsa_maxage=True, lsa_originate=True),
+ retransmit=dict(packets=True, virt_packets=True),
+ state_change=dict(
+ if_state_change=True,
+ neighbor_state_change=True,
+ virtif_state_change=True,
+ virtneighbor_state_change=True,
+ ),
+ ),
+ ospfv3=dict(
+ errors=dict(
+ bad_packet=True,
+ config_error=True,
+ virt_config_error=True,
+ ),
+ state_change=dict(
+ neighbor_state_change=True,
+ virtif_state_change=True,
+ virtneighbor_state_change=True,
+ restart_helper_status_change=True,
+ restart_status_change=True,
+ restart_virtual_helper_status_change=True,
+ ),
+ ),
+ pim=dict(
+ interface_state_change=True,
+ invalid_message_received=True,
+ neighbor_change=True,
+ rp_mapping_change=True,
+ ),
+ power=True,
+ rf=True,
+ rsvp=dict(all=True, lost_flow=True, new_flow=True),
+ selective_vrf_download_role_change=True,
+ sensor=True,
+ snmp=dict(
+ authentication=True,
+ coldstart=True,
+ linkdown=True,
+ linkup=True,
+ warmstart=True,
+ ),
+ subscriber=dict(
+ session_agg_access_interface=True,
+ session_agg_node=True,
+ ),
+ syslog=True,
+ system=True,
+ vpls=dict(
+ all=True,
+ full_clear=True,
+ full_raise=True,
+ status=True,
+ ),
+ vrrp_events=True,
+ isis=dict(
+ adjacency_change=True,
+ area_mismatch=True,
+ attempt_to_exceed_max_sequence=True,
+ authentication_failure=True,
+ authentication_type_failure=True,
+ corrupted_lsp_detected=True,
+ database_overload=True,
+ id_len_mismatch=True,
+ lsp_error_detected=True,
+ lsp_too_large_to_propagate=True,
+ manual_address_drops=True,
+ max_area_addresses_mismatch=True,
+ orig_lsp_buff_size_mismatch=True,
+ own_lsp_purge=True,
+ protocols_supported_mismatch=True,
+ rejected_adjacency=True,
+ sequence_number_skip=True,
+ version_skew=True,
+ ),
+ ),
+ ),
+ state="merged",
+ ),
+ )
+ commands = [
+ "snmp-server chassis-id test2",
+ "snmp-server correlator buffer-size 1024",
+ "snmp-server ipv4 dscp af11",
+ "snmp-server ipv6 precedence routine",
+ "snmp-server location test1",
+ "snmp-server logging threshold oid-processing 1",
+ "snmp-server logging threshold pdu-processing 1",
+ "snmp-server mib bulkstat max-procmem-size 101",
+ "snmp-server mroutemib send-all-vrf",
+ "snmp-server overload-control 4 6",
+ "snmp-server packetsize 490",
+ "snmp-server queue-length 2",
+ "snmp-server throttle-time 60",
+ "snmp-server trap-source GigabitEthernet0/0/0/2",
+ "snmp-server trap-timeout 3",
+ "snmp-server drop report acl IPv4 test1",
+ "snmp-server drop unknown-user",
+ "snmp-server ifmib internal cache max-duration 4",
+ "snmp-server inform retries 7",
+ "snmp-server notification-log-mib size 5",
+ "snmp-server notification-log-mib GlobalSize 5",
+ "snmp-server trap link ietf",
+ "snmp-server trap throttle-time 12",
+ "snmp-server timeouts threshold 0",
+ "snmp-server timeouts pdu stats 1",
+ "snmp-server timeouts subagent 1",
+ "snmp-server timeouts inQdrop 0",
+ "snmp-server timeouts duplicate 0",
+ "snmp-server traps addrpool low",
+ "snmp-server traps addrpool high",
+ "snmp-server traps bfd",
+ "snmp-server traps bgp cbgp2",
+ "snmp-server traps bulkstat collection",
+ "snmp-server traps bridgemib",
+ "snmp-server traps copy-complete",
+ "snmp-server traps cisco-entity-ext",
+ "snmp-server traps config",
+ "snmp-server traps diameter peerdown",
+ "snmp-server traps diameter peerup",
+ "snmp-server traps diameter protocolerror",
+ "snmp-server traps diameter permanentfail",
+ "snmp-server traps diameter transientfail",
+ "snmp-server traps entity",
+ "snmp-server traps entity-redundancy all",
+ "snmp-server traps entity-redundancy status",
+ "snmp-server traps entity-redundancy switchover",
+ "snmp-server traps entity-state operstatus",
+ "snmp-server traps entity-state switchover",
+ "snmp-server traps flash removal",
+ "snmp-server traps flash insertion",
+ "snmp-server traps hsrp",
+ "snmp-server traps ipsla",
+ "snmp-server traps ipsec tunnel start",
+ "snmp-server traps ipsec tunnel stop",
+ "snmp-server traps isis adjacency-change area-mismatch attempt-to-exceed-max-sequence "
+ "authentication-failure authentication-type-failure corrupted-lsp-detected database-overload "
+ "id-len-mismatch lsp-error-detected lsp-too-large-to-propagate manual-address-drops"
+ " max-area-addresses-mismatch orig-lsp-buff-size-mismatch version-skew own-lsp-purge"
+ " rejected-adjacency protocols-supported-mismatch sequence-number-skip",
+ "snmp-server traps l2tun sessions",
+ "snmp-server traps l2tun tunnel-up",
+ "snmp-server traps l2tun tunnel-down",
+ "snmp-server traps l2vpn all",
+ "snmp-server traps l2vpn vc-up",
+ "snmp-server traps l2vpn vc-down",
+ "snmp-server traps msdp peer-state-change",
+ "snmp-server traps ospf retransmit virt-packets",
+ "snmp-server traps ospf retransmit packets",
+ "snmp-server traps ospf lsa lsa-originate",
+ "snmp-server traps ospf lsa lsa-maxage",
+ "snmp-server traps ospf errors bad-packet",
+ "snmp-server traps ospf errors authentication-failure",
+ "snmp-server traps ospf errors config-error",
+ "snmp-server traps ospf errors virt-bad-packet",
+ "snmp-server traps ospf errors virt-authentication-failure",
+ "snmp-server traps ospf errors virt-config-error",
+ "snmp-server traps ospf state-change if-state-change",
+ "snmp-server traps ospf state-change neighbor-state-change",
+ "snmp-server traps ospf state-change virtif-state-change",
+ "snmp-server traps ospf state-change virtneighbor-state-change",
+ "snmp-server traps ospfv3 errors bad-packet",
+ "snmp-server traps ospfv3 errors config-error",
+ "snmp-server traps ospfv3 errors virt-config-error",
+ "snmp-server traps ospfv3 state-change neighbor-state-change",
+ "snmp-server traps ospfv3 state-change virtif-state-change",
+ "snmp-server traps ospfv3 state-change virtneighbor-state-change",
+ "snmp-server traps ospfv3 state-change restart-status-change",
+ "snmp-server traps ospfv3 state-change restart-helper-status-change",
+ "snmp-server traps ospfv3 state-change restart-virtual-helper-status-change",
+ "snmp-server traps power",
+ "snmp-server traps rf",
+ "snmp-server traps pim neighbor-change",
+ "snmp-server traps pim invalid-message-received",
+ "snmp-server traps pim rp-mapping-change",
+ "snmp-server traps pim interface-state-change",
+ "snmp-server traps rsvp lost-flow",
+ "snmp-server traps rsvp new-flow",
+ "snmp-server traps rsvp all",
+ "snmp-server traps selective-vrf-download role-change",
+ "snmp-server traps sensor",
+ "snmp-server traps vrrp events",
+ "snmp-server traps syslog",
+ "snmp-server traps system",
+ "snmp-server traps subscriber session-agg access-interface",
+ "snmp-server traps subscriber session-agg node",
+ "snmp-server traps vpls all",
+ "snmp-server traps vpls full-clear",
+ "snmp-server traps vpls full-raise",
+ "snmp-server traps vpls status",
+ "snmp-server traps snmp linkup",
+ "snmp-server traps snmp linkdown",
+ "snmp-server traps snmp coldstart",
+ "snmp-server traps snmp warmstart",
+ "snmp-server traps snmp authentication",
+ "snmp-server community test2 RO SDROwner IPv4 test IPv6 test1",
+ "snmp-server community-map cm1 context c1 security-name s1 target-list t1",
+ "snmp-server correlator ruleset rule1",
+ "snmp-server correlator rule rule1 timeout 5",
+ "snmp-server context c1",
+ "snmp-server context c2",
+ "snmp-server group g2 v1 read test1 write test2 context test3 IPv4 test IPv6 test1",
+ "snmp-server interface GigabitEthernet0/0/0/2",
+ "snmp-server mib bulkstat object-list test1",
+ "snmp-server mib bulkstat schema mib1 object-list test1",
+ "snmp-server mib bulkstat schema mib1 poll-interval 1",
+ "snmp-server mib bulkstat transfer-id test2 buffer-size 1024",
+ "snmp-server mib bulkstat transfer-id test2 enable",
+ "snmp-server mib bulkstat transfer-id test2 format schemaASCII",
+ "snmp-server mib bulkstat transfer-id test2 retain 1",
+ "snmp-server mib bulkstat transfer-id test2 retry 1",
+ "snmp-server mib bulkstat transfer-id test2 schema test2",
+ "snmp-server user u1 test2 IPv4 test1 IPv6 test2 v4acl SystemOwner",
+ "snmp-server target list test2 vrf vrf2",
+ "snmp-server target list test host 1.1.1.2",
+ "snmp-server vrf vrf1",
+ "host 1.1.1.1 traps test1",
+ ]
+ result = self.execute_module(changed=True)
+ print(result["commands"])
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_snmp_server_deleted(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ snmp-server vrf vrf1
+ host 1.1.1.1 traps test1
+ !
+ snmp-server drop report acl IPv4 test1
+ snmp-server drop unknown-user
+ snmp-server ipv4 dscp af11
+ snmp-server ipv6 precedence routine
+ snmp-server user u1 test2 v1 IPv4 test1 IPv6 test2 v4acl
+ snmp-server community test2 RW SystemOwner IPv4 test IPv6 test1
+ snmp-server group g2 v1 read test1 write test2 context test3 IPv4 test IPv6 test1
+ snmp-server queue-length 2
+ snmp-server trap-timeout 3
+ snmp-server trap throttle-time 12
+ snmp-server traps rf
+ snmp-server traps bfd
+ snmp-server traps bgp cbgp2
+ snmp-server traps pim neighbor-change
+ snmp-server traps pim invalid-message-received
+ snmp-server traps pim rp-mapping-change
+ snmp-server traps pim interface-state-change
+ snmp-server traps copy-complete
+ snmp-server traps hsrp
+ snmp-server traps ipsla
+ snmp-server traps msdp peer-state-change
+ snmp-server traps snmp linkup
+ snmp-server traps snmp linkdown
+ snmp-server traps snmp coldstart
+ snmp-server traps snmp warmstart
+ snmp-server traps snmp authentication
+ snmp-server traps vrrp events
+ snmp-server traps flash removal
+ snmp-server traps flash insertion
+ snmp-server traps ipsec tunnel stop
+ snmp-server traps ipsec tunnel start
+ snmp-server traps power
+ snmp-server traps config
+ snmp-server traps entity
+ snmp-server traps sensor
+ snmp-server traps selective-vrf-download role-change
+ snmp-server traps syslog
+ snmp-server traps system
+ snmp-server traps ospf lsa lsa-maxage
+ snmp-server traps ospf lsa lsa-originate
+ snmp-server traps ospf errors bad-packet
+ snmp-server traps ospf errors authentication-failure
+ snmp-server traps ospf errors config-error
+ snmp-server traps ospf errors virt-bad-packet
+ snmp-server traps ospf errors virt-authentication-failure
+ snmp-server traps ospf errors virt-config-error
+ snmp-server traps ospf retransmit packets
+ snmp-server traps ospf retransmit virt-packets
+ snmp-server traps ospf state-change if-state-change
+ snmp-server traps ospf state-change neighbor-state-change
+ snmp-server traps ospf state-change virtif-state-change
+ snmp-server traps ospf state-change virtneighbor-state-change
+ snmp-server traps rsvp all
+ snmp-server traps rsvp new-flow
+ snmp-server traps rsvp lost-flow
+ snmp-server traps l2tun sessions
+ snmp-server traps l2tun tunnel-up
+ snmp-server traps l2tun tunnel-down
+ snmp-server traps vpls all
+ snmp-server traps vpls status
+ snmp-server traps vpls full-clear
+ snmp-server traps vpls full-raise
+ snmp-server traps bulkstat collection
+ snmp-server traps diameter peerup
+ snmp-server traps diameter peerdown
+ snmp-server traps diameter protocolerror
+ snmp-server traps diameter permanentfail
+ snmp-server traps diameter transientfail
+ snmp-server traps l2vpn all
+ snmp-server traps l2vpn vc-up
+ snmp-server traps l2vpn vc-down
+ snmp-server traps bridgemib
+ snmp-server traps ospfv3 errors bad-packet
+ snmp-server traps ospfv3 errors config-error
+ snmp-server traps ospfv3 errors virt-config-error
+ snmp-server traps ospfv3 state-change neighbor-state-change
+ snmp-server traps ospfv3 state-change virtif-state-change
+ snmp-server traps ospfv3 state-change virtneighbor-state-change
+ snmp-server traps ospfv3 state-change restart-status-change
+ snmp-server traps ospfv3 state-change restart-helper-status-change
+ snmp-server traps ospfv3 state-change restart-virtual-helper-status-change
+ snmp-server traps subscriber session-agg node
+ snmp-server traps subscriber session-agg access-interface
+ snmp-server traps addrpool low
+ snmp-server traps addrpool high
+ snmp-server traps cisco-entity-ext
+ snmp-server traps entity-state operstatus
+ snmp-server traps entity-state switchover
+ snmp-server traps entity-redundancy all
+ snmp-server traps entity-redundancy status
+ snmp-server traps entity-redundancy switchover
+ snmp-server chassis-id test2
+ snmp-server contact t1
+ snmp-server location test1
+ snmp-server target list test host 1.1.1.2
+ snmp-server target list test2 vrf vrf2
+ snmp-server context c1
+ snmp-server context c2
+ snmp-server logging threshold oid-processing 1
+ snmp-server logging threshold pdu-processing 1
+ snmp-server mib bulkstat max-procmem-size 101
+ snmp-server mib bulkstat object-list test1
+ !
+ snmp-server timeouts duplicate 0
+ snmp-server timeouts inQdrop 0
+ snmp-server timeouts subagent 1
+ snmp-server timeouts pdu stats 1
+ snmp-server timeouts threshold 0
+ snmp-server packetsize 490
+ snmp-server correlator buffer-size 1024
+ snmp-server trap-source GigabitEthernet0/0/0/2
+ snmp-server throttle-time 60
+ snmp-server community-map cm1 context c1 security-name s1 target-list t1
+ snmp-server inform retries 7
+ snmp-server overload-control 4 6
+ snmp-server interface GigabitEthernet0/0/0/2
+ !
+ snmp-server ifmib internal cache max-duration 4
+ snmp-server mroutemib send-all-vrf
+ snmp-server notification-log-mib size 5
+ snmp-server notification-log-mib GlobalSize 5
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(state="deleted"))
+ commands = [
+ "no snmp-server chassis-id test2",
+ "no snmp-server correlator buffer-size 1024",
+ "no snmp-server contact t1",
+ "no snmp-server ipv4 dscp af11",
+ "no snmp-server ipv6 precedence routine",
+ "no snmp-server location test1",
+ "no snmp-server logging threshold oid-processing 1",
+ "no snmp-server logging threshold pdu-processing 1",
+ "no snmp-server mib bulkstat max-procmem-size 101",
+ "no snmp-server mroutemib send-all-vrf",
+ "no snmp-server overload-control 4 6",
+ "no snmp-server packetsize 490",
+ "no snmp-server queue-length 2",
+ "no snmp-server throttle-time 60",
+ "no snmp-server trap-source GigabitEthernet0/0/0/2",
+ "no snmp-server trap-timeout 3",
+ "no snmp-server drop report acl IPv4 test1",
+ "no snmp-server drop unknown-user",
+ "no snmp-server ifmib internal cache max-duration 4",
+ "no snmp-server inform retries 7",
+ "no snmp-server notification-log-mib size 5",
+ "no snmp-server notification-log-mib GlobalSize 5",
+ "no snmp-server trap throttle-time 12",
+ "no snmp-server timeouts threshold 0",
+ "no snmp-server timeouts pdu stats 1",
+ "no snmp-server timeouts subagent 1",
+ "no snmp-server timeouts inQdrop 0",
+ "no snmp-server timeouts duplicate 0",
+ "no snmp-server traps addrpool low",
+ "no snmp-server traps addrpool high",
+ "no snmp-server traps bfd",
+ "no snmp-server traps bgp cbgp2",
+ "no snmp-server traps bulkstat collection",
+ "no snmp-server traps bridgemib",
+ "no snmp-server traps copy-complete",
+ "no snmp-server traps cisco-entity-ext",
+ "no snmp-server traps config",
+ "no snmp-server traps diameter peerdown",
+ "no snmp-server traps diameter peerup",
+ "no snmp-server traps diameter protocolerror",
+ "no snmp-server traps diameter permanentfail",
+ "no snmp-server traps diameter transientfail",
+ "no snmp-server traps entity",
+ "no snmp-server traps entity-redundancy all",
+ "no snmp-server traps entity-redundancy status",
+ "no snmp-server traps entity-redundancy switchover",
+ "no snmp-server traps entity-state operstatus",
+ "no snmp-server traps entity-state switchover",
+ "no snmp-server traps flash removal",
+ "no snmp-server traps flash insertion",
+ "no snmp-server traps hsrp",
+ "no snmp-server traps ipsla",
+ "no snmp-server traps ipsec tunnel start",
+ "no snmp-server traps ipsec tunnel stop",
+ "no snmp-server traps l2tun sessions",
+ "no snmp-server traps l2tun tunnel-up",
+ "no snmp-server traps l2tun tunnel-down",
+ "no snmp-server traps l2vpn all",
+ "no snmp-server traps l2vpn vc-up",
+ "no snmp-server traps l2vpn vc-down",
+ "no snmp-server traps msdp peer-state-change",
+ "no snmp-server traps ospf retransmit virt-packets",
+ "no snmp-server traps ospf retransmit packets",
+ "no snmp-server traps ospf lsa lsa-originate",
+ "no snmp-server traps ospf lsa lsa-maxage",
+ "no snmp-server traps ospf errors bad-packet",
+ "no snmp-server traps ospf errors authentication-failure",
+ "no snmp-server traps ospf errors config-error",
+ "no snmp-server traps ospf errors virt-bad-packet",
+ "no snmp-server traps ospf errors virt-authentication-failure",
+ "no snmp-server traps ospf errors virt-config-error",
+ "no snmp-server traps ospf state-change if-state-change",
+ "no snmp-server traps ospf state-change neighbor-state-change",
+ "no snmp-server traps ospf state-change virtif-state-change",
+ "no snmp-server traps ospf state-change virtneighbor-state-change",
+ "no snmp-server traps ospfv3 errors bad-packet",
+ "no snmp-server traps ospfv3 errors config-error",
+ "no snmp-server traps ospfv3 errors virt-config-error",
+ "no snmp-server traps ospfv3 state-change neighbor-state-change",
+ "no snmp-server traps ospfv3 state-change virtif-state-change",
+ "no snmp-server traps ospfv3 state-change virtneighbor-state-change",
+ "no snmp-server traps ospfv3 state-change restart-status-change",
+ "no snmp-server traps ospfv3 state-change restart-helper-status-change",
+ "no snmp-server traps ospfv3 state-change restart-virtual-helper-status-change",
+ "no snmp-server traps power",
+ "no snmp-server traps rf",
+ "no snmp-server traps pim neighbor-change",
+ "no snmp-server traps pim invalid-message-received",
+ "no snmp-server traps pim rp-mapping-change",
+ "no snmp-server traps pim interface-state-change",
+ "no snmp-server traps rsvp lost-flow",
+ "no snmp-server traps rsvp new-flow",
+ "no snmp-server traps rsvp all",
+ "no snmp-server traps selective-vrf-download role-change",
+ "no snmp-server traps sensor",
+ "no snmp-server traps vrrp events",
+ "no snmp-server traps syslog",
+ "no snmp-server traps system",
+ "no snmp-server traps subscriber session-agg access-interface",
+ "no snmp-server traps subscriber session-agg node",
+ "no snmp-server traps vpls all",
+ "no snmp-server traps vpls full-clear",
+ "no snmp-server traps vpls full-raise",
+ "no snmp-server traps vpls status",
+ "no snmp-server traps snmp linkup",
+ "no snmp-server traps snmp linkdown",
+ "no snmp-server traps snmp coldstart",
+ "no snmp-server traps snmp warmstart",
+ "no snmp-server traps snmp authentication",
+ "no snmp-server community test2 RW SystemOwner IPv4 test IPv6 test1",
+ "no snmp-server community-map cm1 context c1 security-name s1 target-list t1",
+ "no snmp-server context c1",
+ "no snmp-server context c2",
+ "no snmp-server group g2 v1 read test1 write test2 context test3 IPv4 test IPv6 test1",
+ "no snmp-server interface GigabitEthernet0/0/0/2",
+ "no snmp-server mib bulkstat object-list test1",
+ "no snmp-server user u1 test2 v1 IPv4 test1 IPv6 test2 v4acl",
+ "no snmp-server target list test host 1.1.1.2",
+ "no snmp-server target list test2 vrf vrf2",
+ "no snmp-server vrf vrf1",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_snmp_server_replaced(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ snmp-server vrf vrf1
+ host 1.1.1.1 traps test1
+ !
+ snmp-server drop report acl IPv4 test1
+ snmp-server drop unknown-user
+ snmp-server ipv4 dscp af11
+ snmp-server ipv6 precedence routine
+ snmp-server user u1 test2 v1 IPv4 test1 IPv6 test2 v4acl
+ snmp-server community test2 RO SDROwner IPv4 test IPv6 test1
+ snmp-server group g2 v1 read test1 write test2 context test3 IPv4 test IPv6 test1
+ snmp-server queue-length 2
+ snmp-server trap-timeout 3
+ snmp-server trap throttle-time 12
+ snmp-server traps rf
+ snmp-server traps bfd
+ snmp-server traps bgp cbgp2
+ snmp-server traps pim neighbor-change
+ snmp-server traps pim invalid-message-received
+ snmp-server traps pim rp-mapping-change
+ snmp-server traps pim interface-state-change
+ snmp-server traps copy-complete
+ snmp-server traps hsrp
+ snmp-server traps ipsla
+ snmp-server traps msdp peer-state-change
+ snmp-server traps snmp linkup
+ snmp-server traps snmp linkdown
+ snmp-server traps snmp coldstart
+ snmp-server traps snmp warmstart
+ snmp-server traps snmp authentication
+ snmp-server traps vrrp events
+ snmp-server traps flash removal
+ snmp-server traps flash insertion
+ snmp-server traps ipsec tunnel stop
+ snmp-server traps ipsec tunnel start
+ snmp-server traps power
+ snmp-server traps config
+ snmp-server traps entity
+ snmp-server traps sensor
+ snmp-server traps selective-vrf-download role-change
+ snmp-server traps syslog
+ snmp-server traps system
+ snmp-server traps ospf lsa lsa-maxage
+ snmp-server traps ospf lsa lsa-originate
+ snmp-server traps ospf errors bad-packet
+ snmp-server traps ospf errors authentication-failure
+ snmp-server traps ospf errors config-error
+ snmp-server traps ospf errors virt-bad-packet
+ snmp-server traps ospf errors virt-authentication-failure
+ snmp-server traps ospf errors virt-config-error
+ snmp-server traps ospf retransmit packets
+ snmp-server traps ospf retransmit virt-packets
+ snmp-server traps ospf state-change if-state-change
+ snmp-server traps ospf state-change neighbor-state-change
+ snmp-server traps ospf state-change virtif-state-change
+ snmp-server traps ospf state-change virtneighbor-state-change
+ snmp-server traps rsvp all
+ snmp-server traps rsvp new-flow
+ snmp-server traps rsvp lost-flow
+ snmp-server traps l2tun sessions
+ snmp-server traps l2tun tunnel-up
+ snmp-server traps l2tun tunnel-down
+ snmp-server traps vpls all
+ snmp-server traps vpls status
+ snmp-server traps vpls full-clear
+ snmp-server traps vpls full-raise
+ snmp-server traps bulkstat collection
+ snmp-server traps diameter peerup
+ snmp-server traps diameter peerdown
+ snmp-server traps diameter protocolerror
+ snmp-server traps diameter permanentfail
+ snmp-server traps diameter transientfail
+ snmp-server traps l2vpn all
+ snmp-server traps l2vpn vc-up
+ snmp-server traps l2vpn vc-down
+ snmp-server traps bridgemib
+ snmp-server traps ospfv3 errors bad-packet
+ snmp-server traps ospfv3 errors config-error
+ snmp-server traps ospfv3 errors virt-config-error
+ snmp-server traps ospfv3 state-change neighbor-state-change
+ snmp-server traps ospfv3 state-change virtif-state-change
+ snmp-server traps ospfv3 state-change virtneighbor-state-change
+ snmp-server traps ospfv3 state-change restart-status-change
+ snmp-server traps ospfv3 state-change restart-helper-status-change
+ snmp-server traps ospfv3 state-change restart-virtual-helper-status-change
+ snmp-server traps subscriber session-agg node
+ snmp-server traps subscriber session-agg access-interface
+ snmp-server traps addrpool low
+ snmp-server traps addrpool high
+ snmp-server traps cisco-entity-ext
+ snmp-server traps entity-state operstatus
+ snmp-server traps entity-state switchover
+ snmp-server traps entity-redundancy all
+ snmp-server traps entity-redundancy status
+ snmp-server traps entity-redundancy switchover
+ snmp-server chassis-id test2
+ snmp-server contact t1
+ snmp-server location test1
+ snmp-server target list test host 1.1.1.2
+ snmp-server target list test2 vrf vrf2
+ snmp-server context c1
+ snmp-server context c2
+ snmp-server logging threshold oid-processing 1
+ snmp-server logging threshold pdu-processing 1
+ snmp-server mib bulkstat max-procmem-size 101
+ snmp-server mib bulkstat object-list test1
+ !
+ snmp-server mib bulkstat schema mib1
+ object-list test1
+ poll-interval 1
+ !
+ snmp-server mib bulkstat transfer-id test2
+ retry 1
+ buffer-size 1024
+ enable
+ format schemaASCII
+ retain 1
+ schema test2
+ !
+ snmp-server timeouts duplicate 0
+ snmp-server timeouts inQdrop 0
+ snmp-server timeouts subagent 1
+ snmp-server timeouts pdu stats 1
+ snmp-server timeouts threshold 0
+ snmp-server packetsize 490
+ snmp-server correlator rule rule1
+ timeout 5
+ !
+ snmp-server correlator ruleset rule1
+ !
+ snmp-server correlator buffer-size 1024
+ snmp-server trap-source GigabitEthernet0/0/0/2
+ snmp-server throttle-time 60
+ snmp-server community-map cm1 context c1 security-name s1 target-list t1
+ snmp-server inform retries 7
+ snmp-server overload-control 4 6
+ snmp-server ifmib internal cache max-duration 4
+ snmp-server mroutemib send-all-vrf
+ snmp-server notification-log-mib size 5
+ snmp-server notification-log-mib GlobalSize 5
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ vrfs=[
+ dict(
+ vrf="vrf2",
+ hosts=[
+ dict(
+ community="test1",
+ host="1.1.1.1",
+ traps=True,
+ ),
+ ],
+ ),
+ ],
+ users=[
+ dict(
+ Ipv4_acl="test1",
+ Ipv6_acl="test2",
+ group="test2",
+ user="u1",
+ v4_acl="v4acl",
+ ),
+ ],
+ timeouts=dict(
+ duplicate=0,
+ inQdrop=0,
+ pdu_stats=1,
+ subagent=1,
+ threshold=0,
+ ),
+ trap=dict(throttle_time=12),
+ targets=[
+ dict(name="test2", vrf="vrf2"),
+ dict(host="1.1.1.2", name="test"),
+ ],
+ ifmib=dict(internal_cache_max_duration=4),
+ inform=dict(retries=7),
+ chassis_id="test2",
+ packetsize=490,
+ queue_length=2,
+ throttle_time=60,
+ trap_source="GigabitEthernet0/0/0/2",
+ trap_timeout=3,
+ context=["c1", "c2"],
+ correlator=dict(
+ buffer_size=1024,
+ rule_sets=[dict(name="rule1")],
+ rules=[dict(rule_name="rule1", timeout=5)],
+ ),
+ communities=[
+ dict(
+ name="test2",
+ ro=True,
+ sdrowner=True,
+ acl_v4="test",
+ acl_v6="test1",
+ ),
+ ],
+ community_maps=[
+ dict(
+ name="cm1",
+ context="c1",
+ target_list="t1",
+ security_name="s1",
+ ),
+ ],
+ drop=dict(report_IPv4="test1", unknown_user=True),
+ ipv6=dict(precedence="routine"),
+ ipv4=dict(dscp="af11"),
+ groups=[
+ dict(
+ Ipv4_acl="test",
+ Ipv6_acl="test1",
+ context="test3",
+ group="g2",
+ read="test1",
+ version="v1",
+ write="test2",
+ ),
+ ],
+ location="test",
+ logging_threshold_oid_processing=2,
+ logging_threshold_pdu_processing=1,
+ mib_bulkstat_max_procmem_size=101,
+ mroutemib_send_all_vrf=True,
+ mib_object_lists=["test1"],
+ overload_control=dict(
+ overload_drop_time=4,
+ overload_throttle_rate=6,
+ ),
+ mib_schema=[
+ dict(
+ name="mib1",
+ object_list="test1",
+ poll_interval=1,
+ ),
+ ],
+ notification_log_mib=dict(GlobalSize=5, size=5),
+ mib_bulkstat_transfer_ids=[
+ dict(
+ buffer_size=1024,
+ enable=True,
+ format_schemaASCI=True,
+ name="test2",
+ retain=1,
+ retry=1,
+ schema="test2",
+ ),
+ ],
+ traps=dict(
+ diameter=dict(
+ peerdown=True,
+ peerup=True,
+ permanentfail=True,
+ protocolerror=True,
+ transientfail=True,
+ ),
+ entity=True,
+ entity_redundancy=dict(
+ all=True,
+ status=True,
+ switchover=True,
+ ),
+ entity_state=dict(operstatus=True, switchover=True),
+ flash=dict(insertion=True, removal=True),
+ ipsec=dict(start=True, stop=True),
+ bridgemib=True,
+ bulkstat_collection=True,
+ cisco_entity_ext=True,
+ config=True,
+ copy_complete=True,
+ addrpool=dict(high=True, low=True),
+ bfd=True,
+ bgp=dict(cbgp2=True),
+ l2tun=dict(
+ sessions=True,
+ tunnel_down=True,
+ tunnel_up=True,
+ ),
+ l2vpn=dict(all=True, vc_down=True, vc_up=True),
+ msdp_peer_state_change=True,
+ ospf=dict(
+ errors=dict(
+ authentication_failure=True,
+ bad_packet=True,
+ config_error=True,
+ virt_authentication_failure=True,
+ virt_bad_packet=True,
+ virt_config_error=True,
+ ),
+ lsa=dict(lsa_maxage=True, lsa_originate=True),
+ retransmit=dict(packets=True, virt_packets=True),
+ state_change=dict(
+ if_state_change=True,
+ neighbor_state_change=True,
+ virtif_state_change=True,
+ virtneighbor_state_change=True,
+ ),
+ ),
+ ospfv3=dict(
+ errors=dict(
+ bad_packet=True,
+ config_error=True,
+ virt_config_error=True,
+ ),
+ ),
+ pim=dict(
+ interface_state_change=True,
+ invalid_message_received=True,
+ neighbor_change=True,
+ rp_mapping_change=True,
+ ),
+ power=True,
+ rf=True,
+ rsvp=dict(all=True, lost_flow=True, new_flow=True),
+ selective_vrf_download_role_change=True,
+ sensor=True,
+ snmp=dict(
+ authentication=True,
+ coldstart=True,
+ linkdown=True,
+ linkup=True,
+ warmstart=True,
+ ),
+ subscriber=dict(
+ session_agg_access_interface=True,
+ session_agg_node=True,
+ ),
+ syslog=True,
+ system=True,
+ vpls=dict(
+ all=True,
+ full_clear=True,
+ full_raise=True,
+ status=True,
+ ),
+ vrrp_events=True,
+ ),
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "no snmp-server contact t1",
+ "no snmp-server traps hsrp",
+ "no snmp-server traps ipsla",
+ "no snmp-server traps ospfv3 state-change neighbor-state-change",
+ "no snmp-server traps ospfv3 state-change virtif-state-change",
+ "no snmp-server traps ospfv3 state-change virtneighbor-state-change",
+ "no snmp-server traps ospfv3 state-change restart-status-change",
+ "no snmp-server traps ospfv3 state-change restart-helper-status-change",
+ "no snmp-server traps ospfv3 state-change restart-virtual-helper-status-change",
+ "no snmp-server vrf vrf1",
+ "snmp-server location test",
+ "snmp-server logging threshold oid-processing 2",
+ "snmp-server user u1 test2 IPv4 test1 IPv6 test2 v4acl",
+ "snmp-server vrf vrf2",
+ "host 1.1.1.1 traps test1",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_snmp_server_replaced_idempotent(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ snmp-server vrf vrf1
+ host 1.1.1.1 traps test1
+ !
+ snmp-server drop report acl IPv4 test1
+ snmp-server drop unknown-user
+ snmp-server ipv4 dscp af11
+ snmp-server ipv6 precedence routine
+ snmp-server user u1 test2 v1 IPv4 test1 IPv6 test2 v4acl
+ snmp-server community test2 RW SystemOwner IPv4 test IPv6 test1
+ snmp-server group g2 v1 read test1 write test2 context test3 IPv4 test IPv6 test1
+ snmp-server queue-length 2
+ snmp-server trap-timeout 3
+ snmp-server trap throttle-time 12
+ snmp-server traps rf
+ snmp-server traps bfd
+ snmp-server traps bgp cbgp2
+ snmp-server traps pim neighbor-change
+ snmp-server traps pim invalid-message-received
+ snmp-server traps pim rp-mapping-change
+ snmp-server traps pim interface-state-change
+ snmp-server traps copy-complete
+ snmp-server traps hsrp
+ snmp-server traps ipsla
+ snmp-server traps msdp peer-state-change
+ snmp-server traps snmp linkup
+ snmp-server traps snmp linkdown
+ snmp-server traps snmp coldstart
+ snmp-server traps snmp warmstart
+ snmp-server traps snmp authentication
+ snmp-server traps vrrp events
+ snmp-server traps flash removal
+ snmp-server traps flash insertion
+ snmp-server traps ipsec tunnel stop
+ snmp-server traps ipsec tunnel start
+ snmp-server traps power
+ snmp-server traps config
+ snmp-server traps entity
+ snmp-server traps sensor
+ snmp-server traps selective-vrf-download role-change
+ snmp-server traps syslog
+ snmp-server traps system
+ snmp-server traps ospf lsa lsa-maxage
+ snmp-server traps ospf lsa lsa-originate
+ snmp-server traps ospf errors bad-packet
+ snmp-server traps ospf errors authentication-failure
+ snmp-server traps ospf errors config-error
+ snmp-server traps ospf errors virt-bad-packet
+ snmp-server traps ospf errors virt-authentication-failure
+ snmp-server traps ospf errors virt-config-error
+ snmp-server traps ospf retransmit packets
+ snmp-server traps ospf retransmit virt-packets
+ snmp-server traps ospf state-change if-state-change
+ snmp-server traps ospf state-change neighbor-state-change
+ snmp-server traps ospf state-change virtif-state-change
+ snmp-server traps ospf state-change virtneighbor-state-change
+ snmp-server traps rsvp all
+ snmp-server traps rsvp new-flow
+ snmp-server traps rsvp lost-flow
+ snmp-server traps l2tun sessions
+ snmp-server traps l2tun tunnel-up
+ snmp-server traps l2tun tunnel-down
+ snmp-server traps vpls all
+ snmp-server traps vpls status
+ snmp-server traps vpls full-clear
+ snmp-server traps vpls full-raise
+ snmp-server traps bulkstat collection
+ snmp-server traps diameter peerup
+ snmp-server traps diameter peerdown
+ snmp-server traps diameter protocolerror
+ snmp-server traps diameter permanentfail
+ snmp-server traps diameter transientfail
+ snmp-server traps l2vpn all
+ snmp-server traps l2vpn vc-up
+ snmp-server traps l2vpn vc-down
+ snmp-server traps bridgemib
+ snmp-server traps ospfv3 errors bad-packet
+ snmp-server traps ospfv3 errors config-error
+ snmp-server traps ospfv3 errors virt-config-error
+ snmp-server traps ospfv3 state-change neighbor-state-change
+ snmp-server traps ospfv3 state-change virtif-state-change
+ snmp-server traps ospfv3 state-change virtneighbor-state-change
+ snmp-server traps ospfv3 state-change restart-status-change
+ snmp-server traps ospfv3 state-change restart-helper-status-change
+ snmp-server traps ospfv3 state-change restart-virtual-helper-status-change
+ snmp-server traps subscriber session-agg node
+ snmp-server traps subscriber session-agg access-interface
+ snmp-server traps addrpool low
+ snmp-server traps addrpool high
+ snmp-server traps cisco-entity-ext
+ snmp-server traps entity-state operstatus
+ snmp-server traps entity-state switchover
+ snmp-server traps entity-redundancy all
+ snmp-server traps entity-redundancy status
+ snmp-server traps entity-redundancy switchover
+ snmp-server chassis-id test2
+ snmp-server location test1
+ snmp-server target list test host 1.1.1.2
+ snmp-server target list test2 vrf vrf2
+ snmp-server context c1
+ snmp-server context c2
+ snmp-server logging threshold oid-processing 1
+ snmp-server logging threshold pdu-processing 1
+ snmp-server mib bulkstat max-procmem-size 101
+ snmp-server mib bulkstat object-list test1
+ !
+ snmp-server mib bulkstat schema mib1
+ object-list test1
+ poll-interval 1
+ !
+ snmp-server mib bulkstat transfer-id test2
+ retry 1
+ buffer-size 1024
+ enable
+ format schemaASCII
+ retain 1
+ schema test2
+ !
+ snmp-server timeouts duplicate 0
+ snmp-server timeouts inQdrop 0
+ snmp-server timeouts subagent 1
+ snmp-server timeouts pdu stats 1
+ snmp-server timeouts threshold 0
+ snmp-server packetsize 490
+ snmp-server correlator rule rule1
+ timeout 5
+ !
+ snmp-server correlator ruleset rule1
+ !
+ snmp-server correlator buffer-size 1024
+ snmp-server trap-source GigabitEthernet0/0/0/2
+ snmp-server throttle-time 60
+ snmp-server community-map cm1 context c1 security-name s1 target-list t1
+ snmp-server inform retries 7
+ snmp-server overload-control 4 6
+ snmp-server ifmib internal cache max-duration 4
+ snmp-server mroutemib send-all-vrf
+ snmp-server notification-log-mib size 5
+ snmp-server notification-log-mib GlobalSize 5
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ vrfs=[
+ dict(
+ vrf="vrf1",
+ hosts=[
+ dict(
+ community="test1",
+ host="1.1.1.1",
+ traps=True,
+ ),
+ ],
+ ),
+ ],
+ users=[
+ dict(
+ Ipv4_acl="test1",
+ Ipv6_acl="test2",
+ group="test2",
+ user="u1",
+ v4_acl="v4acl",
+ version="v1",
+ ),
+ ],
+ timeouts=dict(
+ duplicate=0,
+ inQdrop=0,
+ pdu_stats=1,
+ subagent=1,
+ threshold=0,
+ ),
+ trap=dict(throttle_time=12),
+ targets=[
+ dict(name="test2", vrf="vrf2"),
+ dict(host="1.1.1.2", name="test"),
+ ],
+ ifmib=dict(internal_cache_max_duration=4),
+ inform=dict(retries=7),
+ chassis_id="test2",
+ packetsize=490,
+ queue_length=2,
+ throttle_time=60,
+ trap_source="GigabitEthernet0/0/0/2",
+ trap_timeout=3,
+ context=["c1", "c2"],
+ correlator=dict(
+ buffer_size=1024,
+ rule_sets=[dict(name="rule1")],
+ rules=[dict(rule_name="rule1", timeout=5)],
+ ),
+ communities=[
+ dict(
+ name="test2",
+ rw=True,
+ systemowner=True,
+ acl_v4="test",
+ acl_v6="test1",
+ ),
+ ],
+ community_maps=[
+ dict(
+ name="cm1",
+ context="c1",
+ target_list="t1",
+ security_name="s1",
+ ),
+ ],
+ drop=dict(report_IPv4="test1", unknown_user=True),
+ ipv6=dict(precedence="routine"),
+ ipv4=dict(dscp="af11"),
+ groups=[
+ dict(
+ Ipv4_acl="test",
+ Ipv6_acl="test1",
+ context="test3",
+ group="g2",
+ read="test1",
+ version="v1",
+ write="test2",
+ ),
+ ],
+ location="test1",
+ logging_threshold_oid_processing=1,
+ logging_threshold_pdu_processing=1,
+ mib_bulkstat_max_procmem_size=101,
+ mroutemib_send_all_vrf=True,
+ mib_object_lists=["test1"],
+ overload_control=dict(
+ overload_drop_time=4,
+ overload_throttle_rate=6,
+ ),
+ mib_schema=[
+ dict(
+ name="mib1",
+ object_list="test1",
+ poll_interval=1,
+ ),
+ ],
+ notification_log_mib=dict(GlobalSize=5, size=5),
+ mib_bulkstat_transfer_ids=[
+ dict(
+ buffer_size=1024,
+ enable=True,
+ format_schemaASCI=True,
+ name="test2",
+ retain=1,
+ retry=1,
+ schema="test2",
+ ),
+ ],
+ traps=dict(
+ diameter=dict(
+ peerdown=True,
+ peerup=True,
+ permanentfail=True,
+ protocolerror=True,
+ transientfail=True,
+ ),
+ entity=True,
+ entity_redundancy=dict(
+ all=True,
+ status=True,
+ switchover=True,
+ ),
+ entity_state=dict(operstatus=True, switchover=True),
+ flash=dict(insertion=True, removal=True),
+ hsrp=True,
+ ipsla=True,
+ ipsec=dict(start=True, stop=True),
+ bridgemib=True,
+ bulkstat_collection=True,
+ cisco_entity_ext=True,
+ config=True,
+ copy_complete=True,
+ addrpool=dict(high=True, low=True),
+ bfd=True,
+ bgp=dict(cbgp2=True),
+ l2tun=dict(
+ sessions=True,
+ tunnel_down=True,
+ tunnel_up=True,
+ ),
+ l2vpn=dict(all=True, vc_down=True, vc_up=True),
+ msdp_peer_state_change=True,
+ ospf=dict(
+ errors=dict(
+ authentication_failure=True,
+ bad_packet=True,
+ config_error=True,
+ virt_authentication_failure=True,
+ virt_bad_packet=True,
+ virt_config_error=True,
+ ),
+ lsa=dict(lsa_maxage=True, lsa_originate=True),
+ retransmit=dict(packets=True, virt_packets=True),
+ state_change=dict(
+ if_state_change=True,
+ neighbor_state_change=True,
+ virtif_state_change=True,
+ virtneighbor_state_change=True,
+ ),
+ ),
+ ospfv3=dict(
+ errors=dict(
+ bad_packet=True,
+ config_error=True,
+ virt_config_error=True,
+ ),
+ state_change=dict(
+ neighbor_state_change=True,
+ virtif_state_change=True,
+ virtneighbor_state_change=True,
+ restart_helper_status_change=True,
+ restart_status_change=True,
+ restart_virtual_helper_status_change=True,
+ ),
+ ),
+ pim=dict(
+ interface_state_change=True,
+ invalid_message_received=True,
+ neighbor_change=True,
+ rp_mapping_change=True,
+ ),
+ power=True,
+ rf=True,
+ rsvp=dict(all=True, lost_flow=True, new_flow=True),
+ selective_vrf_download_role_change=True,
+ sensor=True,
+ snmp=dict(
+ authentication=True,
+ coldstart=True,
+ linkdown=True,
+ linkup=True,
+ warmstart=True,
+ ),
+ subscriber=dict(
+ session_agg_access_interface=True,
+ session_agg_node=True,
+ ),
+ syslog=True,
+ system=True,
+ vpls=dict(
+ all=True,
+ full_clear=True,
+ full_raise=True,
+ status=True,
+ ),
+ vrrp_events=True,
+ ),
+ ),
+ state="replaced",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_snmp_server_overridden(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ snmp-server vrf vrf1
+ host 1.1.1.1 traps test1
+ !
+ snmp-server drop report acl IPv4 test1
+ snmp-server drop unknown-user
+ snmp-server ipv4 dscp af11
+ snmp-server ipv6 precedence routine
+ snmp-server user u1 test2 v1 IPv4 test1 IPv6 test2 v4acl
+ snmp-server community test2 RO SDROwner IPv4 test IPv6 test1
+ snmp-server group g2 v1 read test1 write test2 context test3 IPv4 test IPv6 test1
+ snmp-server queue-length 2
+ snmp-server trap-timeout 3
+ snmp-server trap throttle-time 12
+ snmp-server traps rf
+ snmp-server traps bfd
+ snmp-server traps bgp cbgp2
+ snmp-server traps pim neighbor-change
+ snmp-server traps pim invalid-message-received
+ snmp-server traps pim rp-mapping-change
+ snmp-server traps pim interface-state-change
+ snmp-server traps copy-complete
+ snmp-server traps hsrp
+ snmp-server traps ipsla
+ snmp-server traps msdp peer-state-change
+ snmp-server traps snmp linkup
+ snmp-server traps snmp linkdown
+ snmp-server traps snmp coldstart
+ snmp-server traps snmp warmstart
+ snmp-server traps snmp authentication
+ snmp-server traps vrrp events
+ snmp-server traps flash removal
+ snmp-server traps flash insertion
+ snmp-server traps ipsec tunnel stop
+ snmp-server traps ipsec tunnel start
+ snmp-server traps power
+ snmp-server traps config
+ snmp-server traps entity
+ snmp-server traps sensor
+ snmp-server traps selective-vrf-download role-change
+ snmp-server traps syslog
+ snmp-server traps system
+ snmp-server traps ospf lsa lsa-maxage
+ snmp-server traps ospf lsa lsa-originate
+ snmp-server traps ospf errors bad-packet
+ snmp-server traps ospf errors authentication-failure
+ snmp-server traps ospf errors config-error
+ snmp-server traps ospf errors virt-bad-packet
+ snmp-server traps ospf errors virt-authentication-failure
+ snmp-server traps ospf errors virt-config-error
+ snmp-server traps ospf retransmit packets
+ snmp-server traps ospf retransmit virt-packets
+ snmp-server traps ospf state-change if-state-change
+ snmp-server traps ospf state-change neighbor-state-change
+ snmp-server traps ospf state-change virtif-state-change
+ snmp-server traps ospf state-change virtneighbor-state-change
+ snmp-server traps rsvp all
+ snmp-server traps rsvp new-flow
+ snmp-server traps rsvp lost-flow
+ snmp-server traps l2tun sessions
+ snmp-server traps l2tun tunnel-up
+ snmp-server traps l2tun tunnel-down
+ snmp-server traps vpls all
+ snmp-server traps vpls status
+ snmp-server traps vpls full-clear
+ snmp-server traps vpls full-raise
+ snmp-server traps bulkstat collection
+ snmp-server traps diameter peerup
+ snmp-server traps diameter peerdown
+ snmp-server traps diameter protocolerror
+ snmp-server traps diameter permanentfail
+ snmp-server traps diameter transientfail
+ snmp-server traps l2vpn all
+ snmp-server traps l2vpn vc-up
+ snmp-server traps l2vpn vc-down
+ snmp-server traps bridgemib
+ snmp-server traps ospfv3 errors bad-packet
+ snmp-server traps ospfv3 errors config-error
+ snmp-server traps ospfv3 errors virt-config-error
+ snmp-server traps ospfv3 state-change neighbor-state-change
+ snmp-server traps ospfv3 state-change virtif-state-change
+ snmp-server traps ospfv3 state-change virtneighbor-state-change
+ snmp-server traps ospfv3 state-change restart-status-change
+ snmp-server traps ospfv3 state-change restart-helper-status-change
+ snmp-server traps ospfv3 state-change restart-virtual-helper-status-change
+ snmp-server traps subscriber session-agg node
+ snmp-server traps subscriber session-agg access-interface
+ snmp-server traps addrpool low
+ snmp-server traps addrpool high
+ snmp-server traps cisco-entity-ext
+ snmp-server traps entity-state operstatus
+ snmp-server traps entity-state switchover
+ snmp-server traps entity-redundancy all
+ snmp-server traps entity-redundancy status
+ snmp-server traps entity-redundancy switchover
+ snmp-server chassis-id test2
+ snmp-server contact t1
+ snmp-server location test1
+ snmp-server target list test host 1.1.1.2
+ snmp-server target list test2 vrf vrf2
+ snmp-server context c1
+ snmp-server context c2
+ snmp-server logging threshold oid-processing 1
+ snmp-server logging threshold pdu-processing 1
+ snmp-server mib bulkstat max-procmem-size 101
+ snmp-server mib bulkstat object-list test1
+ !
+ snmp-server mib bulkstat schema mib1
+ object-list test1
+ poll-interval 1
+ !
+ snmp-server mib bulkstat transfer-id test2
+ retry 1
+ buffer-size 1024
+ enable
+ format schemaASCII
+ retain 1
+ schema test2
+ !
+ snmp-server timeouts duplicate 0
+ snmp-server timeouts inQdrop 0
+ snmp-server timeouts subagent 1
+ snmp-server timeouts pdu stats 1
+ snmp-server timeouts threshold 0
+ snmp-server packetsize 490
+ snmp-server correlator rule rule1
+ timeout 5
+ !
+ snmp-server correlator ruleset rule1
+ !
+ snmp-server correlator buffer-size 1024
+ snmp-server trap-source GigabitEthernet0/0/0/2
+ snmp-server throttle-time 60
+ snmp-server community-map cm1 context c1 security-name s1 target-list t1
+ snmp-server inform retries 7
+ snmp-server overload-control 4 6
+ snmp-server ifmib internal cache max-duration 4
+ snmp-server mroutemib send-all-vrf
+ snmp-server notification-log-mib size 5
+ snmp-server notification-log-mib GlobalSize 5
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ vrfs=[
+ dict(
+ vrf="vrf2",
+ hosts=[
+ dict(
+ community="test1",
+ host="1.1.1.1",
+ traps=True,
+ ),
+ ],
+ ),
+ ],
+ users=[
+ dict(
+ Ipv4_acl="test1",
+ Ipv6_acl="test2",
+ group="test2",
+ user="u1",
+ v4_acl="v4acl",
+ ),
+ ],
+ timeouts=dict(
+ duplicate=0,
+ inQdrop=0,
+ pdu_stats=1,
+ subagent=1,
+ threshold=0,
+ ),
+ trap=dict(throttle_time=12),
+ targets=[
+ dict(name="test2", vrf="vrf2"),
+ dict(host="1.1.1.2", name="test"),
+ ],
+ ifmib=dict(internal_cache_max_duration=4),
+ inform=dict(retries=7),
+ chassis_id="test2",
+ packetsize=490,
+ queue_length=2,
+ throttle_time=60,
+ trap_source="GigabitEthernet0/0/0/2",
+ trap_timeout=3,
+ context=["c1", "c2"],
+ correlator=dict(
+ buffer_size=1024,
+ rule_sets=[dict(name="rule1")],
+ rules=[dict(rule_name="rule1", timeout=5)],
+ ),
+ communities=[
+ dict(
+ name="test2",
+ ro=True,
+ sdrowner=True,
+ acl_v4="test",
+ acl_v6="test1",
+ ),
+ ],
+ community_maps=[
+ dict(
+ name="cm1",
+ context="c1",
+ target_list="t1",
+ security_name="s1",
+ ),
+ ],
+ drop=dict(report_IPv4="test1", unknown_user=True),
+ ipv6=dict(precedence="routine"),
+ ipv4=dict(dscp="af11"),
+ groups=[
+ dict(
+ Ipv4_acl="test",
+ Ipv6_acl="test1",
+ context="test3",
+ group="g2",
+ read="test1",
+ version="v1",
+ write="test2",
+ ),
+ ],
+ location="test",
+ logging_threshold_oid_processing=2,
+ logging_threshold_pdu_processing=1,
+ mib_bulkstat_max_procmem_size=101,
+ mroutemib_send_all_vrf=True,
+ mib_object_lists=["test1"],
+ overload_control=dict(
+ overload_drop_time=4,
+ overload_throttle_rate=6,
+ ),
+ mib_schema=[
+ dict(
+ name="mib1",
+ object_list="test1",
+ poll_interval=1,
+ ),
+ ],
+ notification_log_mib=dict(GlobalSize=5, size=5),
+ mib_bulkstat_transfer_ids=[
+ dict(
+ buffer_size=1024,
+ enable=True,
+ format_schemaASCI=True,
+ name="test2",
+ retain=1,
+ retry=1,
+ schema="test2",
+ ),
+ ],
+ traps=dict(
+ diameter=dict(
+ peerdown=True,
+ peerup=True,
+ permanentfail=True,
+ protocolerror=True,
+ transientfail=True,
+ ),
+ entity=True,
+ entity_redundancy=dict(
+ all=True,
+ status=True,
+ switchover=True,
+ ),
+ entity_state=dict(operstatus=True, switchover=True),
+ flash=dict(insertion=True, removal=True),
+ ipsec=dict(start=True, stop=True),
+ bridgemib=True,
+ bulkstat_collection=True,
+ cisco_entity_ext=True,
+ config=True,
+ copy_complete=True,
+ addrpool=dict(high=True, low=True),
+ bfd=True,
+ bgp=dict(cbgp2=True),
+ l2tun=dict(
+ sessions=True,
+ tunnel_down=True,
+ tunnel_up=True,
+ ),
+ l2vpn=dict(all=True, vc_down=True, vc_up=True),
+ msdp_peer_state_change=True,
+ ospf=dict(
+ errors=dict(
+ authentication_failure=True,
+ bad_packet=True,
+ config_error=True,
+ virt_authentication_failure=True,
+ virt_bad_packet=True,
+ virt_config_error=True,
+ ),
+ lsa=dict(lsa_maxage=True, lsa_originate=True),
+ retransmit=dict(packets=True, virt_packets=True),
+ state_change=dict(
+ if_state_change=True,
+ neighbor_state_change=True,
+ virtif_state_change=True,
+ virtneighbor_state_change=True,
+ ),
+ ),
+ ospfv3=dict(
+ errors=dict(
+ bad_packet=True,
+ config_error=True,
+ virt_config_error=True,
+ ),
+ ),
+ pim=dict(
+ interface_state_change=True,
+ invalid_message_received=True,
+ neighbor_change=True,
+ rp_mapping_change=True,
+ ),
+ power=True,
+ rf=True,
+ rsvp=dict(all=True, lost_flow=True, new_flow=True),
+ selective_vrf_download_role_change=True,
+ sensor=True,
+ snmp=dict(
+ authentication=True,
+ coldstart=True,
+ linkdown=True,
+ linkup=True,
+ warmstart=True,
+ ),
+ subscriber=dict(
+ session_agg_access_interface=True,
+ session_agg_node=True,
+ ),
+ syslog=True,
+ system=True,
+ vpls=dict(
+ all=True,
+ full_clear=True,
+ full_raise=True,
+ status=True,
+ ),
+ vrrp_events=True,
+ ),
+ ),
+ state="overridden",
+ ),
+ )
+ commands = [
+ "no snmp-server contact t1",
+ "no snmp-server traps hsrp",
+ "no snmp-server traps ipsla",
+ "no snmp-server traps ospfv3 state-change neighbor-state-change",
+ "no snmp-server traps ospfv3 state-change virtif-state-change",
+ "no snmp-server traps ospfv3 state-change virtneighbor-state-change",
+ "no snmp-server traps ospfv3 state-change restart-status-change",
+ "no snmp-server traps ospfv3 state-change restart-helper-status-change",
+ "no snmp-server traps ospfv3 state-change restart-virtual-helper-status-change",
+ "no snmp-server vrf vrf1",
+ "snmp-server location test",
+ "snmp-server logging threshold oid-processing 2",
+ "snmp-server user u1 test2 IPv4 test1 IPv6 test2 v4acl",
+ "snmp-server vrf vrf2",
+ "host 1.1.1.1 traps test1",
+ ]
+ result = self.execute_module(changed=True)
+ self.assertEqual(sorted(result["commands"]), sorted(commands))
+
+ def test_iosxr_snmp_server_overridden_idempotent(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ snmp-server vrf vrf1
+ host 1.1.1.1 traps test1
+ !
+ snmp-server drop report acl IPv4 test1
+ snmp-server drop unknown-user
+ snmp-server ipv4 dscp af11
+ snmp-server ipv6 precedence routine
+ snmp-server user u1 test2 v1 IPv4 test1 IPv6 test2 v4acl
+ snmp-server community test2 RW SystemOwner IPv4 test IPv6 test1
+ snmp-server group g2 v1 read test1 write test2 context test3 IPv4 test IPv6 test1
+ snmp-server queue-length 2
+ snmp-server trap-timeout 3
+ snmp-server trap throttle-time 12
+ snmp-server traps rf
+ snmp-server traps bfd
+ snmp-server traps bgp cbgp2
+ snmp-server traps pim neighbor-change
+ snmp-server traps pim invalid-message-received
+ snmp-server traps pim rp-mapping-change
+ snmp-server traps pim interface-state-change
+ snmp-server traps copy-complete
+ snmp-server traps hsrp
+ snmp-server traps ipsla
+ snmp-server traps msdp peer-state-change
+ snmp-server traps snmp linkup
+ snmp-server traps snmp linkdown
+ snmp-server traps snmp coldstart
+ snmp-server traps snmp warmstart
+ snmp-server traps snmp authentication
+ snmp-server traps vrrp events
+ snmp-server traps flash removal
+ snmp-server traps flash insertion
+ snmp-server traps ipsec tunnel stop
+ snmp-server traps ipsec tunnel start
+ snmp-server traps power
+ snmp-server traps config
+ snmp-server traps entity
+ snmp-server traps sensor
+ snmp-server traps selective-vrf-download role-change
+ snmp-server traps syslog
+ snmp-server traps system
+ snmp-server traps ospf lsa lsa-maxage
+ snmp-server traps ospf lsa lsa-originate
+ snmp-server traps ospf errors bad-packet
+ snmp-server traps ospf errors authentication-failure
+ snmp-server traps ospf errors config-error
+ snmp-server traps ospf errors virt-bad-packet
+ snmp-server traps ospf errors virt-authentication-failure
+ snmp-server traps ospf errors virt-config-error
+ snmp-server traps ospf retransmit packets
+ snmp-server traps ospf retransmit virt-packets
+ snmp-server traps ospf state-change if-state-change
+ snmp-server traps ospf state-change neighbor-state-change
+ snmp-server traps ospf state-change virtif-state-change
+ snmp-server traps ospf state-change virtneighbor-state-change
+ snmp-server traps rsvp all
+ snmp-server traps rsvp new-flow
+ snmp-server traps rsvp lost-flow
+ snmp-server traps l2tun sessions
+ snmp-server traps l2tun tunnel-up
+ snmp-server traps l2tun tunnel-down
+ snmp-server traps vpls all
+ snmp-server traps vpls status
+ snmp-server traps vpls full-clear
+ snmp-server traps vpls full-raise
+ snmp-server traps bulkstat collection
+ snmp-server traps diameter peerup
+ snmp-server traps diameter peerdown
+ snmp-server traps diameter protocolerror
+ snmp-server traps diameter permanentfail
+ snmp-server traps diameter transientfail
+ snmp-server traps l2vpn all
+ snmp-server traps l2vpn vc-up
+ snmp-server traps l2vpn vc-down
+ snmp-server traps bridgemib
+ snmp-server traps ospfv3 errors bad-packet
+ snmp-server traps ospfv3 errors config-error
+ snmp-server traps ospfv3 errors virt-config-error
+ snmp-server traps ospfv3 state-change neighbor-state-change
+ snmp-server traps ospfv3 state-change virtif-state-change
+ snmp-server traps ospfv3 state-change virtneighbor-state-change
+ snmp-server traps ospfv3 state-change restart-status-change
+ snmp-server traps ospfv3 state-change restart-helper-status-change
+ snmp-server traps ospfv3 state-change restart-virtual-helper-status-change
+ snmp-server traps subscriber session-agg node
+ snmp-server traps subscriber session-agg access-interface
+ snmp-server traps addrpool low
+ snmp-server traps addrpool high
+ snmp-server traps cisco-entity-ext
+ snmp-server traps entity-state operstatus
+ snmp-server traps entity-state switchover
+ snmp-server traps entity-redundancy all
+ snmp-server traps entity-redundancy status
+ snmp-server traps entity-redundancy switchover
+ snmp-server chassis-id test2
+ snmp-server location test1
+ snmp-server target list test host 1.1.1.2
+ snmp-server target list test2 vrf vrf2
+ snmp-server context c1
+ snmp-server context c2
+ snmp-server logging threshold oid-processing 1
+ snmp-server logging threshold pdu-processing 1
+ snmp-server mib bulkstat max-procmem-size 101
+ snmp-server mib bulkstat object-list test1
+ !
+ snmp-server mib bulkstat schema mib1
+ object-list test1
+ poll-interval 1
+ !
+ snmp-server mib bulkstat transfer-id test2
+ retry 1
+ buffer-size 1024
+ enable
+ format schemaASCII
+ retain 1
+ schema test2
+ !
+ snmp-server timeouts duplicate 0
+ snmp-server timeouts inQdrop 0
+ snmp-server timeouts subagent 1
+ snmp-server timeouts pdu stats 1
+ snmp-server timeouts threshold 0
+ snmp-server packetsize 490
+ snmp-server correlator rule rule1
+ timeout 5
+ !
+ snmp-server correlator ruleset rule1
+ !
+ snmp-server correlator buffer-size 1024
+ snmp-server trap-source GigabitEthernet0/0/0/2
+ snmp-server throttle-time 60
+ snmp-server community-map cm1 context c1 security-name s1 target-list t1
+ snmp-server inform retries 7
+ snmp-server overload-control 4 6
+ snmp-server ifmib internal cache max-duration 4
+ snmp-server mroutemib send-all-vrf
+ snmp-server notification-log-mib size 5
+ snmp-server notification-log-mib GlobalSize 5
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(
+ dict(
+ config=dict(
+ vrfs=[
+ dict(
+ vrf="vrf1",
+ hosts=[
+ dict(
+ community="test1",
+ host="1.1.1.1",
+ traps=True,
+ ),
+ ],
+ ),
+ ],
+ users=[
+ dict(
+ Ipv4_acl="test1",
+ Ipv6_acl="test2",
+ group="test2",
+ user="u1",
+ v4_acl="v4acl",
+ version="v1",
+ ),
+ ],
+ timeouts=dict(
+ duplicate=0,
+ inQdrop=0,
+ pdu_stats=1,
+ subagent=1,
+ threshold=0,
+ ),
+ trap=dict(throttle_time=12),
+ targets=[
+ dict(name="test2", vrf="vrf2"),
+ dict(host="1.1.1.2", name="test"),
+ ],
+ ifmib=dict(internal_cache_max_duration=4),
+ inform=dict(retries=7),
+ chassis_id="test2",
+ packetsize=490,
+ queue_length=2,
+ throttle_time=60,
+ trap_source="GigabitEthernet0/0/0/2",
+ trap_timeout=3,
+ context=["c1", "c2"],
+ correlator=dict(
+ buffer_size=1024,
+ rule_sets=[dict(name="rule1")],
+ rules=[dict(rule_name="rule1", timeout=5)],
+ ),
+ communities=[
+ dict(
+ name="test2",
+ rw=True,
+ systemowner=True,
+ acl_v4="test",
+ acl_v6="test1",
+ ),
+ ],
+ community_maps=[
+ dict(
+ name="cm1",
+ context="c1",
+ target_list="t1",
+ security_name="s1",
+ ),
+ ],
+ drop=dict(report_IPv4="test1", unknown_user=True),
+ ipv6=dict(precedence="routine"),
+ ipv4=dict(dscp="af11"),
+ groups=[
+ dict(
+ Ipv4_acl="test",
+ Ipv6_acl="test1",
+ context="test3",
+ group="g2",
+ read="test1",
+ version="v1",
+ write="test2",
+ ),
+ ],
+ location="test1",
+ logging_threshold_oid_processing=1,
+ logging_threshold_pdu_processing=1,
+ mib_bulkstat_max_procmem_size=101,
+ mroutemib_send_all_vrf=True,
+ mib_object_lists=["test1"],
+ overload_control=dict(
+ overload_drop_time=4,
+ overload_throttle_rate=6,
+ ),
+ mib_schema=[
+ dict(
+ name="mib1",
+ object_list="test1",
+ poll_interval=1,
+ ),
+ ],
+ notification_log_mib=dict(GlobalSize=5, size=5),
+ mib_bulkstat_transfer_ids=[
+ dict(
+ buffer_size=1024,
+ enable=True,
+ format_schemaASCI=True,
+ name="test2",
+ retain=1,
+ retry=1,
+ schema="test2",
+ ),
+ ],
+ traps=dict(
+ diameter=dict(
+ peerdown=True,
+ peerup=True,
+ permanentfail=True,
+ protocolerror=True,
+ transientfail=True,
+ ),
+ entity=True,
+ entity_redundancy=dict(
+ all=True,
+ status=True,
+ switchover=True,
+ ),
+ entity_state=dict(operstatus=True, switchover=True),
+ flash=dict(insertion=True, removal=True),
+ hsrp=True,
+ ipsla=True,
+ ipsec=dict(start=True, stop=True),
+ bridgemib=True,
+ bulkstat_collection=True,
+ cisco_entity_ext=True,
+ config=True,
+ copy_complete=True,
+ addrpool=dict(high=True, low=True),
+ bfd=True,
+ bgp=dict(cbgp2=True),
+ l2tun=dict(
+ sessions=True,
+ tunnel_down=True,
+ tunnel_up=True,
+ ),
+ l2vpn=dict(all=True, vc_down=True, vc_up=True),
+ msdp_peer_state_change=True,
+ ospf=dict(
+ errors=dict(
+ authentication_failure=True,
+ bad_packet=True,
+ config_error=True,
+ virt_authentication_failure=True,
+ virt_bad_packet=True,
+ virt_config_error=True,
+ ),
+ lsa=dict(lsa_maxage=True, lsa_originate=True),
+ retransmit=dict(packets=True, virt_packets=True),
+ state_change=dict(
+ if_state_change=True,
+ neighbor_state_change=True,
+ virtif_state_change=True,
+ virtneighbor_state_change=True,
+ ),
+ ),
+ ospfv3=dict(
+ errors=dict(
+ bad_packet=True,
+ config_error=True,
+ virt_config_error=True,
+ ),
+ state_change=dict(
+ neighbor_state_change=True,
+ virtif_state_change=True,
+ virtneighbor_state_change=True,
+ restart_helper_status_change=True,
+ restart_status_change=True,
+ restart_virtual_helper_status_change=True,
+ ),
+ ),
+ pim=dict(
+ interface_state_change=True,
+ invalid_message_received=True,
+ neighbor_change=True,
+ rp_mapping_change=True,
+ ),
+ power=True,
+ rf=True,
+ rsvp=dict(all=True, lost_flow=True, new_flow=True),
+ selective_vrf_download_role_change=True,
+ sensor=True,
+ snmp=dict(
+ authentication=True,
+ coldstart=True,
+ linkdown=True,
+ linkup=True,
+ warmstart=True,
+ ),
+ subscriber=dict(
+ session_agg_access_interface=True,
+ session_agg_node=True,
+ ),
+ syslog=True,
+ system=True,
+ vpls=dict(
+ all=True,
+ full_clear=True,
+ full_raise=True,
+ status=True,
+ ),
+ vrrp_events=True,
+ ),
+ ),
+ state="overridden",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_snmp_server_rendered(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ config=dict(
+ vrfs=[
+ dict(
+ vrf="vrf1",
+ hosts=[
+ dict(
+ community="test1",
+ host="1.1.1.1",
+ traps=True,
+ ),
+ ],
+ ),
+ ],
+ users=[
+ dict(
+ Ipv4_acl="test1",
+ Ipv6_acl="test2",
+ group="test2",
+ user="u1",
+ v4_acl="v4acl",
+ ),
+ ],
+ timeouts=dict(
+ duplicate=0,
+ inQdrop=0,
+ pdu_stats=1,
+ subagent=1,
+ threshold=0,
+ ),
+ trap=dict(throttle_time=12),
+ targets=[
+ dict(name="test2", vrf="vrf2"),
+ dict(host="1.1.1.2", name="test"),
+ ],
+ ifmib=dict(internal_cache_max_duration=4),
+ inform=dict(retries=7),
+ chassis_id="test2",
+ packetsize=490,
+ queue_length=2,
+ throttle_time=60,
+ trap_source="GigabitEthernet0/0/0/2",
+ trap_timeout=3,
+ context=["c1", "c2"],
+ correlator=dict(
+ buffer_size=1024,
+ rule_sets=[dict(name="rule1")],
+ rules=[dict(rule_name="rule1", timeout=5)],
+ ),
+ communities=[
+ dict(
+ name="test2",
+ ro=True,
+ sdrowner=True,
+ acl_v4="test",
+ acl_v6="test1",
+ ),
+ ],
+ community_maps=[
+ dict(
+ name="cm1",
+ context="c1",
+ target_list="t1",
+ security_name="s1",
+ ),
+ ],
+ drop=dict(report_IPv4="test1", unknown_user=True),
+ ipv6=dict(precedence="routine"),
+ ipv4=dict(dscp="af11"),
+ groups=[
+ dict(
+ Ipv4_acl="test",
+ Ipv6_acl="test1",
+ context="test3",
+ group="g2",
+ read="test1",
+ version="v1",
+ write="test2",
+ ),
+ ],
+ interfaces=[dict(name=" GigabitEthernet0/0/0/2")],
+ location="test1",
+ logging_threshold_oid_processing=1,
+ logging_threshold_pdu_processing=1,
+ mib_bulkstat_max_procmem_size=101,
+ mroutemib_send_all_vrf=True,
+ mib_object_lists=["test1"],
+ overload_control=dict(
+ overload_drop_time=4,
+ overload_throttle_rate=6,
+ ),
+ mib_schema=[
+ dict(
+ name="mib1",
+ object_list="test1",
+ poll_interval=1,
+ ),
+ ],
+ notification_log_mib=dict(GlobalSize=5, size=5),
+ mib_bulkstat_transfer_ids=[
+ dict(
+ buffer_size=1024,
+ enable=True,
+ format_schemaASCI=True,
+ name="test2",
+ retain=1,
+ retry=1,
+ schema="test2",
+ ),
+ ],
+ traps=dict(
+ diameter=dict(
+ peerdown=True,
+ peerup=True,
+ permanentfail=True,
+ protocolerror=True,
+ transientfail=True,
+ ),
+ entity=True,
+ entity_redundancy=dict(
+ all=True,
+ status=True,
+ switchover=True,
+ ),
+ entity_state=dict(operstatus=True, switchover=True),
+ flash=dict(insertion=True, removal=True),
+ hsrp=True,
+ ipsla=True,
+ ipsec=dict(start=True, stop=True),
+ bridgemib=True,
+ bulkstat_collection=True,
+ cisco_entity_ext=True,
+ config=True,
+ copy_complete=True,
+ addrpool=dict(high=True, low=True),
+ bfd=True,
+ bgp=dict(cbgp2=True),
+ l2tun=dict(
+ sessions=True,
+ tunnel_down=True,
+ tunnel_up=True,
+ ),
+ l2vpn=dict(all=True, vc_down=True, vc_up=True),
+ msdp_peer_state_change=True,
+ ospf=dict(
+ errors=dict(
+ authentication_failure=True,
+ bad_packet=True,
+ config_error=True,
+ virt_authentication_failure=True,
+ virt_bad_packet=True,
+ virt_config_error=True,
+ ),
+ lsa=dict(lsa_maxage=True, lsa_originate=True),
+ retransmit=dict(packets=True, virt_packets=True),
+ state_change=dict(
+ if_state_change=True,
+ neighbor_state_change=True,
+ virtif_state_change=True,
+ virtneighbor_state_change=True,
+ ),
+ ),
+ ospfv3=dict(
+ errors=dict(
+ bad_packet=True,
+ config_error=True,
+ virt_config_error=True,
+ ),
+ state_change=dict(
+ neighbor_state_change=True,
+ virtif_state_change=True,
+ virtneighbor_state_change=True,
+ restart_helper_status_change=True,
+ restart_status_change=True,
+ restart_virtual_helper_status_change=True,
+ ),
+ ),
+ pim=dict(
+ interface_state_change=True,
+ invalid_message_received=True,
+ neighbor_change=True,
+ rp_mapping_change=True,
+ ),
+ power=True,
+ rf=True,
+ rsvp=dict(all=True, lost_flow=True, new_flow=True),
+ selective_vrf_download_role_change=True,
+ sensor=True,
+ snmp=dict(
+ authentication=True,
+ coldstart=True,
+ linkdown=True,
+ linkup=True,
+ warmstart=True,
+ ),
+ subscriber=dict(
+ session_agg_access_interface=True,
+ session_agg_node=True,
+ ),
+ syslog=True,
+ system=True,
+ vpls=dict(
+ all=True,
+ full_clear=True,
+ full_raise=True,
+ status=True,
+ ),
+ vrrp_events=True,
+ ),
+ ),
+ state="rendered",
+ ),
+ )
+ commands = [
+ "snmp-server chassis-id test2",
+ "snmp-server correlator buffer-size 1024",
+ "snmp-server ipv4 dscp af11",
+ "snmp-server ipv6 precedence routine",
+ "snmp-server location test1",
+ "snmp-server logging threshold oid-processing 1",
+ "snmp-server logging threshold pdu-processing 1",
+ "snmp-server mib bulkstat max-procmem-size 101",
+ "snmp-server mroutemib send-all-vrf",
+ "snmp-server overload-control 4 6",
+ "snmp-server packetsize 490",
+ "snmp-server queue-length 2",
+ "snmp-server throttle-time 60",
+ "snmp-server trap-source GigabitEthernet0/0/0/2",
+ "snmp-server trap-timeout 3",
+ "snmp-server drop report acl IPv4 test1",
+ "snmp-server drop unknown-user",
+ "snmp-server ifmib internal cache max-duration 4",
+ "snmp-server inform retries 7",
+ "snmp-server notification-log-mib size 5",
+ "snmp-server notification-log-mib GlobalSize 5",
+ "snmp-server trap throttle-time 12",
+ "snmp-server timeouts threshold 0",
+ "snmp-server timeouts pdu stats 1",
+ "snmp-server timeouts subagent 1",
+ "snmp-server timeouts inQdrop 0",
+ "snmp-server timeouts duplicate 0",
+ "snmp-server traps addrpool low",
+ "snmp-server traps addrpool high",
+ "snmp-server traps bfd",
+ "snmp-server traps bgp cbgp2",
+ "snmp-server traps bulkstat collection",
+ "snmp-server traps bridgemib",
+ "snmp-server traps copy-complete",
+ "snmp-server traps cisco-entity-ext",
+ "snmp-server traps config",
+ "snmp-server traps diameter peerdown",
+ "snmp-server traps diameter peerup",
+ "snmp-server traps diameter protocolerror",
+ "snmp-server traps diameter permanentfail",
+ "snmp-server traps diameter transientfail",
+ "snmp-server traps entity",
+ "snmp-server traps entity-redundancy all",
+ "snmp-server traps entity-redundancy status",
+ "snmp-server traps entity-redundancy switchover",
+ "snmp-server traps entity-state operstatus",
+ "snmp-server traps entity-state switchover",
+ "snmp-server traps flash removal",
+ "snmp-server traps flash insertion",
+ "snmp-server traps hsrp",
+ "snmp-server traps ipsla",
+ "snmp-server traps ipsec tunnel start",
+ "snmp-server traps ipsec tunnel stop",
+ "snmp-server traps l2tun sessions",
+ "snmp-server traps l2tun tunnel-up",
+ "snmp-server traps l2tun tunnel-down",
+ "snmp-server traps l2vpn all",
+ "snmp-server traps l2vpn vc-up",
+ "snmp-server traps l2vpn vc-down",
+ "snmp-server traps msdp peer-state-change",
+ "snmp-server traps ospf retransmit virt-packets",
+ "snmp-server traps ospf retransmit packets",
+ "snmp-server traps ospf lsa lsa-originate",
+ "snmp-server traps ospf lsa lsa-maxage",
+ "snmp-server traps ospf errors bad-packet",
+ "snmp-server traps ospf errors authentication-failure",
+ "snmp-server traps ospf errors config-error",
+ "snmp-server traps ospf errors virt-bad-packet",
+ "snmp-server traps ospf errors virt-authentication-failure",
+ "snmp-server traps ospf errors virt-config-error",
+ "snmp-server traps ospf state-change if-state-change",
+ "snmp-server traps ospf state-change neighbor-state-change",
+ "snmp-server traps ospf state-change virtif-state-change",
+ "snmp-server traps ospf state-change virtneighbor-state-change",
+ "snmp-server traps ospfv3 errors bad-packet",
+ "snmp-server traps ospfv3 errors config-error",
+ "snmp-server traps ospfv3 errors virt-config-error",
+ "snmp-server traps ospfv3 state-change neighbor-state-change",
+ "snmp-server traps ospfv3 state-change virtif-state-change",
+ "snmp-server traps ospfv3 state-change virtneighbor-state-change",
+ "snmp-server traps ospfv3 state-change restart-status-change",
+ "snmp-server traps ospfv3 state-change restart-helper-status-change",
+ "snmp-server traps ospfv3 state-change restart-virtual-helper-status-change",
+ "snmp-server traps power",
+ "snmp-server traps rf",
+ "snmp-server traps pim neighbor-change",
+ "snmp-server traps pim invalid-message-received",
+ "snmp-server traps pim rp-mapping-change",
+ "snmp-server traps pim interface-state-change",
+ "snmp-server traps rsvp lost-flow",
+ "snmp-server traps rsvp new-flow",
+ "snmp-server traps rsvp all",
+ "snmp-server traps selective-vrf-download role-change",
+ "snmp-server traps sensor",
+ "snmp-server traps vrrp events",
+ "snmp-server traps syslog",
+ "snmp-server traps system",
+ "snmp-server traps subscriber session-agg access-interface",
+ "snmp-server traps subscriber session-agg node",
+ "snmp-server traps vpls all",
+ "snmp-server traps vpls full-clear",
+ "snmp-server traps vpls full-raise",
+ "snmp-server traps vpls status",
+ "snmp-server traps snmp linkup",
+ "snmp-server traps snmp linkdown",
+ "snmp-server traps snmp coldstart",
+ "snmp-server traps snmp warmstart",
+ "snmp-server traps snmp authentication",
+ "snmp-server community test2 RO SDROwner IPv4 test IPv6 test1",
+ "snmp-server community-map cm1 context c1 security-name s1 target-list t1",
+ "snmp-server correlator ruleset rule1",
+ "snmp-server correlator rule rule1 timeout 5",
+ "snmp-server context c1",
+ "snmp-server context c2",
+ "snmp-server group g2 v1 read test1 write test2 context test3 IPv4 test IPv6 test1",
+ "snmp-server interface GigabitEthernet0/0/0/2",
+ "snmp-server mib bulkstat object-list test1",
+ "snmp-server mib bulkstat schema mib1 object-list test1",
+ "snmp-server mib bulkstat schema mib1 poll-interval 1",
+ "snmp-server mib bulkstat transfer-id test2 buffer-size 1024",
+ "snmp-server mib bulkstat transfer-id test2 enable",
+ "snmp-server mib bulkstat transfer-id test2 format schemaASCII",
+ "snmp-server mib bulkstat transfer-id test2 retain 1",
+ "snmp-server mib bulkstat transfer-id test2 retry 1",
+ "snmp-server mib bulkstat transfer-id test2 schema test2",
+ "snmp-server user u1 test2 IPv4 test1 IPv6 test2 v4acl",
+ "snmp-server target list test2 vrf vrf2",
+ "snmp-server target list test host 1.1.1.2",
+ "snmp-server vrf vrf1",
+ "host 1.1.1.1 traps test1",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(sorted(result["rendered"]), sorted(commands))
+
+ def test_iosxr_snmp_server_gathered(self):
+ self.maxDiff = None
+ run_cfg = dedent(
+ """\
+ snmp-server vrf vrf1
+ host 1.1.1.1 traps test1
+ !
+ snmp-server drop report acl IPv4 test1
+ snmp-server drop unknown-user
+ snmp-server ipv4 dscp af11
+ snmp-server ipv6 precedence routine
+ snmp-server user u1 test2 v1 IPv4 test1 IPv6 test2 v4acl
+ snmp-server community test2 RO SDROwner IPv4 test IPv6 test1
+ snmp-server group g2 v1 read test1 write test2 context test3 IPv4 test IPv6 test1
+ snmp-server queue-length 2
+ snmp-server trap-timeout 3
+ snmp-server trap throttle-time 12
+ snmp-server traps rf
+ snmp-server traps bfd
+ snmp-server traps bgp cbgp2
+ snmp-server traps pim neighbor-change
+ snmp-server traps pim invalid-message-received
+ snmp-server traps pim rp-mapping-change
+ snmp-server traps pim interface-state-change
+ snmp-server traps copy-complete
+ snmp-server traps hsrp
+ snmp-server traps ipsla
+ snmp-server traps msdp peer-state-change
+ snmp-server traps snmp linkup
+ snmp-server traps snmp linkdown
+ snmp-server traps snmp coldstart
+ snmp-server traps snmp warmstart
+ snmp-server traps snmp authentication
+ snmp-server traps vrrp events
+ snmp-server traps flash removal
+ snmp-server traps flash insertion
+ snmp-server traps ipsec tunnel stop
+ snmp-server traps ipsec tunnel start
+ snmp-server traps power
+ snmp-server traps config
+ snmp-server traps entity
+ snmp-server traps sensor
+ snmp-server traps selective-vrf-download role-change
+ snmp-server traps syslog
+ snmp-server traps system
+ snmp-server traps ospf lsa lsa-maxage
+ snmp-server traps ospf lsa lsa-originate
+ snmp-server traps ospf errors bad-packet
+ snmp-server traps ospf errors authentication-failure
+ snmp-server traps ospf errors config-error
+ snmp-server traps ospf errors virt-bad-packet
+ snmp-server traps ospf errors virt-authentication-failure
+ snmp-server traps ospf errors virt-config-error
+ snmp-server traps ospf retransmit packets
+ snmp-server traps ospf retransmit virt-packets
+ snmp-server traps ospf state-change if-state-change
+ snmp-server traps ospf state-change neighbor-state-change
+ snmp-server traps ospf state-change virtif-state-change
+ snmp-server traps ospf state-change virtneighbor-state-change
+ snmp-server traps rsvp all
+ snmp-server traps rsvp new-flow
+ snmp-server traps rsvp lost-flow
+ snmp-server traps l2tun sessions
+ snmp-server traps l2tun tunnel-up
+ snmp-server traps l2tun tunnel-down
+ snmp-server traps vpls all
+ snmp-server traps vpls status
+ snmp-server traps vpls full-clear
+ snmp-server traps vpls full-raise
+ snmp-server traps bulkstat collection
+ snmp-server traps diameter peerup
+ snmp-server traps diameter peerdown
+ snmp-server traps diameter protocolerror
+ snmp-server traps diameter permanentfail
+ snmp-server traps diameter transientfail
+ snmp-server traps l2vpn all
+ snmp-server traps l2vpn vc-up
+ snmp-server traps l2vpn vc-down
+ snmp-server traps bridgemib
+ snmp-server traps ospfv3 errors bad-packet
+ snmp-server traps ospfv3 errors config-error
+ snmp-server traps ospfv3 errors virt-config-error
+ snmp-server traps ospfv3 state-change neighbor-state-change
+ snmp-server traps ospfv3 state-change virtif-state-change
+ snmp-server traps ospfv3 state-change virtneighbor-state-change
+ snmp-server traps ospfv3 state-change restart-status-change
+ snmp-server traps ospfv3 state-change restart-helper-status-change
+ snmp-server traps ospfv3 state-change restart-virtual-helper-status-change
+ snmp-server traps subscriber session-agg node
+ snmp-server traps subscriber session-agg access-interface
+ snmp-server traps addrpool low
+ snmp-server traps addrpool high
+ snmp-server traps cisco-entity-ext
+ snmp-server traps entity-state operstatus
+ snmp-server traps entity-state switchover
+ snmp-server traps entity-redundancy all
+ snmp-server traps entity-redundancy status
+ snmp-server traps entity-redundancy switchover
+ snmp-server chassis-id test2
+ snmp-server contact t1
+ snmp-server location test1
+ snmp-server target list test host 1.1.1.2
+ snmp-server target list test2 vrf vrf2
+ snmp-server context c1
+ snmp-server logging threshold oid-processing 1
+ snmp-server logging threshold pdu-processing 1
+ snmp-server mib bulkstat max-procmem-size 101
+ snmp-server mib bulkstat object-list test1
+ !
+ snmp-server mib bulkstat schema mib1
+ object-list test1
+ poll-interval 1
+ !
+ snmp-server mib bulkstat transfer-id test2
+ retry 1
+ buffer-size 1024
+ enable
+ format schemaASCII
+ retain 1
+ schema test2
+ !
+ snmp-server timeouts duplicate 0
+ snmp-server timeouts inQdrop 0
+ snmp-server timeouts subagent 1
+ snmp-server timeouts pdu stats 1
+ snmp-server timeouts threshold 0
+ snmp-server packetsize 490
+ snmp-server correlator rule rule1
+ timeout 5
+ !
+ snmp-server correlator ruleset rule1
+ !
+ snmp-server correlator buffer-size 1024
+ snmp-server trap-source GigabitEthernet0/0/0/2
+ snmp-server throttle-time 60
+ snmp-server community-map cm1 context c1 security-name s1 target-list t1
+ snmp-server inform retries 7
+ snmp-server overload-control 4 6
+ snmp-server ifmib internal cache max-duration 4
+ snmp-server mroutemib send-all-vrf
+ snmp-server notification-log-mib size 5
+ snmp-server notification-log-mib GlobalSize 5
+ !
+ """,
+ )
+ self.get_config.return_value = run_cfg
+ set_module_args(dict(state="gathered"))
+ gathered = {
+ "vrfs": [
+ {
+ "vrf": "vrf1",
+ "hosts": [
+ {
+ "host": "1.1.1.1",
+ "traps": True,
+ "community": "test1",
+ },
+ ],
+ },
+ ],
+ "drop": {"report_IPv4": "test1", "unknown_user": True},
+ "ipv4": {"dscp": "af11"},
+ "ipv6": {"precedence": "routine"},
+ "users": [
+ {
+ "user": "u1",
+ "group": "test2",
+ "acl_v4": "test1",
+ "acl_v6": "test2",
+ "v4_acl": "v4acl",
+ "version": "v1",
+ },
+ ],
+ "communities": [
+ {
+ "name": "test2",
+ "ro": True,
+ "acl_v4": "test",
+ "acl_v6": "test1",
+ "sdrowner": True,
+ },
+ ],
+ "groups": [
+ {
+ "group": "g2",
+ "acl_v4": "test",
+ "acl_v6": "test1",
+ "context": "test3",
+ "read": "test1",
+ "write": "test2",
+ "version": "v1",
+ },
+ ],
+ "queue_length": 2,
+ "trap_timeout": 3,
+ "trap": {"throttle_time": 12},
+ "traps": {
+ "rf": True,
+ "bfd": True,
+ "bgp": {"cbgp2": True},
+ "pim": {
+ "neighbor_change": True,
+ "invalid_message_received": True,
+ "rp_mapping_change": True,
+ "interface_state_change": True,
+ },
+ "copy_complete": True,
+ "hsrp": True,
+ "ipsla": True,
+ "msdp_peer_state_change": True,
+ "snmp": {
+ "linkup": True,
+ "linkdown": True,
+ "coldstart": True,
+ "warmstart": True,
+ "authentication": True,
+ },
+ "vrrp_events": True,
+ "flash": {"removal": True, "insertion": True},
+ "ipsec": {"stop": True, "start": True},
+ "power": True,
+ "config": True,
+ "entity": True,
+ "sensor": True,
+ "selective_vrf_download_role_change": True,
+ "syslog": True,
+ "system": True,
+ "ospf": {
+ "lsa": {"lsa_maxage": True, "lsa_originate": True},
+ "errors": {
+ "bad_packet": True,
+ "authentication_failure": True,
+ "config_error": True,
+ "virt_bad_packet": True,
+ "virt_authentication_failure": True,
+ "virt_config_error": True,
+ },
+ "retransmit": {"packets": True, "virt_packets": True},
+ "state_change": {
+ "if_state_change": True,
+ "neighbor_state_change": True,
+ "virtif_state_change": True,
+ "virtneighbor_state_change": True,
+ },
+ },
+ "rsvp": {"all": True, "new_flow": True, "lost_flow": True},
+ "l2tun": {
+ "sessions": True,
+ "tunnel_up": True,
+ "tunnel_down": True,
+ },
+ "vpls": {
+ "all": True,
+ "status": True,
+ "full_clear": True,
+ "full_raise": True,
+ },
+ "bulkstat_collection": True,
+ "diameter": {
+ "peerup": True,
+ "peerdown": True,
+ "protocolerror": True,
+ "permanentfail": True,
+ "transientfail": True,
+ },
+ "l2vpn": {"all": True, "vc_up": True, "vc_down": True},
+ "bridgemib": True,
+ "ospfv3": {
+ "errors": {
+ "bad_packet": True,
+ "config_error": True,
+ "virt_config_error": True,
+ },
+ "state_change": {
+ "neighbor_state_change": True,
+ "virtif_state_change": True,
+ "virtneighbor_state_change": True,
+ "restart_status_change": True,
+ "restart_helper_status_change": True,
+ "restart_virtual_helper_status_change": True,
+ },
+ },
+ "subscriber": {
+ "session_agg_node": True,
+ "session_agg_access_interface": True,
+ },
+ "addrpool": {"low": True, "high": True},
+ "cisco_entity_ext": True,
+ "entity_state": {"operstatus": True, "switchover": True},
+ "entity_redundancy": {
+ "all": True,
+ "status": True,
+ "switchover": True,
+ },
+ },
+ "chassis_id": "test2",
+ "contact": "t1",
+ "location": "test1",
+ "targets": [
+ {"name": "test", "host": "1.1.1.2"},
+ {"name": "test2", "vrf": "vrf2"},
+ ],
+ "context": ["c1"],
+ "logging_threshold_oid_processing": 1,
+ "logging_threshold_pdu_processing": 1,
+ "mib_bulkstat_max_procmem_size": 101,
+ "mib_object_lists": ["test1"],
+ "mib_schema": [
+ {"name": "mib1", "object_list": "test1", "poll_interval": 1},
+ ],
+ "mib_bulkstat_transfer_ids": [
+ {
+ "name": "test2",
+ "retry": 1,
+ "buffer_size": 1024,
+ "enable": True,
+ "format_schemaASCI": True,
+ "retain": 1,
+ "schema": "test2",
+ },
+ ],
+ "timeouts": {
+ "duplicate": 0,
+ "inQdrop": 0,
+ "subagent": 1,
+ "pdu_stats": 1,
+ "threshold": 0,
+ },
+ "packetsize": 490,
+ "correlator": {
+ "rules": [
+ {"rule_name": "rule1"},
+ {"rule_name": "rule1", "timeout": 5},
+ ],
+ "rule_sets": [{"name": "rule1"}],
+ "buffer_size": 1024,
+ },
+ "trap_source": "GigabitEthernet0/0/0/2",
+ "throttle_time": 60,
+ "community_maps": [
+ {
+ "name": "cm1",
+ "context": "c1",
+ "security_name": "s1",
+ "target_list": "t1",
+ },
+ ],
+ "inform": {"retries": 7},
+ "overload_control": {
+ "overload_drop_time": 4,
+ "overload_throttle_rate": 6,
+ },
+ "ifmib": {"internal_cache_max_duration": 4},
+ "mroutemib_send_all_vrf": True,
+ "notification_log_mib": {"size": 5, "GlobalSize": 5},
+ }
+ result = self.execute_module(changed=False)
+ self.assertEqual(gathered, result["gathered"])
+
+ def test_iosxr_snmp_server_parsed(self):
+ self.maxDiff = None
+ set_module_args(
+ dict(
+ running_config="snmp-server vrf test1\n host 1.1.1.1 traps test1\n host 1.1.1.2 traps test1\n "
+ "context test2\n!\nsnmp-server drop report acl IPv6 test\nsnmp-server drop unknown-user"
+ "\nsnmp-server host 1.1.1.1 traps test udp-port 1\nsnmp-server host 1.1.1.2 informs "
+ "version 2c test\nsnmp-server host 1.1.1.3 traps test\nsnmp-server user test1 test2 v1 "
+ "IPv4 test1 IPv6 test2 SDROwner\nsnmp-server "
+ "community test RO IPv4 test IPv6 test\nsnmp-"
+ "server community test1 RO\nsnmp-server group "
+ "test v1 notify test1\nsnmp-server group test1 "
+ "v1 read test1 write test2 context test3 IPv4 test"
+ " IPv6 test1\nsnmp-server group test2 v1 "
+ "notify test read test1\nsnmp-server group test4 "
+ "v1 notify t1 context test\nsnmp-server queue-length "
+ "1\nsnmp-server trap-timeout 1\nsnmp-server trap "
+ "throttle-time 10\nsnmp-server traps rf\nsnmp-server traps "
+ "bfd\nsnmp-server traps bgp cbgp2\nsnmp-server "
+ "traps bgp updown\nsnmp-server traps ntp\nsnmp-server "
+ "traps pim neighbor-change\nsnmp-server traps "
+ "pim invalid-message-received\nsnmp-server traps pim "
+ "rp-mapping-change\nsnmp-server traps pim interface-state-change"
+ "\nsnmp-server traps copy-complete\nsnmp-server "
+ "traps hsrp\nsnmp-server traps ipsla\nsnmp-server traps msdp "
+ "peer-state-change\nsnmp-server traps vrrp events\nsnmp-server "
+ "traps flash removal\nsnmp-server traps flash insertion\nsnmp-server "
+ "traps ipsec tunnel stop\nsnmp-server traps ipsec tunnel start\nsnmp-server "
+ "traps power\nsnmp-server traps config\nsnmp-server traps entity\nsnmp-server "
+ "traps isakmp tunnel stop\nsnmp-server traps isakmp tunnel start\nsnmp-server "
+ "traps isis database-overload manual-address-drops corrupted-lsp-detected "
+ "attempt-to-exceed-max-sequence id-len-mismatch max-area-addresses-mismatch"
+ " own-lsp-purge sequence-number-skip authentication-type-failure "
+ "authentication-failure version-skew area-mismatch rejected-adjacency "
+ "lsp-too-large-to-propagate orig-lsp-buff-size-mismatch protocols-supported-mismatch"
+ " adjacency-change lsp-error-detected\nsnmp-server traps sensor\nsnmp-server"
+ " traps selective-vrf-download role-change\nsnmp-server traps syslog"
+ "\nsnmp-server traps system\nsnmp-server traps ospf lsa lsa-maxage"
+ "\nsnmp-server traps ospf lsa lsa-originate\nsnmp-server traps ospf"
+ " errors bad-packet\nsnmp-server traps ospf errors authentication-failure"
+ "\nsnmp-server traps ospf errors config-error\nsnmp-server traps ospf"
+ " errors virt-bad-packet\nsnmp-server traps ospf errors "
+ "virt-authentication-failure\nsnmp-server traps ospf errors"
+ " virt-config-error\nsnmp-server traps ospf retransmit"
+ " packets\nsnmp-server traps ospf retransmit virt-packets"
+ "\nsnmp-server traps ospf state-change if-state-change"
+ "\nsnmp-server traps ospf state-change neighbor-state-change"
+ "\nsnmp-server traps ospf state-change virtif-state-change\n"
+ "snmp-server traps ospf state-change virtneighbor-state-change"
+ "\nsnmp-server traps rsvp all\nsnmp-server traps rsvp new-flow\n"
+ "snmp-server traps rsvp lost-flow\nsnmp-server traps l2tun sessions\n"
+ "snmp-server traps l2tun tunnel-up\nsnmp-server traps l2tun tunnel-down"
+ "\nsnmp-server traps l2tun pseudowire status\nsnmp-server traps vpls all\n"
+ "snmp-server traps vpls status\nsnmp-server traps vpls full-clear\nsnmp-server "
+ "traps vpls full-raise\nsnmp-server traps snmp linkup\nsnmp-server traps snmp "
+ "linkdown\nsnmp-server traps snmp coldstart\nsnmp-server traps snmp warmstart"
+ "\nsnmp-server traps snmp authentication\nsnmp-server traps bulkstat transfer"
+ "\nsnmp-server traps bulkstat collection\nsnmp-server traps diameter peerup\
+ nsnmp-server traps diameter peerdown\nsnmp-server traps diameter protocolerror"
+ "\nsnmp-server traps diameter permanentfail\nsnmp-server traps diameter transientfail"
+ "\nsnmp-server traps l2vpn all\nsnmp-server traps l2vpn cisco\nsnmp-server traps "
+ "l2vpn vc-up\nsnmp-server traps l2vpn vc-down\nsnmp-server traps bridgemib\nsnmp-"
+ "server traps ospfv3 errors bad-packet\nsnmp-server traps ospfv3 errors config-error"
+ "\nsnmp-server traps ospfv3 errors virt-bad-packet\nsnmp-server traps ospfv3 errors "
+ "virt-config-error\nsnmp-server traps ospfv3 state-change if-state-change\nsnmp-"
+ "server traps ospfv3 state-change neighbor-state-change\nsnmp-server traps ospfv3 "
+ "state-change nssa-state-change\nsnmp-server traps ospfv3 state-change "
+ "virtif-state-change\nsnmp-server traps ospfv3 state-change "
+ "virtneighbor-state-change\nsnmp-server traps ospfv3 state-change "
+ "restart-status-change\nsnmp-server traps ospfv3 state-change "
+ "restart-helper-status-change\nsnmp-server traps ospfv3 state-change "
+ "restart-virtual-helper-status-change\nsnmp-server traps fru-ctrl"
+ "\nsnmp-server traps subscriber session-agg node\nsnmp-server traps "
+ "subscriber session-agg access-interface\nsnmp-server traps addrpool "
+ "low\nsnmp-server traps addrpool high\nsnmp-server traps cisco-entity-ext"
+ "\nsnmp-server traps entity-state operstatus\nsnmp-server traps entity-state "
+ "switchover\nsnmp-server traps entity-redundancy all"
+ "\nsnmp-server traps entity-redundancy "
+ "status\nsnmp-server traps entity-redundancy switchover\nsnmp-server chassis-id test2"
+ "\nsnmp-server contact test\nsnmp-server location test\nsnmp-server target list test1 "
+ "vrf vrf1\nsnmp-server target list test1 host 1.1.1.1\nsnmp-server context test\n"
+ "snmp-server context test2\nsnmp-server logging threshold oid-processing 0\n"
+ "snmp-server logging threshold pdu-processing 0\nsnmp-server mib bulkstat max-"
+ "procmem-size 100\nsnmp-server mib bulkstat object-list test\n!\nsnmp-server mib "
+ "bulkstat transfer-id test1\n retry 1\n buffer-size 1024\n enable\n format schemaASCII\n"
+ " retain 1\n schema test\n!\nsnmp-server timeouts duplicate 0\nsnmp-server timeouts"
+ " inQdrop 0\nsnmp-server timeouts subagent 1\nsnmp-server timeouts pdu stats"
+ " 1\nsnmp-server timeouts threshold 0\nsnmp-server packetsize 485\nsnmp-server"
+ " correlator buffer-size 1024\nsnmp-server trap-source GigabitEthernet0/0/0/1"
+ "\nsnmp-server throttle-time 50\nsnmp-server community-map test context test "
+ "security-name test2\nsnmp-server community-map test1 context test security-name "
+ "test2\nsnmp-server inform pending 1\nsnmp-server inform retries 1\nsnmp-server "
+ "inform timeout 1\nsnmp-server oid-poll-stats\nsnmp-server overload-control 0 0"
+ "\nsnmp-server trap authentication vrf disable\nsnmp-server "
+ "interface GigabitEthernet0/0/0/0\n notification linkupdown disable\n "
+ "index persistence\n!\nsnmp-server ifmib ifalias long\nsnmp-server "
+ "ifindex persist\nsnmp-server ifmib internal cache max-duration "
+ "0\nsnmp-server ifmib ipsubscriber\nsnmp-server ifmib stats cache"
+ "\nsnmp-server trap link ietf\nsnmp-server location test\nsnmp-server"
+ " mroutemib send-all-vrf\nsnmp-server notification-log-mib size 1\nsnmp-server "
+ "notification-log-mib default\nsnmp-server notification-log-mib disable\nsnmp-server"
+ " notification-log-mib GlobalSize 1",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "vrfs": [
+ {
+ "vrf": "test1",
+ "context": ["test2"],
+ "hosts": [
+ {
+ "host": "1.1.1.1",
+ "traps": True,
+ "community": "test1",
+ },
+ {
+ "host": "1.1.1.2",
+ "traps": True,
+ "community": "test1",
+ },
+ ],
+ },
+ ],
+ "drop": {"report_IPv6": "test", "unknown_user": True},
+ "hosts": [
+ {
+ "host": "1.1.1.1",
+ "traps": True,
+ "community": "test",
+ "udp_port": 1,
+ },
+ {
+ "host": "1.1.1.2",
+ "informs": True,
+ "community": "test",
+ "version": "2c",
+ },
+ {"host": "1.1.1.3", "traps": True, "community": "test"},
+ ],
+ "users": [
+ {
+ "user": "test1",
+ "group": "test2",
+ "acl_v4": "test1",
+ "acl_v6": "test2",
+ "v4_acl": "SDROwner",
+ "version": "v1",
+ },
+ ],
+ "communities": [
+ {
+ "name": "test",
+ "ro": True,
+ "acl_v4": "test",
+ "acl_v6": "test",
+ },
+ {"name": "test1", "ro": True},
+ ],
+ "groups": [
+ {"group": "test", "notify": "test1", "version": "v1"},
+ {
+ "group": "test1",
+ "acl_v4": "test",
+ "acl_v6": "test1",
+ "context": "test3",
+ "read": "test1",
+ "write": "test2",
+ "version": "v1",
+ },
+ {
+ "group": "test2",
+ "notify": "test",
+ "read": "test1",
+ "version": "v1",
+ },
+ {
+ "group": "test4",
+ "context": "test",
+ "notify": "t1",
+ "version": "v1",
+ },
+ ],
+ "queue_length": 1,
+ "trap_timeout": 1,
+ "trap": {
+ "throttle_time": 10,
+ "authentication_vrf_disable": True,
+ "link_ietf": True,
+ },
+ "traps": {
+ "rf": True,
+ "bfd": True,
+ "bgp": {"cbgp2": True},
+ "pim": {
+ "neighbor_change": True,
+ "invalid_message_received": True,
+ "rp_mapping_change": True,
+ "interface_state_change": True,
+ },
+ "copy_complete": True,
+ "hsrp": True,
+ "ipsla": True,
+ "msdp_peer_state_change": True,
+ "vrrp_events": True,
+ "flash": {"removal": True, "insertion": True},
+ "ipsec": {"stop": True, "start": True},
+ "power": True,
+ "config": True,
+ "entity": True,
+ "isakmp": {"stop": True, "start": True},
+ "isis": {
+ "id_len_mismatch": True,
+ "database_overload": True,
+ "manual_address_drops": True,
+ "corrupted_lsp_detected": True,
+ "attempt_to_exceed_max_sequence": True,
+ "max_area_addresses_mismatch": True,
+ "own_lsp_purge": True,
+ "sequence_number_skip": True,
+ "authentication_type_failure": True,
+ "authentication_failure": True,
+ "version_skew": True,
+ "area_mismatch": True,
+ "rejected_adjacency": True,
+ "lsp_too_large_to_propagate": True,
+ "orig_lsp_buff_size_mismatch": True,
+ "protocols_supported_mismatch": True,
+ "adjacency_change": True,
+ "lsp_error_detected": True,
+ },
+ "sensor": True,
+ "selective_vrf_download_role_change": True,
+ "syslog": True,
+ "system": True,
+ "ospf": {
+ "lsa": {"lsa_maxage": True, "lsa_originate": True},
+ "errors": {
+ "bad_packet": True,
+ "authentication_failure": True,
+ "config_error": True,
+ "virt_bad_packet": True,
+ "virt_authentication_failure": True,
+ "virt_config_error": True,
+ },
+ "retransmit": {"packets": True, "virt_packets": True},
+ "state_change": {
+ "if_state_change": True,
+ "neighbor_state_change": True,
+ "virtif_state_change": True,
+ "virtneighbor_state_change": True,
+ },
+ },
+ "rsvp": {"all": True, "new_flow": True, "lost_flow": True},
+ "l2tun": {
+ "sessions": True,
+ "tunnel_up": True,
+ "tunnel_down": True,
+ },
+ "vpls": {
+ "all": True,
+ "status": True,
+ "full_clear": True,
+ "full_raise": True,
+ },
+ "snmp": {
+ "linkup": True,
+ "linkdown": True,
+ "coldstart": True,
+ "warmstart": True,
+ "authentication": True,
+ },
+ "bulkstat_transfer": True,
+ "bulkstat_collection": True,
+ "diameter": {
+ "protocolerror": True,
+ "permanentfail": True,
+ "transientfail": True,
+ },
+ "l2vpn": {
+ "all": True,
+ "cisco": True,
+ "vc_up": True,
+ "vc_down": True,
+ },
+ "bridgemib": True,
+ "ospfv3": {
+ "errors": {
+ "bad_packet": True,
+ "config_error": True,
+ "virt_bad_packet": True,
+ "virt_config_error": True,
+ },
+ "state_change": {
+ "if_state_change": True,
+ "neighbor_state_change": True,
+ "nssa_state_change": True,
+ "virtif_state_change": True,
+ "virtneighbor_state_change": True,
+ "restart_status_change": True,
+ "restart_helper_status_change": True,
+ "restart_virtual_helper_status_change": True,
+ },
+ },
+ "fru_ctrl": True,
+ "subscriber": {
+ "session_agg_node": True,
+ "session_agg_access_interface": True,
+ },
+ "addrpool": {"low": True, "high": True},
+ "cisco_entity_ext": True,
+ "entity_state": {"operstatus": True, "switchover": True},
+ "entity_redundancy": {
+ "all": True,
+ "status": True,
+ "switchover": True,
+ },
+ },
+ "chassis_id": "test2",
+ "contact": "test",
+ "location": "test",
+ "targets": [
+ {"name": "test1", "vrf": "vrf1"},
+ {"name": "test1", "host": "1.1.1.1"},
+ ],
+ "context": ["test", "test2"],
+ "logging_threshold_oid_processing": 0,
+ "logging_threshold_pdu_processing": 0,
+ "mib_bulkstat_max_procmem_size": 100,
+ "mib_object_lists": ["test"],
+ "mib_bulkstat_transfer_ids": [
+ {
+ "name": "test1",
+ "retry": 1,
+ "buffer_size": 1024,
+ "enable": True,
+ "format_schemaASCI": True,
+ "retain": 1,
+ "schema": "test",
+ },
+ ],
+ "timeouts": {
+ "duplicate": 0,
+ "inQdrop": 0,
+ "subagent": 1,
+ "pdu_stats": 1,
+ "threshold": 0,
+ },
+ "packetsize": 485,
+ "correlator": {"buffer_size": 1024},
+ "trap_source": "GigabitEthernet0/0/0/1",
+ "throttle_time": 50,
+ "community_maps": [
+ {"name": "test", "context": "test", "security_name": "test2"},
+ {"name": "test1", "context": "test", "security_name": "test2"},
+ ],
+ "inform": {"pending": 1, "retries": 1, "timeout": 1},
+ "oid_poll_stats": True,
+ "overload_control": {
+ "overload_drop_time": 0,
+ "overload_throttle_rate": 0,
+ },
+ "interfaces": [
+ {
+ "name": "GigabitEthernet0/0/0/0",
+ "notification_linkupdown_disable": True,
+ },
+ ],
+ "ifmib": {
+ "ifalias_long": True,
+ "internal_cache_max_duration": 0,
+ "ipsubscriber": True,
+ "stats": True,
+ },
+ "ifindex": True,
+ "mroutemib_send_all_vrf": True,
+ "notification_log_mib": {
+ "size": 1,
+ "default": True,
+ "disable": True,
+ "GlobalSize": 1,
+ },
+ }
+ self.assertEqual(parsed_list, result["parsed"])
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_static_routes.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_static_routes.py
new file mode 100644
index 00000000..ba91d7f3
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_static_routes.py
@@ -0,0 +1,380 @@
+#
+# (c) 2019, Ansible by Red Hat, inc
+# 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
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_static_routes
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrStaticRoutesModule(TestIosxrModule):
+ module = iosxr_static_routes
+
+ def setUp(self):
+ super(TestIosxrStaticRoutesModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.static_routes.static_routes.Static_routesFacts.get_device_data",
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestIosxrStaticRoutesModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def load_fixtures(self, commands=None):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("iosxr_static_routes_config.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_iosxr_static_routes_merged(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ vrf="dev_site",
+ address_families=[
+ dict(
+ afi="ipv6",
+ safi="unicast",
+ routes=[
+ dict(
+ dest="1200:10::/64",
+ next_hops=[
+ dict(
+ interface="GigabitEthernet0/0/0/1",
+ admin_distance=55,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ commands = [
+ "router static",
+ "vrf dev_site",
+ "address-family ipv6 unicast",
+ "1200:10::/64 GigabitEthernet0/0/0/1 55",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_static_routes_merged_idempotent(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ vrf="DEV_SITE",
+ address_families=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ routes=[
+ dict(
+ dest="192.0.2.48/28",
+ next_hops=[
+ dict(
+ interface="192.0.2.12",
+ description="DEV",
+ dest_vrf="test_1",
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="merged",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_static_routes_default(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ address_families=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ routes=[
+ dict(
+ dest="192.168.1.0/24",
+ next_hops=[
+ dict(
+ interface="GigabitEthernet0/0/0/2",
+ track="ip_sla_2",
+ vrflabel=1200,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ )
+ commands = [
+ "router static",
+ "address-family ipv4 unicast",
+ "192.168.1.0/24 GigabitEthernet0/0/0/2 track ip_sla_2 vrflabel 1200",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_static_routes_default_idempotent(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ address_families=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ routes=[
+ dict(
+ dest="192.0.2.32/28",
+ next_hops=[
+ dict(
+ forward_router_address="192.0.2.11",
+ admin_distance=100,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_static_routes_replaced(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ address_families=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ routes=[
+ dict(
+ dest="192.0.2.16/28",
+ next_hops=[
+ dict(
+ forward_router_address="192.0.2.11",
+ admin_distance=100,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="replaced",
+ ),
+ )
+ commands = [
+ "router static",
+ "address-family ipv4 unicast",
+ "no 192.0.2.16/28 192.0.2.10 FastEthernet0/0/0/1",
+ "no 192.0.2.16/28 FastEthernet0/0/0/5",
+ "192.0.2.16/28 192.0.2.11 100",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_static_routes_replaced_idempotent(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ address_families=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ routes=[
+ dict(
+ dest="192.0.2.16/28",
+ next_hops=[
+ dict(
+ interface="FastEthernet0/0/0/5",
+ track="ip_sla_1",
+ ),
+ dict(
+ interface="FastEthernet0/0/0/1",
+ forward_router_address="192.0.2.10",
+ tag=10,
+ description="LAB",
+ metric=120,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="replaced",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_iosxr_static_routes_overridden(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ vrf="DEV_SITE_NEW",
+ address_families=[
+ dict(
+ afi="ipv4",
+ safi="unicast",
+ routes=[
+ dict(
+ dest="192.0.4.16/28",
+ next_hops=[
+ dict(
+ interface="FastEthernet0/0/0/5",
+ track="ip_sla_1",
+ ),
+ dict(
+ interface="FastEthernet0/0/0/1",
+ forward_router_address="192.0.2.10",
+ tag=10,
+ description="LAB",
+ metric=120,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ state="overridden",
+ ),
+ )
+ commands = [
+ "router static",
+ "no address-family ipv4 unicast",
+ "no address-family ipv6 unicast",
+ "no vrf DEV_SITE",
+ "vrf DEV_SITE_NEW",
+ "address-family ipv4 unicast",
+ "192.0.4.16/28 192.0.2.10 FastEthernet0/0/0/1 description LAB metric 120 tag 10",
+ "192.0.4.16/28 FastEthernet0/0/0/5 track ip_sla_1",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_static_routes_deleted_afi(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(address_families=[dict(afi="ipv4", safi="unicast")]),
+ ],
+ state="deleted",
+ ),
+ )
+
+ commands = ["router static", "no address-family ipv4 unicast"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_static_routes_deleted_vrf(self):
+ set_module_args(dict(config=[dict(vrf="DEV_SITE")], state="deleted"))
+
+ commands = ["router static", "no vrf DEV_SITE"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_static_routes_deleted_all(self):
+ set_module_args(dict(state="deleted"))
+
+ commands = ["no router static"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_static_routes_parsed(self):
+ set_module_args(
+ dict(
+ running_config="router static\n address-family ipv4 unicast\n 0.0.0.0/0 172.31.32.1\n "
+ "10.0.0.0/8 Null0 200\n 11.0.0.0/8 Loopback888\n 203.0.113.0/24 TenGigE0/0/0/0\n !\n!",
+ state="parsed",
+ ),
+ )
+ result = self.execute_module(changed=False)
+ parsed_list = [
+ {
+ "address_families": [
+ {
+ "afi": "ipv4",
+ "routes": [
+ {
+ "dest": "0.0.0.0/0",
+ "next_hops": [
+ {"forward_router_address": "172.31.32.1"},
+ ],
+ },
+ {
+ "dest": "10.0.0.0/8",
+ "next_hops": [
+ {
+ "admin_distance": 200,
+ "interface": "Null0",
+ },
+ ],
+ },
+ {
+ "dest": "11.0.0.0/8",
+ "next_hops": [{"interface": "Loopback888"}],
+ },
+ {
+ "dest": "203.0.113.0/24",
+ "next_hops": [{"interface": "TenGigE0/0/0/0"}],
+ },
+ ],
+ "safi": "unicast",
+ },
+ ],
+ },
+ ]
+ self.assertEqual(parsed_list, result["parsed"])
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_system.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_system.py
new file mode 100644
index 00000000..4e09671e
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_system.py
@@ -0,0 +1,123 @@
+# (c) 2016 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_system
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrSystemModule(TestIosxrModule):
+
+ module = iosxr_system
+
+ def setUp(self):
+ super(TestIosxrSystemModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_system.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_system.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_is_cliconf = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_system.is_cliconf",
+ )
+ self.is_cliconf = self.mock_is_cliconf.start()
+
+ def tearDown(self):
+ super(TestIosxrSystemModule, self).tearDown()
+
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+
+ def load_fixtures(self, commands=None):
+ self.get_config.return_value = load_fixture("iosxr_system_config.cfg")
+ self.load_config.return_value = dict(diff=None, session="session")
+ self.is_cliconf.return_value = True
+
+ def test_iosxr_system_hostname_changed(self):
+ set_module_args(dict(hostname="foo"))
+ commands = ["hostname foo", "no domain lookup disable"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_system_domain_name(self):
+ set_module_args(dict(domain_name="test.com"))
+ commands = ["domain name test.com", "no domain lookup disable"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_system_domain_search(self):
+ set_module_args(dict(domain_search=["ansible.com", "redhat.com"]))
+ commands = [
+ "domain list ansible.com",
+ "no domain list cisco.com",
+ "no domain lookup disable",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_system_lookup_source(self):
+ set_module_args(dict(lookup_source="Ethernet1"))
+ commands = [
+ "domain lookup source-interface Ethernet1",
+ "no domain lookup disable",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_system_lookup_enabled(self):
+ set_module_args(dict(lookup_enabled=True))
+ commands = ["no domain lookup disable"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_system_name_servers(self):
+ name_servers = ["8.8.8.8", "8.8.4.4", "1.1.1.1"]
+ set_module_args(dict(name_servers=name_servers))
+ self.execute_module(changed=True)
+
+ def test_iosxr_system_state_absent(self):
+ set_module_args(dict(state="absent"))
+ commands = [
+ "no hostname",
+ "no domain name",
+ "no domain lookup disable",
+ "no domain lookup source-interface MgmtEth0/0/CPU0/0",
+ "no domain list redhat.com",
+ "no domain list cisco.com",
+ "no domain name-server 8.8.8.8",
+ "no domain name-server 8.8.4.4",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_iosxr_system_no_change(self):
+ set_module_args(
+ dict(
+ hostname="iosxr01",
+ domain_name="eng.ansible.com",
+ lookup_enabled=False,
+ ),
+ )
+ self.execute_module()
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_user.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_user.py
new file mode 100644
index 00000000..3bb6f504
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_user.py
@@ -0,0 +1,131 @@
+# (c) 2016 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from ansible_collections.cisco.iosxr.plugins.modules import iosxr_user
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+from ansible_collections.cisco.iosxr.tests.unit.modules.utils import set_module_args
+
+from .iosxr_module import TestIosxrModule, load_fixture
+
+
+class TestIosxrUserModule(TestIosxrModule):
+
+ module = iosxr_user
+
+ def setUp(self):
+ super(TestIosxrUserModule, self).setUp()
+
+ self.mock_get_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_user.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_user.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_is_cliconf = patch(
+ "ansible_collections.cisco.iosxr.plugins.modules.iosxr_user.is_cliconf",
+ )
+ self.is_cliconf = self.mock_is_cliconf.start()
+
+ def tearDown(self):
+ super(TestIosxrUserModule, self).tearDown()
+
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_is_cliconf.stop()
+
+ def load_fixtures(self, commands=None, transport="cli"):
+ self.get_config.return_value = load_fixture("iosxr_user_config.cfg")
+ self.load_config.return_value = dict(diff=None, session="session")
+ self.is_cliconf.return_value = True
+
+ def test_iosxr_user_delete(self):
+ set_module_args(dict(name="ansible", state="absent"))
+ result = self.execute_module(changed=True)
+ self.assertEqual(result["commands"], ["no username ansible"])
+
+ def test_iosxr_user_password(self):
+ set_module_args(dict(name="ansible", configured_password="test"))
+ result = self.execute_module(changed=True)
+ self.assertEqual(result["commands"], ["username ansible secret test"])
+
+ def test_iosxr_user_purge(self):
+ set_module_args(dict(purge=True))
+ result = self.execute_module(changed=True)
+ self.assertEqual(result["commands"], ["no username ansible"])
+
+ def test_iosxr_user_group(self):
+ set_module_args(dict(name="ansible", group="sysadmin"))
+ result = self.execute_module(changed=True)
+ self.assertEqual(
+ result["commands"],
+ ["username ansible group sysadmin"],
+ )
+
+ def test_iosxr_user_update_password_changed(self):
+ set_module_args(
+ dict(
+ name="test",
+ configured_password="test",
+ update_password="on_create",
+ ),
+ )
+ result = self.execute_module(changed=True)
+ self.assertEqual(
+ result["commands"],
+ ["username test", "username test secret test"],
+ )
+
+ def test_iosxr_user_update_password_on_create_ok(self):
+ set_module_args(
+ dict(
+ name="ansible",
+ configured_password="test",
+ update_password="on_create",
+ ),
+ )
+ self.execute_module()
+
+ def test_iosxr_user_update_password_always(self):
+ set_module_args(
+ dict(
+ name="ansible",
+ configured_password="test",
+ update_password="always",
+ ),
+ )
+ result = self.execute_module(changed=True)
+ self.assertEqual(result["commands"], ["username ansible secret test"])
+
+ def test_iosxr_user_admin_mode(self):
+ set_module_args(
+ dict(name="ansible-2", configured_password="test-2", admin=True),
+ )
+ result = self.execute_module(changed=True)
+ self.assertEqual(
+ result["commands"],
+ ["username ansible-2", "username ansible-2 secret test-2"],
+ )
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_utils.py b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_utils.py
new file mode 100644
index 00000000..7707adf4
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/network/iosxr/test_iosxr_utils.py
@@ -0,0 +1,28 @@
+#
+# (c) 2022, Ansible by Red Hat, inc
+# 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
+from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.utils.utils import Version
+from ansible_collections.cisco.iosxr.tests.unit.compat import unittest
+
+
+class TestIosxrUtils(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_VersionOperation(self):
+ self.assertEqual(Version("3.0.1") < Version("3.1.0"), True)
+ self.assertEqual(Version("0.0.1") < Version("3.1.0"), True)
+ self.assertEqual(Version("3.0.1") < Version("3.0.1"), False)
+ self.assertEqual(Version("3.0.1") <= Version("3.0.1"), True)
+ self.assertEqual(Version("4.0.1") > Version("3.0.1"), True)
+ self.assertEqual(Version("4.1.1") > Version("4.1.0"), True)
+ self.assertEqual(Version("4.1.1") == Version("4.1.1"), True)
diff --git a/ansible_collections/cisco/iosxr/tests/unit/modules/utils.py b/ansible_collections/cisco/iosxr/tests/unit/modules/utils.py
new file mode 100644
index 00000000..d63a8692
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/modules/utils.py
@@ -0,0 +1,55 @@
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+import json
+
+from ansible.module_utils import basic
+from ansible.module_utils._text import to_bytes
+
+from ansible_collections.cisco.iosxr.tests.unit.compat import unittest
+from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch
+
+
+def set_module_args(args):
+ if "_ansible_remote_tmp" not in args:
+ args["_ansible_remote_tmp"] = "/tmp"
+ if "_ansible_keep_remote_files" not in args:
+ args["_ansible_keep_remote_files"] = False
+
+ args = json.dumps({"ANSIBLE_MODULE_ARGS": args})
+ basic._ANSIBLE_ARGS = to_bytes(args)
+
+
+class AnsibleExitJson(Exception):
+ pass
+
+
+class AnsibleFailJson(Exception):
+ pass
+
+
+def exit_json(*args, **kwargs):
+ if "changed" not in kwargs:
+ kwargs["changed"] = False
+ raise AnsibleExitJson(kwargs)
+
+
+def fail_json(*args, **kwargs):
+ kwargs["failed"] = True
+ raise AnsibleFailJson(kwargs)
+
+
+class ModuleTestCase(unittest.TestCase):
+ def setUp(self):
+ self.mock_module = patch.multiple(
+ basic.AnsibleModule,
+ exit_json=exit_json,
+ fail_json=fail_json,
+ )
+ self.mock_module.start()
+ self.mock_sleep = patch("time.sleep")
+ self.mock_sleep.start()
+ set_module_args({})
+ self.addCleanup(self.mock_module.stop)
+ self.addCleanup(self.mock_sleep.stop)
diff --git a/ansible_collections/cisco/iosxr/tests/unit/requirements.txt b/ansible_collections/cisco/iosxr/tests/unit/requirements.txt
new file mode 100644
index 00000000..a9772bea
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/tests/unit/requirements.txt
@@ -0,0 +1,42 @@
+boto3
+placebo
+pycrypto
+passlib
+pypsrp
+python-memcached
+pytz
+pyvmomi
+redis
+requests
+setuptools > 0.6 # pytest-xdist installed via requirements does not work with very old setuptools (sanity_ok)
+unittest2 ; python_version < '2.7'
+importlib ; python_version < '2.7'
+netaddr
+ipaddress
+netapp-lib
+solidfire-sdk-python
+
+# requirements for F5 specific modules
+f5-sdk ; python_version >= '2.7'
+f5-icontrol-rest ; python_version >= '2.7'
+deepdiff
+
+# requirement for Fortinet specific modules
+pyFMG
+
+# requirement for aci_rest module
+xmljson
+
+# requirement for winrm connection plugin tests
+pexpect
+
+# requirement for the linode module
+linode-python # APIv3
+linode_api4 ; python_version > '2.6' # APIv4
+
+# requirement for the gitlab module
+python-gitlab
+httmock
+
+# requirment for kubevirt modules
+openshift ; python_version >= '2.7'