From 7e04b5ba8ba32ec6992362788626ea10fc69b375 Mon Sep 17 00:00:00 2001 From: Ansible Core Team Date: Mon, 9 Mar 2020 09:40:34 +0000 Subject: [PATCH] Migrated to cisco.ios --- .../argspec/acl_interfaces/acl_interfaces.py | 66 - .../network/ios/argspec/acls/acls.py | 593 ------- .../network/ios/argspec/facts/facts.py | 24 - .../ios/argspec/interfaces/interfaces.py | 47 - .../argspec/l2_interfaces/l2_interfaces.py | 57 - .../argspec/l3_interfaces/l3_interfaces.py | 53 - .../network/ios/argspec/lacp/lacp.py | 47 - .../lacp_interfaces/lacp_interfaces.py | 48 - .../argspec/lag_interfaces/lag_interfaces.py | 52 - .../ios/argspec/lldp_global/lldp_global.py | 58 - .../lldp_interfaces/lldp_interfaces.py | 52 - .../argspec/static_routes/static_routes.py | 85 - .../network/ios/argspec/vlans/vlans.py | 50 - .../config/acl_interfaces/acl_interfaces.py | 405 ----- .../network/ios/config/acls/acls.py | 717 --------- .../ios/config/interfaces/interfaces.py | 295 ---- .../ios/config/l2_interfaces/l2_interfaces.py | 336 ---- .../ios/config/l3_interfaces/l3_interfaces.py | 328 ---- .../network/ios/config/lacp/lacp.py | 189 --- .../config/lacp_interfaces/lacp_interfaces.py | 260 --- .../config/lag_interfaces/lag_interfaces.py | 296 ---- .../ios/config/lldp_global/lldp_global.py | 238 --- .../config/lldp_interfaces/lldp_interfaces.py | 270 ---- .../ios/config/static_routes/static_routes.py | 532 ------- .../network/ios/config/vlans/vlans.py | 292 ---- .../facts/acl_interfaces/acl_interfaces.py | 122 -- .../network/ios/facts/acls/acls.py | 498 ------ .../module_utils/network/ios/facts/facts.py | 79 - .../ios/facts/interfaces/interfaces.py | 97 -- .../ios/facts/l2_interfaces/l2_interfaces.py | 114 -- .../ios/facts/l3_interfaces/l3_interfaces.py | 124 -- .../network/ios/facts/lacp/lacp.py | 83 - .../facts/lacp_interfaces/lacp_interfaces.py | 102 -- .../facts/lag_interfaces/lag_interfaces.py | 118 -- .../network/ios/facts/legacy/base.py | 380 ----- .../ios/facts/lldp_global/lldp_global.py | 90 -- .../facts/lldp_interfaces/lldp_interfaces.py | 108 -- .../ios/facts/static_routes/static_routes.py | 225 --- .../network/ios/facts/vlans/vlans.py | 144 -- lib/ansible/module_utils/network/ios/ios.py | 183 --- .../network/ios/providers/cli/config/base.py | 77 - .../cli/config/bgp/address_family.py | 140 -- .../ios/providers/cli/config/bgp/neighbors.py | 196 --- .../ios/providers/cli/config/bgp/process.py | 140 -- .../network/ios/providers/module.py | 62 - .../network/ios/providers/providers.py | 120 -- .../module_utils/network/ios/utils/utils.py | 328 ---- .../modules/network/ios/_ios_interface.py | 495 ------ .../modules/network/ios/_ios_l2_interface.py | 499 ------ .../modules/network/ios/_ios_l3_interface.py | 327 ---- lib/ansible/modules/network/ios/_ios_vlan.py | 350 ---- .../modules/network/ios/ios_acl_interfaces.py | 633 -------- lib/ansible/modules/network/ios/ios_acls.py | 1417 ----------------- lib/ansible/modules/network/ios/ios_banner.py | 186 --- lib/ansible/modules/network/ios/ios_bgp.py | 438 ----- .../modules/network/ios/ios_command.py | 230 --- lib/ansible/modules/network/ios/ios_config.py | 567 ------- lib/ansible/modules/network/ios/ios_facts.py | 239 --- .../modules/network/ios/ios_interfaces.py | 405 ----- .../modules/network/ios/ios_l2_interfaces.py | 390 ----- .../modules/network/ios/ios_l3_interfaces.py | 442 ----- lib/ansible/modules/network/ios/ios_lacp.py | 185 --- .../network/ios/ios_lacp_interfaces.py | 363 ----- .../modules/network/ios/ios_lag_interfaces.py | 390 ----- .../modules/network/ios/ios_linkagg.py | 318 ---- lib/ansible/modules/network/ios/ios_lldp.py | 112 -- .../modules/network/ios/ios_lldp_global.py | 256 --- .../network/ios/ios_lldp_interfaces.py | 501 ------ .../modules/network/ios/ios_logging.py | 429 ----- lib/ansible/modules/network/ios/ios_ntp.py | 308 ---- lib/ansible/modules/network/ios/ios_ping.py | 210 --- .../modules/network/ios/ios_static_route.py | 313 ---- .../modules/network/ios/ios_static_routes.py | 710 --------- lib/ansible/modules/network/ios/ios_system.py | 380 ----- lib/ansible/modules/network/ios/ios_user.py | 533 ------- lib/ansible/modules/network/ios/ios_vlans.py | 464 ------ lib/ansible/modules/network/ios/ios_vrf.py | 719 --------- lib/ansible/plugins/action/ios.py | 95 -- lib/ansible/plugins/cliconf/ios.py | 387 ----- lib/ansible/plugins/doc_fragments/ios.py | 81 - lib/ansible/plugins/terminal/ios.py | 102 -- .../ios_acl_interfaces/defaults/main.yaml | 3 - .../targets/ios_acl_interfaces/tasks/cli.yaml | 21 - .../ios_acl_interfaces/tasks/main.yaml | 2 - .../ios_acl_interfaces/tests/cli/_parsed.cfg | 8 - .../tests/cli/_populate_config.yaml | 14 - .../tests/cli/_remove_config.yaml | 15 - .../ios_acl_interfaces/tests/cli/deleted.yaml | 65 - .../tests/cli/empty_config.yaml | 58 - .../tests/cli/gathered.yaml | 21 - .../ios_acl_interfaces/tests/cli/merged.yaml | 53 - .../tests/cli/overridden.yaml | 41 - .../ios_acl_interfaces/tests/cli/parsed.yaml | 16 - .../tests/cli/rendered.yaml | 39 - .../tests/cli/replaced.yaml | 41 - .../ios_acl_interfaces/tests/cli/rtt.yaml | 78 - .../targets/ios_acl_interfaces/vars/main.yaml | 99 -- .../targets/ios_acls/defaults/main.yaml | 3 - .../targets/ios_acls/meta/main.yaml | 1 - .../targets/ios_acls/tasks/cli.yaml | 21 - .../targets/ios_acls/tasks/main.yaml | 2 - .../targets/ios_acls/tests/cli/_parsed.cfg | 7 - .../ios_acls/tests/cli/_populate_config.yaml | 15 - .../ios_acls/tests/cli/_remove_config.yaml | 12 - .../targets/ios_acls/tests/cli/deleted.yaml | 70 - .../ios_acls/tests/cli/empty_config.yaml | 58 - .../targets/ios_acls/tests/cli/gathered.yaml | 21 - .../targets/ios_acls/tests/cli/merged.yaml | 123 -- .../ios_acls/tests/cli/overridden.yaml | 73 - .../targets/ios_acls/tests/cli/parsed.yaml | 16 - .../targets/ios_acls/tests/cli/rendered.yaml | 54 - .../targets/ios_acls/tests/cli/replaced.yaml | 72 - .../targets/ios_acls/tests/cli/rtt.yaml | 173 -- .../targets/ios_acls/vars/main.yaml | 242 --- .../targets/ios_banner/defaults/main.yaml | 2 - .../targets/ios_banner/meta/main.yml | 2 - .../targets/ios_banner/tasks/cli.yaml | 24 - .../targets/ios_banner/tasks/main.yaml | 2 - .../ios_banner/tests/cli/basic-login.yaml | 50 - .../ios_banner/tests/cli/basic-motd.yaml | 50 - .../ios_banner/tests/cli/basic-no-login.yaml | 41 - .../tests/cli/multiple-login-exec.yaml | 55 - .../ios_banner/tests/cli/net_banner.yml | 32 - .../targets/ios_bgp/defaults/main.yaml | 2 - .../targets/ios_bgp/meta/main.yaml | 2 - .../targets/ios_bgp/tasks/cli.yaml | 17 - .../targets/ios_bgp/tasks/main.yaml | 2 - .../targets/ios_bgp/tests/cli/basic.yaml | 504 ------ .../targets/ios_command/defaults/main.yaml | 3 - .../targets/ios_command/meta/main.yml | 2 - .../targets/ios_command/tasks/cli.yaml | 24 - .../targets/ios_command/tasks/main.yaml | 2 - .../ios_command/tests/cli/bad_operator.yaml | 20 - .../ios_command/tests/cli/cli_command.yaml | 28 - .../ios_command/tests/cli/contains.yaml | 20 - .../ios_command/tests/cli/error_regex.yaml | 59 - .../ios_command/tests/cli/invalid.yaml | 28 - .../targets/ios_command/tests/cli/output.yaml | 30 - .../ios_command/tests/cli/timeout.yaml | 19 - .../targets/ios_config/defaults/main.yaml | 3 - .../targets/ios_config/meta/main.yml | 2 - .../targets/ios_config/tasks/cli.yaml | 17 - .../targets/ios_config/tasks/cli_config.yaml | 17 - .../targets/ios_config/tasks/main.yaml | 3 - .../templates/basic/base_running_config | 9 - .../ios_config/templates/basic/config.j2 | 4 - .../ios_config/templates/basic/configblock.j2 | 5 - .../templates/basic/configexact1.j2 | 6 - .../templates/basic/configexact2.j2 | 5 - .../templates/basic/configstrict1.j2 | 5 - .../templates/basic/intended_running_config | 9 - .../ios_config/templates/basic/macro.j2 | 8 - .../ios_config/templates/basic/setupblock.j2 | 5 - .../ios_config/templates/basic/setupexact.j2 | 7 - .../ios_config/templates/basic/setupstrict.j2 | 7 - .../ios_config/templates/defaults/config.j2 | 4 - .../targets/ios_config/tests/cli/backup.yaml | 125 -- .../ios_config/tests/cli/defaults.yaml | 57 - .../targets/ios_config/tests/cli/diff.yaml | 33 - .../targets/ios_config/tests/cli/macro.yaml | 66 - .../targets/ios_config/tests/cli/save.yaml | 49 - .../ios_config/tests/cli/src_basic.yaml | 70 - .../ios_config/tests/cli/src_invalid.yaml | 18 - .../ios_config/tests/cli/src_match_none.yaml | 38 - .../ios_config/tests/cli/sublevel.yaml | 39 - .../ios_config/tests/cli/sublevel_block.yaml | 58 - .../ios_config/tests/cli/sublevel_exact.yaml | 61 - .../ios_config/tests/cli/sublevel_strict.yaml | 57 - .../cli/sublevel_strict_mul_parents.yaml | 66 - .../ios_config/tests/cli/toplevel.yaml | 33 - .../ios_config/tests/cli/toplevel_after.yaml | 40 - .../ios_config/tests/cli/toplevel_before.yaml | 40 - .../tests/cli/toplevel_nonidempotent.yaml | 35 - .../tests/cli_config/cli_backup.yaml | 113 -- .../tests/cli_config/cli_basic.yaml | 45 - .../tests/cli_config/cli_block_replace.yaml | 32 - .../tests/cli_config/cli_exact_match.yaml | 33 - .../tests/cli_config/cli_strict_match.yaml | 24 - .../targets/ios_facts/defaults/main.yaml | 3 - .../targets/ios_facts/meta/main.yml | 2 - .../targets/ios_facts/tasks/cli.yaml | 24 - .../targets/ios_facts/tasks/main.yaml | 2 - .../ios_facts/tests/cli/all_facts.yaml | 35 - .../ios_facts/tests/cli/default_facts.yaml | 35 - .../ios_facts/tests/cli/invalid_subset.yaml | 48 - .../ios_facts/tests/cli/not_hardware.yaml | 31 - test/integration/targets/ios_file/aliases | 1 - .../targets/ios_file/defaults/main.yaml | 2 - test/integration/targets/ios_file/ios1.cfg | 3 - .../integration/targets/ios_file/nonascii.bin | Bin 32768 -> 0 bytes .../targets/ios_file/tasks/cli.yaml | 17 - .../targets/ios_file/tasks/main.yaml | 2 - .../targets/ios_file/tests/cli/net_get.yaml | 52 - .../targets/ios_file/tests/cli/net_put.yaml | 73 - .../targets/ios_interface/defaults/main.yaml | 2 - .../targets/ios_interface/meta/main.yaml | 2 - .../targets/ios_interface/tasks/cli.yaml | 24 - .../targets/ios_interface/tasks/main.yaml | 2 - .../ios_interface/tests/cli/basic.yaml | 228 --- .../ios_interface/tests/cli/intent.yaml | 140 -- .../tests/cli/net_interface.yaml | 47 - .../targets/ios_interfaces/defaults/main.yaml | 3 - .../targets/ios_interfaces/meta/main.yaml | 1 - .../targets/ios_interfaces/tasks/cli.yaml | 21 - .../targets/ios_interfaces/tasks/main.yaml | 2 - .../tests/cli/_populate_config.yaml | 17 - .../tests/cli/_remove_config.yaml | 24 - .../ios_interfaces/tests/cli/deleted.yaml | 47 - .../tests/cli/empty_config.yaml | 36 - .../ios_interfaces/tests/cli/merged.yaml | 50 - .../ios_interfaces/tests/cli/overridden.yaml | 46 - .../ios_interfaces/tests/cli/replaced.yaml | 47 - .../targets/ios_interfaces/vars/main.yaml | 214 --- .../ios_l2_interface/defaults/main.yaml | 2 - .../targets/ios_l2_interface/meta/main.yml | 2 - .../targets/ios_l2_interface/tasks/cli.yaml | 26 - .../targets/ios_l2_interface/tasks/main.yaml | 4 - .../ios_l2_interface/tests/cli/agg.yaml | 81 - .../ios_l2_interface/tests/cli/sanity.yaml | 168 -- .../ios_l2_interfaces/defaults/main.yaml | 3 - .../targets/ios_l2_interfaces/meta/main.yaml | 1 - .../targets/ios_l2_interfaces/tasks/cli.yaml | 25 - .../targets/ios_l2_interfaces/tasks/main.yaml | 2 - .../tests/cli/_populate_config.yaml | 15 - .../tests/cli/_remove_config.yaml | 21 - .../ios_l2_interfaces/tests/cli/deleted.yaml | 41 - .../tests/cli/empty_config.yaml | 36 - .../ios_l2_interfaces/tests/cli/merged.yaml | 50 - .../tests/cli/overridden.yaml | 47 - .../ios_l2_interfaces/tests/cli/replaced.yaml | 50 - .../targets/ios_l2_interfaces/vars/main.yaml | 159 -- .../ios_l3_interface/defaults/main.yaml | 2 - .../targets/ios_l3_interface/meta/main.yaml | 2 - .../targets/ios_l3_interface/tasks/cli.yaml | 24 - .../targets/ios_l3_interface/tasks/main.yaml | 2 - .../ios_l3_interface/tests/cli/basic.yaml | 257 --- .../ios_l3_interfaces/defaults/main.yaml | 3 - .../targets/ios_l3_interfaces/meta/main.yaml | 1 - .../targets/ios_l3_interfaces/tasks/cli.yaml | 21 - .../targets/ios_l3_interfaces/tasks/main.yaml | 2 - .../tests/cli/_populate_config.yaml | 12 - .../tests/cli/_remove_config.yaml | 12 - .../ios_l3_interfaces/tests/cli/deleted.yaml | 43 - .../tests/cli/empty_config.yaml | 36 - .../ios_l3_interfaces/tests/cli/merged.yaml | 51 - .../tests/cli/overridden.yaml | 49 - .../ios_l3_interfaces/tests/cli/replaced.yaml | 51 - .../targets/ios_l3_interfaces/vars/main.yaml | 157 -- test/integration/targets/ios_lacp/aliases | 1 - .../targets/ios_lacp/defaults/main.yaml | 3 - .../targets/ios_lacp/meta/main.yaml | 1 - .../targets/ios_lacp/tasks/cli.yaml | 25 - .../targets/ios_lacp/tasks/main.yaml | 2 - .../ios_lacp/tests/cli/_populate_config.yaml | 8 - .../ios_lacp/tests/cli/_remove_config.yaml | 8 - .../targets/ios_lacp/tests/cli/deleted.yaml | 41 - .../ios_lacp/tests/cli/empty_config.yaml | 27 - .../targets/ios_lacp/tests/cli/merged.yaml | 42 - .../targets/ios_lacp/tests/cli/replaced.yaml | 44 - .../targets/ios_lacp/vars/main.yaml | 36 - .../ios_lacp_interfaces/defaults/main.yaml | 3 - .../ios_lacp_interfaces/tasks/cli.yaml | 25 - .../ios_lacp_interfaces/tasks/main.yaml | 2 - .../tests/cli/_populate_config.yaml | 16 - .../tests/cli/_remove_config.yaml | 17 - .../tests/cli/deleted.yaml | 41 - .../tests/cli/empty_config.yaml | 38 - .../ios_lacp_interfaces/tests/cli/merged.yaml | 47 - .../tests/cli/overridden.yaml | 47 - .../tests/cli/replaced.yaml | 46 - .../ios_lacp_interfaces/vars/main.yaml | 126 -- .../ios_lag_interfaces/defaults/main.yaml | 3 - .../targets/ios_lag_interfaces/meta/main.yaml | 1 - .../targets/ios_lag_interfaces/tasks/cli.yaml | 25 - .../ios_lag_interfaces/tasks/main.yaml | 2 - .../tests/cli/_populate_config.yaml | 11 - .../tests/cli/_remove_config.yaml | 11 - .../ios_lag_interfaces/tests/cli/deleted.yaml | 41 - .../tests/cli/empty_config.yaml | 38 - .../ios_lag_interfaces/tests/cli/merged.yaml | 46 - .../tests/cli/overridden.yaml | 46 - .../tests/cli/replaced.yaml | 50 - .../targets/ios_lag_interfaces/vars/main.yaml | 93 -- .../targets/ios_linkagg/defaults/main.yaml | 3 - .../targets/ios_linkagg/meta/main.yaml | 2 - .../targets/ios_linkagg/tasks/cli.yaml | 24 - .../targets/ios_linkagg/tasks/main.yaml | 2 - .../targets/ios_linkagg/tests/cli/basic.yaml | 171 -- .../targets/ios_lldp/defaults/main.yaml | 2 - .../targets/ios_lldp/meta/main.yaml | 2 - .../targets/ios_lldp/tasks/cli.yaml | 24 - .../targets/ios_lldp/tasks/main.yaml | 2 - .../targets/ios_lldp/tests/cli/basic.yaml | 51 - .../targets/ios_lldp_global/aliases | 1 - .../ios_lldp_global/defaults/main.yaml | 3 - .../targets/ios_lldp_global/meta/main.yaml | 1 - .../targets/ios_lldp_global/tasks/cli.yaml | 21 - .../targets/ios_lldp_global/tasks/main.yaml | 2 - .../tests/cli/_populate_config.yaml | 10 - .../tests/cli/_remove_config.yaml | 10 - .../ios_lldp_global/tests/cli/deleted.yaml | 40 - .../tests/cli/empty_config.yaml | 25 - .../ios_lldp_global/tests/cli/merged.yaml | 43 - .../ios_lldp_global/tests/cli/replaced.yaml | 43 - .../targets/ios_lldp_global/vars/main.yaml | 47 - .../ios_lldp_interfaces/defaults/main.yaml | 3 - .../ios_lldp_interfaces/tasks/cli.yaml | 21 - .../ios_lldp_interfaces/tasks/main.yaml | 2 - .../tests/cli/_enable_lldp.yaml | 7 - .../tests/cli/_populate_config.yaml | 15 - .../tests/cli/_remove_config.yaml | 15 - .../tests/cli/deleted.yaml | 42 - .../tests/cli/empty_config.yaml | 36 - .../ios_lldp_interfaces/tests/cli/merged.yaml | 50 - .../tests/cli/overridden.yaml | 48 - .../tests/cli/replaced.yaml | 48 - .../ios_lldp_interfaces/vars/main.yaml | 126 -- .../targets/ios_logging/defaults/main.yaml | 2 - .../targets/ios_logging/meta/main.yaml | 2 - .../targets/ios_logging/tasks/cli.yaml | 24 - .../targets/ios_logging/tasks/main.yaml | 2 - .../targets/ios_logging/tests/cli/basic.yaml | 144 -- .../ios_logging/tests/cli/net_logging.yaml | 36 - .../targets/ios_ntp/defaults/main.yaml | 2 - .../integration/targets/ios_ntp/meta/main.yml | 2 - .../targets/ios_ntp/tasks/cli.yaml | 24 - .../targets/ios_ntp/tasks/main.yaml | 2 - .../ios_ntp/tests/cli/ntp_configuration.yaml | 106 -- .../targets/ios_ping/defaults/main.yaml | 3 - .../targets/ios_ping/meta/main.yaml | 2 - .../targets/ios_ping/tasks/cli.yaml | 24 - .../targets/ios_ping/tasks/main.yaml | 2 - .../targets/ios_ping/tests/cli/ping.yaml | 55 - .../targets/ios_smoke/defaults/main.yaml | 3 - .../targets/ios_smoke/meta/main.yaml | 2 - .../targets/ios_smoke/tasks/cli.yaml | 24 - .../targets/ios_smoke/tasks/main.yaml | 2 - .../ios_smoke/templates/defaults/config.j2 | 4 - .../ios_smoke/tests/cli/common_config.yaml | 212 --- .../ios_smoke/tests/cli/common_utils.yaml | 152 -- .../ios_smoke/tests/cli/misc_tests.yaml | 41 - .../targets/ios_smoke/tests/cli/reboot.yaml | 19 - .../ios_static_route/defaults/main.yaml | 2 - .../targets/ios_static_route/meta/main.yaml | 2 - .../targets/ios_static_route/tasks/cli.yaml | 24 - .../targets/ios_static_route/tasks/main.yaml | 2 - .../ios_static_route/tests/cli/basic.yaml | 144 -- .../tests/cli/net_static_route.yaml | 33 - .../ios_static_routes/defaults/main.yaml | 3 - .../targets/ios_static_routes/meta/main.yaml | 1 - .../targets/ios_static_routes/tasks/cli.yaml | 20 - .../targets/ios_static_routes/tasks/main.yaml | 2 - .../tests/cli/_intial_setup_config.yaml | 13 - .../tests/cli/_populate_config.yaml | 11 - .../tests/cli/_remove_config.yaml | 12 - .../ios_static_routes/tests/cli/deleted.yaml | 66 - .../tests/cli/empty_config.yaml | 58 - .../ios_static_routes/tests/cli/gathered.yaml | 22 - .../ios_static_routes/tests/cli/merged.yaml | 66 - .../tests/cli/overridden.yaml | 58 - .../ios_static_routes/tests/cli/rendered.yaml | 54 - .../ios_static_routes/tests/cli/replaced.yaml | 61 - .../ios_static_routes/tests/cli/rtt.yaml | 78 - .../targets/ios_static_routes/vars/main.yaml | 88 - .../targets/ios_system/defaults/main.yaml | 2 - .../targets/ios_system/meta/main.yml | 2 - .../targets/ios_system/tasks/cli.yaml | 24 - .../targets/ios_system/tasks/main.yaml | 2 - .../ios_system/tests/cli/net_system.yaml | 37 - .../ios_system/tests/cli/set_domain_list.yaml | 122 -- .../ios_system/tests/cli/set_domain_name.yaml | 36 - .../ios_system/tests/cli/set_hostname.yaml | 36 - .../tests/cli/set_lookup_source.yaml | 94 -- .../tests/cli/set_name_servers.yaml | 91 -- .../targets/ios_user/defaults/main.yaml | 2 - .../targets/ios_user/files/test_rsa | 27 - .../targets/ios_user/files/test_rsa.pub | 1 - .../targets/ios_user/meta/main.yaml | 2 - .../targets/ios_user/tasks/cli.yaml | 24 - .../targets/ios_user/tasks/main.yaml | 2 - .../targets/ios_user/tests/cli/auth.yaml | 83 - .../targets/ios_user/tests/cli/basic.yaml | 142 -- .../targets/ios_vlan/defaults/main.yaml | 3 - .../targets/ios_vlan/meta/main.yaml | 2 - .../targets/ios_vlan/tasks/cli.yaml | 24 - .../targets/ios_vlan/tasks/main.yaml | 2 - .../targets/ios_vlan/tests/cli/basic.yaml | 239 --- .../targets/ios_vlans/defaults/main.yaml | 3 - .../targets/ios_vlans/meta/main.yaml | 1 - .../targets/ios_vlans/tasks/cli.yaml | 25 - .../targets/ios_vlans/tasks/main.yaml | 2 - .../ios_vlans/tests/cli/_populate_config.yaml | 10 - .../ios_vlans/tests/cli/_remove_config.yaml | 11 - .../targets/ios_vlans/tests/cli/deleted.yaml | 42 - .../ios_vlans/tests/cli/empty_config.yaml | 38 - .../targets/ios_vlans/tests/cli/merged.yaml | 54 - .../ios_vlans/tests/cli/overridden.yaml | 48 - .../targets/ios_vlans/tests/cli/replaced.yaml | 49 - .../targets/ios_vlans/vars/main.yaml | 345 ---- test/sanity/ignore.txt | 153 -- .../network/ios/fixtures/configure_terminal | 2 - .../ios/fixtures/ios_acl_interfaces.cfg | 8 - .../network/ios/fixtures/ios_acls_config.cfg | 4 - .../ios/fixtures/ios_banner_show_banner.txt | 3 - .../ios_banner_show_running_config_ios12.txt | 15 - .../network/ios/fixtures/ios_bgp_config.cfg | 24 - .../ios/fixtures/ios_config_config.cfg | 12 - .../ios/fixtures/ios_config_defaults.cfg | 13 - .../network/ios/fixtures/ios_config_src.cfg | 11 - .../network/ios/fixtures/ios_facts_dir | 23 - .../network/ios/fixtures/ios_facts_show_cdp | 4 - .../ios_facts_show_cdp_neighbors_detail | 40 - .../ios/fixtures/ios_facts_show_interfaces | 61 - .../ios/fixtures/ios_facts_show_ip_interface | 0 .../fixtures/ios_facts_show_ipv6_interface | 0 .../network/ios/fixtures/ios_facts_show_lldp | 6 - .../ios_facts_show_lldp_neighbors_detail | 50 - .../fixtures/ios_facts_show_memory_statistics | 0 .../ios/fixtures/ios_facts_show_version | 68 - .../ios/fixtures/ios_logging_config.cfg | 11 - .../ios/fixtures/ios_logging_config_ios12.cfg | 6 - .../network/ios/fixtures/ios_ntp_config.cfg | 7 - .../ios_ping_ping_10.255.255.250_repeat_2 | 4 - .../fixtures/ios_ping_ping_8.8.8.8_repeat_2 | 4 - .../ios/fixtures/ios_static_routes_config.cfg | 2 - .../ios/fixtures/ios_system_config.cfg | 14 - .../network/ios/fixtures/ios_user_config.cfg | 2 - .../network/ios/fixtures/ios_vlan_config.cfg | 9 - .../network/ios/fixtures/ios_vrf_config.cfg | 81 - .../modules/network/ios/fixtures/show_version | 45 - test/units/modules/network/ios/ios_module.py | 87 - .../network/ios/test_ios_acl_interfaces.py | 335 ---- .../modules/network/ios/test_ios_acls.py | 451 ------ .../modules/network/ios/test_ios_banner.py | 76 - .../units/modules/network/ios/test_ios_bgp.py | 207 --- .../modules/network/ios/test_ios_command.py | 126 -- .../modules/network/ios/test_ios_config.py | 250 --- .../modules/network/ios/test_ios_facts.py | 123 -- .../modules/network/ios/test_ios_logging.py | 140 -- .../units/modules/network/ios/test_ios_ntp.py | 99 -- .../modules/network/ios/test_ios_ping.py | 72 - .../network/ios/test_ios_static_routes.py | 357 ----- .../modules/network/ios/test_ios_system.py | 123 -- .../modules/network/ios/test_ios_user.py | 141 -- .../modules/network/ios/test_ios_vlan.py | 149 -- .../units/modules/network/ios/test_ios_vrf.py | 210 --- .../plugins/cliconf/fixtures/ios/show_version | 54 - .../plugins/cliconf/fixtures/nos/show_chassis | 30 - .../cliconf/fixtures/nos/show_running-config | 549 ------- .../plugins/cliconf/fixtures/nos/show_version | 17 - .../cliconf/fixtures/slxos/show_chassis | 40 - .../fixtures/slxos/show_running-config | 624 -------- .../fixtures/slxos/show_startup-config | 624 -------- .../cliconf/fixtures/slxos/show_version | 18 - test/units/plugins/cliconf/test_ios.py | 133 -- 455 files changed, 39950 deletions(-) delete mode 100644 lib/ansible/module_utils/network/ios/argspec/acl_interfaces/acl_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/argspec/acls/acls.py delete mode 100644 lib/ansible/module_utils/network/ios/argspec/facts/facts.py delete mode 100644 lib/ansible/module_utils/network/ios/argspec/interfaces/interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/argspec/l2_interfaces/l2_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/argspec/l3_interfaces/l3_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/argspec/lacp/lacp.py delete mode 100644 lib/ansible/module_utils/network/ios/argspec/lacp_interfaces/lacp_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/argspec/lag_interfaces/lag_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/argspec/lldp_global/lldp_global.py delete mode 100644 lib/ansible/module_utils/network/ios/argspec/lldp_interfaces/lldp_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/argspec/static_routes/static_routes.py delete mode 100644 lib/ansible/module_utils/network/ios/argspec/vlans/vlans.py delete mode 100644 lib/ansible/module_utils/network/ios/config/acl_interfaces/acl_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/config/acls/acls.py delete mode 100644 lib/ansible/module_utils/network/ios/config/interfaces/interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/config/l2_interfaces/l2_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/config/l3_interfaces/l3_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/config/lacp/lacp.py delete mode 100644 lib/ansible/module_utils/network/ios/config/lacp_interfaces/lacp_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/config/lag_interfaces/lag_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/config/lldp_global/lldp_global.py delete mode 100644 lib/ansible/module_utils/network/ios/config/lldp_interfaces/lldp_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/config/static_routes/static_routes.py delete mode 100644 lib/ansible/module_utils/network/ios/config/vlans/vlans.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/acl_interfaces/acl_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/acls/acls.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/facts.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/interfaces/interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/l2_interfaces/l2_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/l3_interfaces/l3_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/lacp/lacp.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/lacp_interfaces/lacp_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/lag_interfaces/lag_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/legacy/base.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/lldp_global/lldp_global.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/lldp_interfaces/lldp_interfaces.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/static_routes/static_routes.py delete mode 100644 lib/ansible/module_utils/network/ios/facts/vlans/vlans.py delete mode 100644 lib/ansible/module_utils/network/ios/ios.py delete mode 100644 lib/ansible/module_utils/network/ios/providers/cli/config/base.py delete mode 100644 lib/ansible/module_utils/network/ios/providers/cli/config/bgp/address_family.py delete mode 100644 lib/ansible/module_utils/network/ios/providers/cli/config/bgp/neighbors.py delete mode 100644 lib/ansible/module_utils/network/ios/providers/cli/config/bgp/process.py delete mode 100644 lib/ansible/module_utils/network/ios/providers/module.py delete mode 100644 lib/ansible/module_utils/network/ios/providers/providers.py delete mode 100644 lib/ansible/module_utils/network/ios/utils/utils.py delete mode 100644 lib/ansible/modules/network/ios/_ios_interface.py delete mode 100644 lib/ansible/modules/network/ios/_ios_l2_interface.py delete mode 100644 lib/ansible/modules/network/ios/_ios_l3_interface.py delete mode 100644 lib/ansible/modules/network/ios/_ios_vlan.py delete mode 100644 lib/ansible/modules/network/ios/ios_acl_interfaces.py delete mode 100644 lib/ansible/modules/network/ios/ios_acls.py delete mode 100644 lib/ansible/modules/network/ios/ios_banner.py delete mode 100644 lib/ansible/modules/network/ios/ios_bgp.py delete mode 100644 lib/ansible/modules/network/ios/ios_command.py delete mode 100644 lib/ansible/modules/network/ios/ios_config.py delete mode 100644 lib/ansible/modules/network/ios/ios_facts.py delete mode 100644 lib/ansible/modules/network/ios/ios_interfaces.py delete mode 100644 lib/ansible/modules/network/ios/ios_l2_interfaces.py delete mode 100644 lib/ansible/modules/network/ios/ios_l3_interfaces.py delete mode 100644 lib/ansible/modules/network/ios/ios_lacp.py delete mode 100644 lib/ansible/modules/network/ios/ios_lacp_interfaces.py delete mode 100644 lib/ansible/modules/network/ios/ios_lag_interfaces.py delete mode 100644 lib/ansible/modules/network/ios/ios_linkagg.py delete mode 100644 lib/ansible/modules/network/ios/ios_lldp.py delete mode 100644 lib/ansible/modules/network/ios/ios_lldp_global.py delete mode 100644 lib/ansible/modules/network/ios/ios_lldp_interfaces.py delete mode 100644 lib/ansible/modules/network/ios/ios_logging.py delete mode 100644 lib/ansible/modules/network/ios/ios_ntp.py delete mode 100644 lib/ansible/modules/network/ios/ios_ping.py delete mode 100644 lib/ansible/modules/network/ios/ios_static_route.py delete mode 100644 lib/ansible/modules/network/ios/ios_static_routes.py delete mode 100644 lib/ansible/modules/network/ios/ios_system.py delete mode 100644 lib/ansible/modules/network/ios/ios_user.py delete mode 100644 lib/ansible/modules/network/ios/ios_vlans.py delete mode 100644 lib/ansible/modules/network/ios/ios_vrf.py delete mode 100644 lib/ansible/plugins/action/ios.py delete mode 100644 lib/ansible/plugins/cliconf/ios.py delete mode 100644 lib/ansible/plugins/doc_fragments/ios.py delete mode 100644 lib/ansible/plugins/terminal/ios.py delete mode 100644 test/integration/targets/ios_acl_interfaces/defaults/main.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tasks/main.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tests/cli/_parsed.cfg delete mode 100644 test/integration/targets/ios_acl_interfaces/tests/cli/_populate_config.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tests/cli/_remove_config.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tests/cli/deleted.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tests/cli/empty_config.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tests/cli/gathered.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tests/cli/merged.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tests/cli/overridden.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tests/cli/parsed.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tests/cli/rendered.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tests/cli/replaced.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/tests/cli/rtt.yaml delete mode 100644 test/integration/targets/ios_acl_interfaces/vars/main.yaml delete mode 100644 test/integration/targets/ios_acls/defaults/main.yaml delete mode 100644 test/integration/targets/ios_acls/meta/main.yaml delete mode 100644 test/integration/targets/ios_acls/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_acls/tasks/main.yaml delete mode 100644 test/integration/targets/ios_acls/tests/cli/_parsed.cfg delete mode 100644 test/integration/targets/ios_acls/tests/cli/_populate_config.yaml delete mode 100644 test/integration/targets/ios_acls/tests/cli/_remove_config.yaml delete mode 100644 test/integration/targets/ios_acls/tests/cli/deleted.yaml delete mode 100644 test/integration/targets/ios_acls/tests/cli/empty_config.yaml delete mode 100644 test/integration/targets/ios_acls/tests/cli/gathered.yaml delete mode 100644 test/integration/targets/ios_acls/tests/cli/merged.yaml delete mode 100644 test/integration/targets/ios_acls/tests/cli/overridden.yaml delete mode 100644 test/integration/targets/ios_acls/tests/cli/parsed.yaml delete mode 100644 test/integration/targets/ios_acls/tests/cli/rendered.yaml delete mode 100644 test/integration/targets/ios_acls/tests/cli/replaced.yaml delete mode 100644 test/integration/targets/ios_acls/tests/cli/rtt.yaml delete mode 100644 test/integration/targets/ios_acls/vars/main.yaml delete mode 100644 test/integration/targets/ios_banner/defaults/main.yaml delete mode 100644 test/integration/targets/ios_banner/meta/main.yml delete mode 100644 test/integration/targets/ios_banner/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_banner/tasks/main.yaml delete mode 100644 test/integration/targets/ios_banner/tests/cli/basic-login.yaml delete mode 100644 test/integration/targets/ios_banner/tests/cli/basic-motd.yaml delete mode 100644 test/integration/targets/ios_banner/tests/cli/basic-no-login.yaml delete mode 100644 test/integration/targets/ios_banner/tests/cli/multiple-login-exec.yaml delete mode 100644 test/integration/targets/ios_banner/tests/cli/net_banner.yml delete mode 100644 test/integration/targets/ios_bgp/defaults/main.yaml delete mode 100644 test/integration/targets/ios_bgp/meta/main.yaml delete mode 100644 test/integration/targets/ios_bgp/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_bgp/tasks/main.yaml delete mode 100644 test/integration/targets/ios_bgp/tests/cli/basic.yaml delete mode 100644 test/integration/targets/ios_command/defaults/main.yaml delete mode 100644 test/integration/targets/ios_command/meta/main.yml delete mode 100644 test/integration/targets/ios_command/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_command/tasks/main.yaml delete mode 100644 test/integration/targets/ios_command/tests/cli/bad_operator.yaml delete mode 100644 test/integration/targets/ios_command/tests/cli/cli_command.yaml delete mode 100644 test/integration/targets/ios_command/tests/cli/contains.yaml delete mode 100644 test/integration/targets/ios_command/tests/cli/error_regex.yaml delete mode 100644 test/integration/targets/ios_command/tests/cli/invalid.yaml delete mode 100644 test/integration/targets/ios_command/tests/cli/output.yaml delete mode 100644 test/integration/targets/ios_command/tests/cli/timeout.yaml delete mode 100644 test/integration/targets/ios_config/defaults/main.yaml delete mode 100644 test/integration/targets/ios_config/meta/main.yml delete mode 100644 test/integration/targets/ios_config/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_config/tasks/cli_config.yaml delete mode 100644 test/integration/targets/ios_config/tasks/main.yaml delete mode 100644 test/integration/targets/ios_config/templates/basic/base_running_config delete mode 100644 test/integration/targets/ios_config/templates/basic/config.j2 delete mode 100644 test/integration/targets/ios_config/templates/basic/configblock.j2 delete mode 100644 test/integration/targets/ios_config/templates/basic/configexact1.j2 delete mode 100644 test/integration/targets/ios_config/templates/basic/configexact2.j2 delete mode 100644 test/integration/targets/ios_config/templates/basic/configstrict1.j2 delete mode 100644 test/integration/targets/ios_config/templates/basic/intended_running_config delete mode 100644 test/integration/targets/ios_config/templates/basic/macro.j2 delete mode 100644 test/integration/targets/ios_config/templates/basic/setupblock.j2 delete mode 100644 test/integration/targets/ios_config/templates/basic/setupexact.j2 delete mode 100644 test/integration/targets/ios_config/templates/basic/setupstrict.j2 delete mode 100644 test/integration/targets/ios_config/templates/defaults/config.j2 delete mode 100644 test/integration/targets/ios_config/tests/cli/backup.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/defaults.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/diff.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/macro.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/save.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/src_basic.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/src_invalid.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/src_match_none.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/sublevel.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/sublevel_block.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/sublevel_exact.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/sublevel_strict.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/sublevel_strict_mul_parents.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/toplevel.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/toplevel_after.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/toplevel_before.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli/toplevel_nonidempotent.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli_config/cli_backup.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli_config/cli_basic.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli_config/cli_block_replace.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli_config/cli_exact_match.yaml delete mode 100644 test/integration/targets/ios_config/tests/cli_config/cli_strict_match.yaml delete mode 100644 test/integration/targets/ios_facts/defaults/main.yaml delete mode 100644 test/integration/targets/ios_facts/meta/main.yml delete mode 100644 test/integration/targets/ios_facts/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_facts/tasks/main.yaml delete mode 100644 test/integration/targets/ios_facts/tests/cli/all_facts.yaml delete mode 100644 test/integration/targets/ios_facts/tests/cli/default_facts.yaml delete mode 100644 test/integration/targets/ios_facts/tests/cli/invalid_subset.yaml delete mode 100644 test/integration/targets/ios_facts/tests/cli/not_hardware.yaml delete mode 100644 test/integration/targets/ios_file/aliases delete mode 100644 test/integration/targets/ios_file/defaults/main.yaml delete mode 100644 test/integration/targets/ios_file/ios1.cfg delete mode 100644 test/integration/targets/ios_file/nonascii.bin delete mode 100644 test/integration/targets/ios_file/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_file/tasks/main.yaml delete mode 100644 test/integration/targets/ios_file/tests/cli/net_get.yaml delete mode 100644 test/integration/targets/ios_file/tests/cli/net_put.yaml delete mode 100644 test/integration/targets/ios_interface/defaults/main.yaml delete mode 100644 test/integration/targets/ios_interface/meta/main.yaml delete mode 100644 test/integration/targets/ios_interface/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_interface/tasks/main.yaml delete mode 100644 test/integration/targets/ios_interface/tests/cli/basic.yaml delete mode 100644 test/integration/targets/ios_interface/tests/cli/intent.yaml delete mode 100644 test/integration/targets/ios_interface/tests/cli/net_interface.yaml delete mode 100644 test/integration/targets/ios_interfaces/defaults/main.yaml delete mode 100644 test/integration/targets/ios_interfaces/meta/main.yaml delete mode 100644 test/integration/targets/ios_interfaces/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_interfaces/tasks/main.yaml delete mode 100644 test/integration/targets/ios_interfaces/tests/cli/_populate_config.yaml delete mode 100644 test/integration/targets/ios_interfaces/tests/cli/_remove_config.yaml delete mode 100644 test/integration/targets/ios_interfaces/tests/cli/deleted.yaml delete mode 100644 test/integration/targets/ios_interfaces/tests/cli/empty_config.yaml delete mode 100644 test/integration/targets/ios_interfaces/tests/cli/merged.yaml delete mode 100644 test/integration/targets/ios_interfaces/tests/cli/overridden.yaml delete mode 100644 test/integration/targets/ios_interfaces/tests/cli/replaced.yaml delete mode 100644 test/integration/targets/ios_interfaces/vars/main.yaml delete mode 100644 test/integration/targets/ios_l2_interface/defaults/main.yaml delete mode 100644 test/integration/targets/ios_l2_interface/meta/main.yml delete mode 100644 test/integration/targets/ios_l2_interface/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_l2_interface/tasks/main.yaml delete mode 100644 test/integration/targets/ios_l2_interface/tests/cli/agg.yaml delete mode 100644 test/integration/targets/ios_l2_interface/tests/cli/sanity.yaml delete mode 100644 test/integration/targets/ios_l2_interfaces/defaults/main.yaml delete mode 100644 test/integration/targets/ios_l2_interfaces/meta/main.yaml delete mode 100644 test/integration/targets/ios_l2_interfaces/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_l2_interfaces/tasks/main.yaml delete mode 100644 test/integration/targets/ios_l2_interfaces/tests/cli/_populate_config.yaml delete mode 100644 test/integration/targets/ios_l2_interfaces/tests/cli/_remove_config.yaml delete mode 100644 test/integration/targets/ios_l2_interfaces/tests/cli/deleted.yaml delete mode 100644 test/integration/targets/ios_l2_interfaces/tests/cli/empty_config.yaml delete mode 100644 test/integration/targets/ios_l2_interfaces/tests/cli/merged.yaml delete mode 100644 test/integration/targets/ios_l2_interfaces/tests/cli/overridden.yaml delete mode 100644 test/integration/targets/ios_l2_interfaces/tests/cli/replaced.yaml delete mode 100644 test/integration/targets/ios_l2_interfaces/vars/main.yaml delete mode 100644 test/integration/targets/ios_l3_interface/defaults/main.yaml delete mode 100644 test/integration/targets/ios_l3_interface/meta/main.yaml delete mode 100644 test/integration/targets/ios_l3_interface/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_l3_interface/tasks/main.yaml delete mode 100644 test/integration/targets/ios_l3_interface/tests/cli/basic.yaml delete mode 100644 test/integration/targets/ios_l3_interfaces/defaults/main.yaml delete mode 100644 test/integration/targets/ios_l3_interfaces/meta/main.yaml delete mode 100644 test/integration/targets/ios_l3_interfaces/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_l3_interfaces/tasks/main.yaml delete mode 100644 test/integration/targets/ios_l3_interfaces/tests/cli/_populate_config.yaml delete mode 100644 test/integration/targets/ios_l3_interfaces/tests/cli/_remove_config.yaml delete mode 100644 test/integration/targets/ios_l3_interfaces/tests/cli/deleted.yaml delete mode 100644 test/integration/targets/ios_l3_interfaces/tests/cli/empty_config.yaml delete mode 100644 test/integration/targets/ios_l3_interfaces/tests/cli/merged.yaml delete mode 100644 test/integration/targets/ios_l3_interfaces/tests/cli/overridden.yaml delete mode 100644 test/integration/targets/ios_l3_interfaces/tests/cli/replaced.yaml delete mode 100644 test/integration/targets/ios_l3_interfaces/vars/main.yaml delete mode 100644 test/integration/targets/ios_lacp/aliases delete mode 100644 test/integration/targets/ios_lacp/defaults/main.yaml delete mode 100644 test/integration/targets/ios_lacp/meta/main.yaml delete mode 100644 test/integration/targets/ios_lacp/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_lacp/tasks/main.yaml delete mode 100644 test/integration/targets/ios_lacp/tests/cli/_populate_config.yaml delete mode 100644 test/integration/targets/ios_lacp/tests/cli/_remove_config.yaml delete mode 100644 test/integration/targets/ios_lacp/tests/cli/deleted.yaml delete mode 100644 test/integration/targets/ios_lacp/tests/cli/empty_config.yaml delete mode 100644 test/integration/targets/ios_lacp/tests/cli/merged.yaml delete mode 100644 test/integration/targets/ios_lacp/tests/cli/replaced.yaml delete mode 100644 test/integration/targets/ios_lacp/vars/main.yaml delete mode 100644 test/integration/targets/ios_lacp_interfaces/defaults/main.yaml delete mode 100644 test/integration/targets/ios_lacp_interfaces/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_lacp_interfaces/tasks/main.yaml delete mode 100644 test/integration/targets/ios_lacp_interfaces/tests/cli/_populate_config.yaml delete mode 100644 test/integration/targets/ios_lacp_interfaces/tests/cli/_remove_config.yaml delete mode 100644 test/integration/targets/ios_lacp_interfaces/tests/cli/deleted.yaml delete mode 100644 test/integration/targets/ios_lacp_interfaces/tests/cli/empty_config.yaml delete mode 100644 test/integration/targets/ios_lacp_interfaces/tests/cli/merged.yaml delete mode 100644 test/integration/targets/ios_lacp_interfaces/tests/cli/overridden.yaml delete mode 100644 test/integration/targets/ios_lacp_interfaces/tests/cli/replaced.yaml delete mode 100644 test/integration/targets/ios_lacp_interfaces/vars/main.yaml delete mode 100644 test/integration/targets/ios_lag_interfaces/defaults/main.yaml delete mode 100644 test/integration/targets/ios_lag_interfaces/meta/main.yaml delete mode 100644 test/integration/targets/ios_lag_interfaces/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_lag_interfaces/tasks/main.yaml delete mode 100644 test/integration/targets/ios_lag_interfaces/tests/cli/_populate_config.yaml delete mode 100644 test/integration/targets/ios_lag_interfaces/tests/cli/_remove_config.yaml delete mode 100644 test/integration/targets/ios_lag_interfaces/tests/cli/deleted.yaml delete mode 100644 test/integration/targets/ios_lag_interfaces/tests/cli/empty_config.yaml delete mode 100644 test/integration/targets/ios_lag_interfaces/tests/cli/merged.yaml delete mode 100644 test/integration/targets/ios_lag_interfaces/tests/cli/overridden.yaml delete mode 100644 test/integration/targets/ios_lag_interfaces/tests/cli/replaced.yaml delete mode 100644 test/integration/targets/ios_lag_interfaces/vars/main.yaml delete mode 100644 test/integration/targets/ios_linkagg/defaults/main.yaml delete mode 100644 test/integration/targets/ios_linkagg/meta/main.yaml delete mode 100644 test/integration/targets/ios_linkagg/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_linkagg/tasks/main.yaml delete mode 100644 test/integration/targets/ios_linkagg/tests/cli/basic.yaml delete mode 100644 test/integration/targets/ios_lldp/defaults/main.yaml delete mode 100644 test/integration/targets/ios_lldp/meta/main.yaml delete mode 100644 test/integration/targets/ios_lldp/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_lldp/tasks/main.yaml delete mode 100644 test/integration/targets/ios_lldp/tests/cli/basic.yaml delete mode 100644 test/integration/targets/ios_lldp_global/aliases delete mode 100644 test/integration/targets/ios_lldp_global/defaults/main.yaml delete mode 100644 test/integration/targets/ios_lldp_global/meta/main.yaml delete mode 100644 test/integration/targets/ios_lldp_global/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_lldp_global/tasks/main.yaml delete mode 100644 test/integration/targets/ios_lldp_global/tests/cli/_populate_config.yaml delete mode 100644 test/integration/targets/ios_lldp_global/tests/cli/_remove_config.yaml delete mode 100644 test/integration/targets/ios_lldp_global/tests/cli/deleted.yaml delete mode 100644 test/integration/targets/ios_lldp_global/tests/cli/empty_config.yaml delete mode 100644 test/integration/targets/ios_lldp_global/tests/cli/merged.yaml delete mode 100644 test/integration/targets/ios_lldp_global/tests/cli/replaced.yaml delete mode 100644 test/integration/targets/ios_lldp_global/vars/main.yaml delete mode 100644 test/integration/targets/ios_lldp_interfaces/defaults/main.yaml delete mode 100644 test/integration/targets/ios_lldp_interfaces/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_lldp_interfaces/tasks/main.yaml delete mode 100644 test/integration/targets/ios_lldp_interfaces/tests/cli/_enable_lldp.yaml delete mode 100644 test/integration/targets/ios_lldp_interfaces/tests/cli/_populate_config.yaml delete mode 100644 test/integration/targets/ios_lldp_interfaces/tests/cli/_remove_config.yaml delete mode 100644 test/integration/targets/ios_lldp_interfaces/tests/cli/deleted.yaml delete mode 100644 test/integration/targets/ios_lldp_interfaces/tests/cli/empty_config.yaml delete mode 100644 test/integration/targets/ios_lldp_interfaces/tests/cli/merged.yaml delete mode 100644 test/integration/targets/ios_lldp_interfaces/tests/cli/overridden.yaml delete mode 100644 test/integration/targets/ios_lldp_interfaces/tests/cli/replaced.yaml delete mode 100644 test/integration/targets/ios_lldp_interfaces/vars/main.yaml delete mode 100644 test/integration/targets/ios_logging/defaults/main.yaml delete mode 100644 test/integration/targets/ios_logging/meta/main.yaml delete mode 100644 test/integration/targets/ios_logging/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_logging/tasks/main.yaml delete mode 100644 test/integration/targets/ios_logging/tests/cli/basic.yaml delete mode 100644 test/integration/targets/ios_logging/tests/cli/net_logging.yaml delete mode 100644 test/integration/targets/ios_ntp/defaults/main.yaml delete mode 100644 test/integration/targets/ios_ntp/meta/main.yml delete mode 100644 test/integration/targets/ios_ntp/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_ntp/tasks/main.yaml delete mode 100644 test/integration/targets/ios_ntp/tests/cli/ntp_configuration.yaml delete mode 100644 test/integration/targets/ios_ping/defaults/main.yaml delete mode 100644 test/integration/targets/ios_ping/meta/main.yaml delete mode 100644 test/integration/targets/ios_ping/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_ping/tasks/main.yaml delete mode 100644 test/integration/targets/ios_ping/tests/cli/ping.yaml delete mode 100644 test/integration/targets/ios_smoke/defaults/main.yaml delete mode 100644 test/integration/targets/ios_smoke/meta/main.yaml delete mode 100644 test/integration/targets/ios_smoke/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_smoke/tasks/main.yaml delete mode 100644 test/integration/targets/ios_smoke/templates/defaults/config.j2 delete mode 100644 test/integration/targets/ios_smoke/tests/cli/common_config.yaml delete mode 100644 test/integration/targets/ios_smoke/tests/cli/common_utils.yaml delete mode 100644 test/integration/targets/ios_smoke/tests/cli/misc_tests.yaml delete mode 100644 test/integration/targets/ios_smoke/tests/cli/reboot.yaml delete mode 100644 test/integration/targets/ios_static_route/defaults/main.yaml delete mode 100644 test/integration/targets/ios_static_route/meta/main.yaml delete mode 100644 test/integration/targets/ios_static_route/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_static_route/tasks/main.yaml delete mode 100644 test/integration/targets/ios_static_route/tests/cli/basic.yaml delete mode 100644 test/integration/targets/ios_static_route/tests/cli/net_static_route.yaml delete mode 100644 test/integration/targets/ios_static_routes/defaults/main.yaml delete mode 100644 test/integration/targets/ios_static_routes/meta/main.yaml delete mode 100644 test/integration/targets/ios_static_routes/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_static_routes/tasks/main.yaml delete mode 100644 test/integration/targets/ios_static_routes/tests/cli/_intial_setup_config.yaml delete mode 100644 test/integration/targets/ios_static_routes/tests/cli/_populate_config.yaml delete mode 100644 test/integration/targets/ios_static_routes/tests/cli/_remove_config.yaml delete mode 100644 test/integration/targets/ios_static_routes/tests/cli/deleted.yaml delete mode 100644 test/integration/targets/ios_static_routes/tests/cli/empty_config.yaml delete mode 100644 test/integration/targets/ios_static_routes/tests/cli/gathered.yaml delete mode 100644 test/integration/targets/ios_static_routes/tests/cli/merged.yaml delete mode 100644 test/integration/targets/ios_static_routes/tests/cli/overridden.yaml delete mode 100644 test/integration/targets/ios_static_routes/tests/cli/rendered.yaml delete mode 100644 test/integration/targets/ios_static_routes/tests/cli/replaced.yaml delete mode 100644 test/integration/targets/ios_static_routes/tests/cli/rtt.yaml delete mode 100644 test/integration/targets/ios_static_routes/vars/main.yaml delete mode 100644 test/integration/targets/ios_system/defaults/main.yaml delete mode 100644 test/integration/targets/ios_system/meta/main.yml delete mode 100644 test/integration/targets/ios_system/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_system/tasks/main.yaml delete mode 100644 test/integration/targets/ios_system/tests/cli/net_system.yaml delete mode 100644 test/integration/targets/ios_system/tests/cli/set_domain_list.yaml delete mode 100644 test/integration/targets/ios_system/tests/cli/set_domain_name.yaml delete mode 100644 test/integration/targets/ios_system/tests/cli/set_hostname.yaml delete mode 100644 test/integration/targets/ios_system/tests/cli/set_lookup_source.yaml delete mode 100644 test/integration/targets/ios_system/tests/cli/set_name_servers.yaml delete mode 100644 test/integration/targets/ios_user/defaults/main.yaml delete mode 100644 test/integration/targets/ios_user/files/test_rsa delete mode 100644 test/integration/targets/ios_user/files/test_rsa.pub delete mode 100644 test/integration/targets/ios_user/meta/main.yaml delete mode 100644 test/integration/targets/ios_user/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_user/tasks/main.yaml delete mode 100644 test/integration/targets/ios_user/tests/cli/auth.yaml delete mode 100644 test/integration/targets/ios_user/tests/cli/basic.yaml delete mode 100644 test/integration/targets/ios_vlan/defaults/main.yaml delete mode 100644 test/integration/targets/ios_vlan/meta/main.yaml delete mode 100644 test/integration/targets/ios_vlan/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_vlan/tasks/main.yaml delete mode 100644 test/integration/targets/ios_vlan/tests/cli/basic.yaml delete mode 100644 test/integration/targets/ios_vlans/defaults/main.yaml delete mode 100644 test/integration/targets/ios_vlans/meta/main.yaml delete mode 100644 test/integration/targets/ios_vlans/tasks/cli.yaml delete mode 100644 test/integration/targets/ios_vlans/tasks/main.yaml delete mode 100644 test/integration/targets/ios_vlans/tests/cli/_populate_config.yaml delete mode 100644 test/integration/targets/ios_vlans/tests/cli/_remove_config.yaml delete mode 100644 test/integration/targets/ios_vlans/tests/cli/deleted.yaml delete mode 100644 test/integration/targets/ios_vlans/tests/cli/empty_config.yaml delete mode 100644 test/integration/targets/ios_vlans/tests/cli/merged.yaml delete mode 100644 test/integration/targets/ios_vlans/tests/cli/overridden.yaml delete mode 100644 test/integration/targets/ios_vlans/tests/cli/replaced.yaml delete mode 100644 test/integration/targets/ios_vlans/vars/main.yaml delete mode 100644 test/units/modules/network/ios/fixtures/configure_terminal delete mode 100644 test/units/modules/network/ios/fixtures/ios_acl_interfaces.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_acls_config.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_banner_show_banner.txt delete mode 100644 test/units/modules/network/ios/fixtures/ios_banner_show_running_config_ios12.txt delete mode 100644 test/units/modules/network/ios/fixtures/ios_bgp_config.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_config_config.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_config_defaults.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_config_src.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_facts_dir delete mode 100644 test/units/modules/network/ios/fixtures/ios_facts_show_cdp delete mode 100644 test/units/modules/network/ios/fixtures/ios_facts_show_cdp_neighbors_detail delete mode 100644 test/units/modules/network/ios/fixtures/ios_facts_show_interfaces delete mode 100644 test/units/modules/network/ios/fixtures/ios_facts_show_ip_interface delete mode 100644 test/units/modules/network/ios/fixtures/ios_facts_show_ipv6_interface delete mode 100644 test/units/modules/network/ios/fixtures/ios_facts_show_lldp delete mode 100644 test/units/modules/network/ios/fixtures/ios_facts_show_lldp_neighbors_detail delete mode 100644 test/units/modules/network/ios/fixtures/ios_facts_show_memory_statistics delete mode 100644 test/units/modules/network/ios/fixtures/ios_facts_show_version delete mode 100644 test/units/modules/network/ios/fixtures/ios_logging_config.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_logging_config_ios12.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_ntp_config.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_ping_ping_10.255.255.250_repeat_2 delete mode 100644 test/units/modules/network/ios/fixtures/ios_ping_ping_8.8.8.8_repeat_2 delete mode 100644 test/units/modules/network/ios/fixtures/ios_static_routes_config.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_system_config.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_user_config.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_vlan_config.cfg delete mode 100644 test/units/modules/network/ios/fixtures/ios_vrf_config.cfg delete mode 100644 test/units/modules/network/ios/fixtures/show_version delete mode 100644 test/units/modules/network/ios/ios_module.py delete mode 100644 test/units/modules/network/ios/test_ios_acl_interfaces.py delete mode 100644 test/units/modules/network/ios/test_ios_acls.py delete mode 100644 test/units/modules/network/ios/test_ios_banner.py delete mode 100644 test/units/modules/network/ios/test_ios_bgp.py delete mode 100644 test/units/modules/network/ios/test_ios_command.py delete mode 100644 test/units/modules/network/ios/test_ios_config.py delete mode 100644 test/units/modules/network/ios/test_ios_facts.py delete mode 100644 test/units/modules/network/ios/test_ios_logging.py delete mode 100644 test/units/modules/network/ios/test_ios_ntp.py delete mode 100644 test/units/modules/network/ios/test_ios_ping.py delete mode 100644 test/units/modules/network/ios/test_ios_static_routes.py delete mode 100644 test/units/modules/network/ios/test_ios_system.py delete mode 100644 test/units/modules/network/ios/test_ios_user.py delete mode 100644 test/units/modules/network/ios/test_ios_vlan.py delete mode 100644 test/units/modules/network/ios/test_ios_vrf.py delete mode 100644 test/units/plugins/cliconf/fixtures/ios/show_version delete mode 100644 test/units/plugins/cliconf/fixtures/nos/show_chassis delete mode 100644 test/units/plugins/cliconf/fixtures/nos/show_running-config delete mode 100644 test/units/plugins/cliconf/fixtures/nos/show_version delete mode 100644 test/units/plugins/cliconf/fixtures/slxos/show_chassis delete mode 100644 test/units/plugins/cliconf/fixtures/slxos/show_running-config delete mode 100644 test/units/plugins/cliconf/fixtures/slxos/show_startup-config delete mode 100644 test/units/plugins/cliconf/fixtures/slxos/show_version delete mode 100644 test/units/plugins/cliconf/test_ios.py diff --git a/lib/ansible/module_utils/network/ios/argspec/acl_interfaces/acl_interfaces.py b/lib/ansible/module_utils/network/ios/argspec/acl_interfaces/acl_interfaces.py deleted file mode 100644 index 608cf6e728b..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/acl_interfaces/acl_interfaces.py +++ /dev/null @@ -1,66 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The arg spec for the ios_acl_interfaces module -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class Acl_InterfacesArgs(object): - """The arg spec for the ios_acl_interfaces module - """ - - argument_spec = { - 'config': { - 'elements': 'dict', - 'options': { - 'name': {'required': True, 'type': 'str'}, - 'access_groups': { - 'type': 'list', - 'elements': 'dict', - 'options': { - 'afi': {'required': True, 'choices': ['ipv4', 'ipv6'], 'type': 'str'}, - 'acls': { - 'type': 'list', - 'elements': 'dict', - 'options': { - 'name': {'required': True, 'type': 'str'}, - 'direction': {'required': True, 'choices': ['in', 'out'], 'type': 'str'} - } - } - } - } - }, - 'type': 'list' - }, - 'running_config': {'type': 'str'}, - 'state': { - 'choices': ['merged', 'replaced', 'overridden', 'deleted', 'gathered', 'rendered', 'parsed'], - 'default': 'merged', - 'type': 'str' - } - } diff --git a/lib/ansible/module_utils/network/ios/argspec/acls/acls.py b/lib/ansible/module_utils/network/ios/argspec/acls/acls.py deleted file mode 100644 index ca8982e557f..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/acls/acls.py +++ /dev/null @@ -1,593 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# -""" -The arg spec for the ios_acls module -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class AclsArgs(object): - """The arg spec for the ios_acls module - """ - def __init__(self, **kwargs): - pass - - argument_spec = { - 'config': { - 'elements': 'dict', - 'options': { - 'afi': { - 'required': True, - 'choices': ['ipv4', 'ipv6'], - 'type': 'str' - }, - 'acls': { - 'elements': 'dict', - 'type': 'list', - 'options': { - 'name': { - 'required': True, - 'type': 'str' - }, - 'acl_type': { - 'choices': ['extended', 'standard'], - 'type': 'str' - }, - 'aces': { - 'elements': 'dict', - 'type': 'list', - 'options': { - 'grant': { - 'choices': ['permit', 'deny'], - 'type': 'str' - }, - 'sequence': { - 'type': 'int' - }, - 'source': { - 'type': - 'dict', - 'mutually_exclusive': - [['address', 'any', 'host'], - ['wildcard_bits', 'any', 'host']], - 'options': { - 'address': { - 'type': 'str' - }, - 'wildcard_bits': { - 'type': 'str' - }, - 'any': { - 'type': 'bool' - }, - 'host': { - 'type': 'str' - }, - 'port_protocol': { - 'type': 'dict', - 'options': { - 'eq': { - 'type': 'str' - }, - 'gt': { - 'type': 'str' - }, - 'lt': { - 'type': 'str' - }, - 'neq': { - 'type': 'str' - }, - 'range': { - 'type': 'dict', - 'options': { - 'start': { - 'type': 'int' - }, - 'end': { - 'type': 'int' - } - } - } - } - } - }, - }, - 'destination': { - 'type': - 'dict', - 'mutually_exclusive': - [['address', 'any', 'host'], - ['wildcard_bits', 'any', 'host']], - 'options': { - 'address': { - 'type': 'str' - }, - 'wildcard_bits': { - 'type': 'str' - }, - 'any': { - 'type': 'bool' - }, - 'host': { - 'type': 'str' - }, - 'port_protocol': { - 'type': 'dict', - 'options': { - 'eq': { - 'type': 'str' - }, - 'gt': { - 'type': 'str' - }, - 'lt': { - 'type': 'str' - }, - 'neq': { - 'type': 'str' - }, - 'range': { - 'type': 'dict', - 'options': { - 'start': { - 'type': 'int' - }, - 'end': { - 'type': 'int' - } - } - } - } - } - } - }, - 'protocol': { - 'type': 'str' - }, - 'protocol_options': { - 'type': 'dict', - 'options': { - 'protocol_number': { - 'type': 'int' - }, - 'ahp': { - 'type': 'bool' - }, - 'eigrp': { - 'type': 'bool' - }, - 'esp': { - 'type': 'bool' - }, - 'gre': { - 'type': 'bool' - }, - 'hbh': { - 'type': 'bool' - }, - 'icmp': { - 'type': 'dict', - 'options': { - 'administratively_prohibited': - { - 'type': 'bool' - }, - 'alternate_address': { - 'type': 'bool' - }, - 'conversion_error': { - 'type': 'bool' - }, - 'dod_host_prohibited': { - 'type': 'bool' - }, - 'dod_net_prohibited': { - 'type': 'bool' - }, - 'echo': { - 'type': 'bool' - }, - 'echo_reply': { - 'type': 'bool' - }, - 'general_parameter_problem': { - 'type': 'bool' - }, - 'host_isolated': { - 'type': 'bool' - }, - 'host_precedence_unreachable': - { - 'type': 'bool' - }, - 'host_redirect': { - 'type': 'bool' - }, - 'host_tos_redirect': { - 'type': 'bool' - }, - 'host_tos_unreachable': { - 'type': 'bool' - }, - 'host_unknown': { - 'type': 'bool' - }, - 'host_unreachable': { - 'type': 'bool' - }, - 'information_reply': { - 'type': 'bool' - }, - 'information_request': { - 'type': 'bool' - }, - 'mask_reply': { - 'type': 'bool' - }, - 'mask_request': { - 'type': 'bool' - }, - 'mobile_redirect': { - 'type': 'bool' - }, - 'net_redirect': { - 'type': 'bool' - }, - 'net_tos_redirect': { - 'type': 'bool' - }, - 'net_tos_unreachable': { - 'type': 'bool' - }, - 'net_unreachable': { - 'type': 'bool' - }, - 'network_unknown': { - 'type': 'bool' - }, - 'no_room_for_option': { - 'type': 'bool' - }, - 'option_missing': { - 'type': 'bool' - }, - 'packet_too_big': { - 'type': 'bool' - }, - 'parameter_problem': { - 'type': 'bool' - }, - 'port_unreachable': { - 'type': 'bool' - }, - 'precedence_unreachable': { - 'type': 'bool' - }, - 'protocol_unreachable': { - 'type': 'bool' - }, - 'reassembly_timeout': { - 'type': 'bool' - }, - 'redirect': { - 'type': 'bool' - }, - 'router_advertisement': { - 'type': 'bool' - }, - 'router_solicitation': { - 'type': 'bool' - }, - 'source_quench': { - 'type': 'bool' - }, - 'source_route_failed': { - 'type': 'bool' - }, - 'time_exceeded': { - 'type': 'bool' - }, - 'timestamp_reply': { - 'type': 'bool' - }, - 'timestamp_request': { - 'type': 'bool' - }, - 'traceroute': { - 'type': 'bool' - }, - 'ttl_exceeded': { - 'type': 'bool' - }, - 'unreachable': { - 'type': 'bool' - }, - } - }, - 'igmp': { - 'type': 'dict', - 'options': { - 'dvmrp': { - 'type': 'bool' - }, - 'host_query': { - 'type': 'bool' - }, - 'mtrace_resp': { - 'type': 'bool' - }, - 'mtrace_route': { - 'type': 'bool' - }, - 'pim': { - 'type': 'bool' - }, - 'trace': { - 'type': 'bool' - }, - 'v1host_report': { - 'type': 'bool' - }, - 'v2host_report': { - 'type': 'bool' - }, - 'v2leave_group': { - 'type': 'bool' - }, - 'v3host_report': { - 'type': 'bool' - } - } - }, - 'ip': { - 'type': 'bool' - }, - 'ipv6': { - 'type': 'bool' - }, - 'ipinip': { - 'type': 'bool' - }, - 'nos': { - 'type': 'bool' - }, - 'ospf': { - 'type': 'bool' - }, - 'pcp': { - 'type': 'bool' - }, - 'pim': { - 'type': 'bool' - }, - 'sctp': { - 'type': 'bool' - }, - 'tcp': { - 'options': { - 'ack': { - 'type': 'bool' - }, - 'established': { - 'type': 'bool' - }, - 'fin': { - 'type': 'bool' - }, - 'psh': { - 'type': 'bool' - }, - 'rst': { - 'type': 'bool' - }, - 'syn': { - 'type': 'bool' - }, - 'urg': { - 'type': 'bool' - } - }, - 'type': 'dict' - }, - 'udp': { - 'type': 'bool' - } - } - }, - 'dscp': { - 'type': 'str' - }, - 'fragments': { - 'type': 'str' - }, - 'log': { - 'type': 'str' - }, - 'log_input': { - 'type': 'str' - }, - 'option': { - 'type': 'dict', - 'options': { - 'add_ext': { - 'type': 'bool' - }, - 'any_options': { - 'type': 'bool' - }, - 'com_security': { - 'type': 'bool' - }, - 'dps': { - 'type': 'bool' - }, - 'encode': { - 'type': 'bool' - }, - 'eool': { - 'type': 'bool' - }, - 'ext_ip': { - 'type': 'bool' - }, - 'ext_security': { - 'type': 'bool' - }, - 'finn': { - 'type': 'bool' - }, - 'imitd': { - 'type': 'bool' - }, - 'lsr': { - 'type': 'bool' - }, - 'mtup': { - 'type': 'bool' - }, - 'mtur': { - 'type': 'bool' - }, - 'no_op': { - 'type': 'bool' - }, - 'nsapa': { - 'type': 'bool' - }, - 'record_route': { - 'type': 'bool' - }, - 'router_alert': { - 'type': 'bool' - }, - 'sdb': { - 'type': 'bool' - }, - 'security': { - 'type': 'bool' - }, - 'ssr': { - 'type': 'bool' - }, - 'stream_id': { - 'type': 'bool' - }, - 'timestamp': { - 'type': 'bool' - }, - 'traceroute': { - 'type': 'bool' - }, - 'ump': { - 'type': 'bool' - }, - 'visa': { - 'type': 'bool' - }, - 'zsu': { - 'type': 'bool' - } - } - }, - 'precedence': { - 'type': 'int' - }, - 'time_range': { - 'type': 'str' - }, - 'tos': { - 'type': 'dict', - 'options': { - 'service_value': { - 'type': 'int' - }, - 'max_reliability': { - 'type': 'bool' - }, - 'max_throughput': { - 'type': 'bool' - }, - 'min_delay': { - 'type': 'bool' - }, - 'min_monetary_cost': { - 'type': 'bool' - }, - 'normal': { - 'type': 'bool' - } - } - }, - 'ttl': { - 'type': 'dict', - 'options': { - 'eq': { - 'type': 'int' - }, - 'gt': { - 'type': 'int' - }, - 'lt': { - 'type': 'int' - }, - 'neq': { - 'type': 'int' - }, - 'range': { - 'type': 'dict', - 'options': { - 'start': { - 'type': 'int' - }, - 'end': { - 'type': 'int' - } - } - } - } - }, - } - } - } - }, - }, - 'type': 'list' - }, - 'running_config': { - 'type': 'str' - }, - 'state': { - 'choices': [ - 'merged', 'replaced', 'overridden', 'deleted', 'gathered', - 'rendered', 'parsed' - ], - 'default': - 'merged', - 'type': - 'str' - } - } diff --git a/lib/ansible/module_utils/network/ios/argspec/facts/facts.py b/lib/ansible/module_utils/network/ios/argspec/facts/facts.py deleted file mode 100644 index 8cac9e98276..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/facts/facts.py +++ /dev/null @@ -1,24 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The arg spec for the ios facts module. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class FactsArgs(object): - """ The arg spec for the ios facts module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = { - 'gather_subset': dict(default=['!config'], type='list'), - 'gather_network_resources': dict(type='list'), - } diff --git a/lib/ansible/module_utils/network/ios/argspec/interfaces/interfaces.py b/lib/ansible/module_utils/network/ios/argspec/interfaces/interfaces.py deleted file mode 100644 index ae097f53079..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/interfaces/interfaces.py +++ /dev/null @@ -1,47 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# -""" -The arg spec for the ios_interfaces module -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class InterfacesArgs(object): - - def __init__(self, **kwargs): - pass - - argument_spec = {'config': {'elements': 'dict', - 'options': {'name': {'type': 'str', 'required': True}, - 'description': {'type': 'str'}, - 'enabled': {'default': True, 'type': 'bool'}, - 'speed': {'type': 'str'}, - 'mtu': {'type': 'int'}, - 'duplex': {'type': 'str', 'choices': ['full', 'half', 'auto']}}, - 'type': 'list'}, - 'state': {'choices': ['merged', 'replaced', 'overridden', 'deleted'], - 'default': 'merged', - 'type': 'str'}} diff --git a/lib/ansible/module_utils/network/ios/argspec/l2_interfaces/l2_interfaces.py b/lib/ansible/module_utils/network/ios/argspec/l2_interfaces/l2_interfaces.py deleted file mode 100644 index 5ef51fa23de..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/l2_interfaces/l2_interfaces.py +++ /dev/null @@ -1,57 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# -""" -The arg spec for the ios_l2_interfaces module -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class L2_InterfacesArgs(object): - - def __init__(self, **kwargs): - pass - - argument_spec = {'config': {'elements': 'dict', - 'options': {'name': {'type': 'str', 'required': True}, - 'mode': {'type': 'str', 'choices': ['access', 'trunk']}, - 'access': {'type': 'dict', - 'options': {'vlan': {'type': 'int'}} - }, - 'voice': {'type': 'dict', - 'options': {'vlan': {'type': 'int'}} - }, - 'trunk': {'type': 'dict', - 'options': {'allowed_vlans': {'type': 'list'}, - 'encapsulation': {'type': 'str', - 'choices': - ['dot1q', 'isl', 'negotiate']}, - 'native_vlan': {'type': 'int'}, - 'pruning_vlans': {'type': 'list'}} - }}, - 'type': 'list'}, - 'state': {'choices': ['merged', 'replaced', 'overridden', 'deleted'], - 'default': 'merged', - 'type': 'str'}} diff --git a/lib/ansible/module_utils/network/ios/argspec/l3_interfaces/l3_interfaces.py b/lib/ansible/module_utils/network/ios/argspec/l3_interfaces/l3_interfaces.py deleted file mode 100644 index cdf209a27ad..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/l3_interfaces/l3_interfaces.py +++ /dev/null @@ -1,53 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# -""" -The arg spec for the ios_l3_interfaces module -""" - - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class L3_InterfacesArgs(object): - - def __init__(self, **kwargs): - pass - - argument_spec = {'config': {'elements': 'dict', - 'options': {'name': {'type': 'str', 'required': True}, - 'ipv4': {'element': 'dict', - 'type': 'list', - 'options': {'address': {'type': 'str'}, - 'secondary': {'type': 'bool'}, - 'dhcp_client': {'type': 'int'}, - 'dhcp_hostname': {'type': 'str'}}}, - 'ipv6': {'element': 'dict', - 'type': 'list', - 'options': {'address': {'type': 'str'}}} - }, - 'type': 'list'}, - 'state': {'choices': ['merged', 'replaced', 'overridden', 'deleted'], - 'default': 'merged', - 'type': 'str'}} diff --git a/lib/ansible/module_utils/network/ios/argspec/lacp/lacp.py b/lib/ansible/module_utils/network/ios/argspec/lacp/lacp.py deleted file mode 100644 index 1e7294bc5c6..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/lacp/lacp.py +++ /dev/null @@ -1,47 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The arg spec for the ios_lacp module -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class LacpArgs(object): - """The arg spec for the ios_lacp module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = { - 'config': {'options': {'system': {'options': {'priority': {'required': True, 'type': 'int'}}, - 'type': 'dict'} - }, 'type': 'dict' - }, - 'state': {'choices': ['merged', 'replaced', 'deleted'], 'default': 'merged', - 'type': 'str'} - } diff --git a/lib/ansible/module_utils/network/ios/argspec/lacp_interfaces/lacp_interfaces.py b/lib/ansible/module_utils/network/ios/argspec/lacp_interfaces/lacp_interfaces.py deleted file mode 100644 index 10b17e56352..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/lacp_interfaces/lacp_interfaces.py +++ /dev/null @@ -1,48 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The arg spec for the ios_lacp_interfaces module -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class Lacp_InterfacesArgs(object): - """The arg spec for the ios_lacp_interfaces module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = {'config': {'elements': 'dict', - 'options': {'name': {'required': True, 'type': 'str'}, - 'port_priority': {'type': 'int'}, - 'fast_switchover': {'type': 'bool'}, - 'max_bundle': {'type': 'int'}}, - 'type': 'list'}, - 'state': {'choices': ['merged', 'replaced', 'overridden', 'deleted'], - 'default': 'merged', - 'type': 'str'}} diff --git a/lib/ansible/module_utils/network/ios/argspec/lag_interfaces/lag_interfaces.py b/lib/ansible/module_utils/network/ios/argspec/lag_interfaces/lag_interfaces.py deleted file mode 100644 index 0f9b7e25359..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/lag_interfaces/lag_interfaces.py +++ /dev/null @@ -1,52 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The arg spec for the ios_lag_interfaces module -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class Lag_interfacesArgs(object): - - def __init__(self, **kwargs): - pass - - argument_spec = {'config': {'elements': 'dict', - 'options': {'name': {'required': True, 'type': 'str'}, - 'members': {'elements': 'dict', - 'options': { - 'member': {'type': 'str'}, - 'mode': {'choices': ['auto', 'on', 'desirable', - 'active', 'passive'], - 'type': 'str', 'required': True}, - 'link': {'type': 'int'} - }, - 'type': 'list'}}, - 'type': 'list'}, - 'state': {'choices': ['merged', 'replaced', 'overridden', 'deleted'], - 'default': 'merged', - 'type': 'str'}} diff --git a/lib/ansible/module_utils/network/ios/argspec/lldp_global/lldp_global.py b/lib/ansible/module_utils/network/ios/argspec/lldp_global/lldp_global.py deleted file mode 100644 index 62630036c2c..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/lldp_global/lldp_global.py +++ /dev/null @@ -1,58 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# -""" -The arg spec for the ios_lldp_global module -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class Lldp_globalArgs(object): - - def __init__(self, **kwargs): - pass - - argument_spec = {'config': {'options': {'holdtime': {'type': 'int'}, - 'reinit': {'type': 'int'}, - 'enabled': {'type': 'bool'}, - 'timer': {'type': 'int'}, - 'tlv_select': { - 'options': { - 'four_wire_power_management': {'type': 'bool'}, - 'mac_phy_cfg': {'type': 'bool'}, - 'management_address': {'type': 'bool'}, - 'port_description': {'type': 'bool'}, - 'port_vlan': {'type': 'bool'}, - 'power_management': {'type': 'bool'}, - 'system_capabilities': {'type': 'bool'}, - 'system_description': {'type': 'bool'}, - 'system_name': {'type': 'bool'} - }, - 'type': 'dict'}, - }, - 'type': 'dict'}, - 'state': {'choices': ['merged', 'replaced', 'deleted'], - 'default': 'merged', - 'type': 'str'}} diff --git a/lib/ansible/module_utils/network/ios/argspec/lldp_interfaces/lldp_interfaces.py b/lib/ansible/module_utils/network/ios/argspec/lldp_interfaces/lldp_interfaces.py deleted file mode 100644 index 45af268d4d1..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/lldp_interfaces/lldp_interfaces.py +++ /dev/null @@ -1,52 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The arg spec for the ios_lldp_interfaces module -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class Lldp_InterfacesArgs(object): - """The arg spec for the ios_lldp_interfaces module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = {'config': {'elements': 'dict', - 'options': {'name': {'required': True, 'type': 'str'}, - 'transmit': {'type': 'bool'}, - 'receive': {'type': 'bool'}, - 'med_tlv_select': {'options': {'inventory_management': {'type': 'bool'}}, - 'type': 'dict'}, - 'tlv_select': {'options': {'power_management': {'type': 'bool'}}, - 'type': 'dict'} - }, - 'type': 'list'}, - 'state': {'choices': ['merged', 'replaced', 'overridden', 'deleted'], - 'default': 'merged', - 'type': 'str'}} diff --git a/lib/ansible/module_utils/network/ios/argspec/static_routes/static_routes.py b/lib/ansible/module_utils/network/ios/argspec/static_routes/static_routes.py deleted file mode 100644 index 33621879873..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/static_routes/static_routes.py +++ /dev/null @@ -1,85 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The arg spec for the ios_static_routes module -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class Static_RoutesArgs(object): - """The arg spec for the ios_static_routes module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = { - 'config': { - 'elements': 'dict', - 'options': { - 'vrf': {'type': 'str'}, - 'address_families': { - 'elements': 'dict', - 'type': 'list', - 'options': { - 'afi': {'required': True, 'choices': ['ipv4', 'ipv6'], 'type': 'str'}, - 'routes': { - 'elements': 'dict', - 'type': 'list', - 'options': { - 'dest': {'required': True, 'type': 'str'}, - 'topology': {'type': 'str'}, - 'next_hops': { - 'elements': 'dict', - 'type': 'list', - 'options': { - 'forward_router_address': {'type': 'str'}, - 'interface': {'type': 'str'}, - 'dhcp': {'type': 'bool'}, - 'distance_metric': {'type': 'int'}, - 'global': {'type': 'bool'}, - 'name': {'type': 'str'}, - 'multicast': {'type': 'bool'}, - 'permanent': {'type': 'bool'}, - 'tag': {'type': 'int'}, - 'track': {'type': 'int'} - } - } - } - } - } - } - }, - 'type': 'list' - }, - 'running_config': {'type': 'str'}, - 'state': { - 'choices': ['merged', 'replaced', 'overridden', 'deleted', 'gathered', 'rendered', 'parsed'], - 'default': 'merged', - 'type': 'str' - } - } diff --git a/lib/ansible/module_utils/network/ios/argspec/vlans/vlans.py b/lib/ansible/module_utils/network/ios/argspec/vlans/vlans.py deleted file mode 100644 index 893904cfe74..00000000000 --- a/lib/ansible/module_utils/network/ios/argspec/vlans/vlans.py +++ /dev/null @@ -1,50 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The arg spec for the ios_vlans module -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -class VlansArgs(object): - """The arg spec for the ios_vlans module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = {'config': {'elements': 'dict', - 'options': {'name': {'type': 'str'}, - 'vlan_id': {'required': True, 'type': 'int'}, - 'mtu': {'type': 'int'}, - 'remote_span': {'type': 'bool'}, - 'state': {'type': 'str', 'choices': ['active', 'suspend']}, - 'shutdown': {'type': 'str', 'choices': ['enabled', 'disabled']}}, - 'type': 'list'}, - 'state': {'choices': ['merged', 'replaced', 'overridden', 'deleted'], - 'default': 'merged', - 'type': 'str'}} diff --git a/lib/ansible/module_utils/network/ios/config/acl_interfaces/acl_interfaces.py b/lib/ansible/module_utils/network/ios/config/acl_interfaces/acl_interfaces.py deleted file mode 100644 index fa3352389c6..00000000000 --- a/lib/ansible/module_utils/network/ios/config/acl_interfaces/acl_interfaces.py +++ /dev/null @@ -1,405 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_acl_interfaces class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to it's desired end-state is -created -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.six import iteritems -from ansible.module_utils.network.ios.utils.utils import remove_duplicate_interface, normalize_interface - - -class Acl_Interfaces(ConfigBase): - """ - The ios_acl_interfaces class - """ - - gather_subset = [ - '!all', - '!min', - ] - - gather_network_resources = [ - 'acl_interfaces', - ] - - def __init__(self, module): - super(Acl_Interfaces, self).__init__(module) - - def get_acl_interfaces_facts(self, data=None): - """ Get the 'facts' (the current configuration) - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources, data=data) - acl_interfaces_facts = facts['ansible_network_resources'].get('acl_interfaces') - if not acl_interfaces_facts: - return [] - - return acl_interfaces_facts - - def execute_module(self): - """ Execute the module - :rtype: A dictionary - :returns: The result from moduel execution - """ - result = {'changed': False} - commands = list() - warnings = list() - - if self.state in self.ACTION_STATES: - existing_acl_interfaces_facts = self.get_acl_interfaces_facts() - else: - existing_acl_interfaces_facts = [] - - if self.state in self.ACTION_STATES or self.state == 'rendered': - commands.extend(self.set_config(existing_acl_interfaces_facts)) - - if commands and self.state in self.ACTION_STATES: - if not self._module.check_mode: - self._connection.edit_config(commands) - result['changed'] = True - - if self.state in self.ACTION_STATES: - result['commands'] = commands - - if self.state in self.ACTION_STATES or self.state == 'gathered': - changed_acl_interfaces_facts = self.get_acl_interfaces_facts() - elif self.state == 'rendered': - result['rendered'] = commands - elif self.state == 'parsed': - running_config = self._module.params['running_config'] - if not running_config: - self._module.fail_json( - msg="value of running_config parameter must not be empty for state parsed" - ) - result['parsed'] = self.get_acl_interfaces_facts(data=running_config) - else: - changed_acl_interfaces_facts = [] - - if self.state in self.ACTION_STATES: - result['before'] = existing_acl_interfaces_facts - if result['changed']: - result['after'] = changed_acl_interfaces_facts - elif self.state == 'gathered': - result['gathered'] = changed_acl_interfaces_facts - - result['warnings'] = warnings - - return result - - def set_config(self, existing_acl_interfaces_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - want = self._module.params['config'] - if want: - for item in want: - item['name'] = normalize_interface(item['name']) - - have = existing_acl_interfaces_facts - resp = self.set_state(want, have) - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - commands = [] - - state = self._module.params['state'] - if state in ('overridden', 'merged', 'replaced', 'rendered') and not want: - self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(state)) - - if state == 'overridden': - commands = self._state_overridden(want, have) - elif state == 'deleted': - commands = self._state_deleted(want, have) - elif state == 'merged' or state == 'rendered': - commands = self._state_merged(want, have) - elif state == 'replaced': - commands = self._state_replaced(want, have) - - return commands - - def _state_replaced(self, want, have): - """ The command generator when state is replaced - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - commands = [] - - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - continue - commands.extend(self._clear_config(interface, each, 'replaced')) - commands.extend(self._set_config(interface, each)) - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_overridden(self, want, have): - """ The command generator when state is overridden - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - for each in have: - for interface in want: - if each['name'] == interface['name']: - break - else: - # We didn't find a matching desired state, which means we can - # pretend we recieved an empty desired state. - interface = dict(name=each['name']) - commands.extend(self._clear_config(interface, each)) - continue - commands.extend(self._clear_config(interface, each, 'overridden')) - commands.extend(self._set_config(interface, each)) - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_merged(self, want, have): - """ The command generator when state is merged - :param want: the additive configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - # configuring non-existing interface - commands.extend(self._set_config(interface, dict())) - continue - commands.extend(self._set_config(interface, each)) - - return commands - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - :param want: the objects from which the configuration should be removed - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - - if want: - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - continue - commands.extend(self._clear_config(interface, each)) - else: - for each in have: - commands.extend(self._clear_config(dict(), each)) - - return commands - - def dict_to_set(self, input_dict, test_set, final_set, count=0): - # recursive function to convert input dict to set for comparision - test_dict = dict() - if isinstance(input_dict, dict): - input_dict_len = len(input_dict) - for k, v in sorted(iteritems(input_dict)): - count += 1 - if isinstance(v, list): - for each in v: - if isinstance(each, dict): - input_dict_len = len(each) - if [True for i in each.values() if type(i) == list]: - self.dict_to_set(each, set(), final_set, count) - else: - self.dict_to_set(each, test_set, final_set, 0) - else: - if v is not None: - test_dict.update({k: v}) - if tuple(iteritems(test_dict)) not in test_set and count == input_dict_len: - test_set.add(tuple(iteritems(test_dict))) - count = 0 - if count == input_dict_len + 1: - test_set.update(tuple(iteritems(test_dict))) - final_set.add(tuple(test_set)) - - def _set_config(self, want, have): - """ Function that sets the acls config based on the want and have config - :param want: want config - :param have: have config - :param acl_want: want acl config - :param afi: acl afi type - :rtype: A list - :returns: the commands generated based on input want/have params - """ - commands = [] - - want_set = set() - have_set = set() - self.dict_to_set(want, set(), want_set) - self.dict_to_set(have, set(), have_set) - - for w in want_set: - want_afi = dict(w).get('afi') - if have_set: - def common_diff_config_code(diff_list, cmd, commands): - for each in diff_list: - try: - temp = dict(each) - temp_cmd = cmd + ' {0} {1}'.format(temp['name'], temp['direction']) - if temp_cmd not in commands: - commands.append(temp_cmd) - except ValueError: - continue - for h in have_set: - have_afi = dict(h).get('afi') - if have_afi == want_afi: - if want_afi == 'ipv4': - diff = set(w) - set(h) - if diff: - cmd = 'ip access-group' - common_diff_config_code(diff, cmd, commands) - if want_afi == 'ipv6': - diff = set(w) - set(h) - if diff: - cmd = 'ipv6 traffic-filter' - common_diff_config_code(diff, cmd, commands) - break - else: - if want_afi == 'ipv4': - diff = set(w) - set(h) - if diff: - cmd = 'ip access-group' - common_diff_config_code(diff, cmd, commands) - if want_afi == 'ipv6': - diff = set(w) - set(h) - if diff: - cmd = 'ipv6 traffic-filter' - common_diff_config_code(diff, cmd, commands) - else: - def common_want_config_code(want, cmd, commands): - for each in want: - if each[0] == 'afi': - continue - temp = dict(each) - temp_cmd = cmd + ' {0} {1}'.format(temp['name'], temp['direction']) - commands.append(temp_cmd) - if want_afi == 'ipv4': - cmd = 'ip access-group' - common_want_config_code(w, cmd, commands) - if want_afi == 'ipv6': - cmd = 'ipv6 traffic-filter' - common_want_config_code(w, cmd, commands) - commands.sort() - if commands: - interface = want.get('name') - commands.insert(0, 'interface {0}'.format(interface)) - - return commands - - def _clear_config(self, want, have, state=''): - """ Function that deletes the acl config based on the want and have config - :param acl: acl config - :param config: config - :rtype: A list - :returns: the commands generated based on input acl/config params - """ - commands = [] - - if want.get('name'): - interface = 'interface ' + want['name'] - else: - interface = 'interface ' + have['name'] - - w_access_group = want.get('access_groups') - temp_want_afi = [] - temp_want_acl_name = [] - if w_access_group: - # get the user input afi and acls - for each in w_access_group: - want_afi = each.get('afi') - want_acls = each.get('acls') - if want_afi: - temp_want_afi.append(want_afi) - if want_acls: - for each in want_acls: - temp_want_acl_name.append(each.get('name')) - - h_access_group = have.get('access_groups') - if h_access_group: - for access_grp in h_access_group: - for acl in access_grp.get('acls'): - have_afi = access_grp.get('afi') - acl_name = acl.get('name') - acl_direction = acl.get('direction') - if temp_want_afi and state not in ['replaced', 'overridden']: - # if user want to delete acls based on afi - if 'ipv4' in temp_want_afi and have_afi == 'ipv4': - if acl_name in temp_want_acl_name: - continue - cmd = 'no ip access-group' - cmd += ' {0} {1}'.format(acl_name, acl_direction) - commands.append(cmd) - if 'ipv6' in temp_want_afi and have_afi == 'ipv6': - if acl_name in temp_want_acl_name: - continue - cmd = 'no ipv6 traffic-filter' - cmd += ' {0} {1}'.format(acl_name, acl_direction) - commands.append(cmd) - else: - # if user want to delete acls based on interface - if access_grp.get('afi') == 'ipv4': - if acl_name in temp_want_acl_name: - continue - cmd = 'no ip access-group' - cmd += ' {0} {1}'.format(acl_name, acl_direction) - commands.append(cmd) - elif access_grp.get('afi') == 'ipv6': - if acl_name in temp_want_acl_name: - continue - cmd = 'no ipv6 traffic-filter' - cmd += ' {0} {1}'.format(acl_name, acl_direction) - commands.append(cmd) - if commands: - # inserting the interface at first - commands.insert(0, interface) - - return commands diff --git a/lib/ansible/module_utils/network/ios/config/acls/acls.py b/lib/ansible/module_utils/network/ios/config/acls/acls.py deleted file mode 100644 index 2a3f3f244b8..00000000000 --- a/lib/ansible/module_utils/network/ios/config/acls/acls.py +++ /dev/null @@ -1,717 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_acls class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to it's desired end-state is -created -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -import copy -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.six import iteritems -from ansible.module_utils.network.common.utils import remove_empties -from ansible.module_utils.network.ios.utils.utils import new_dict_to_set - - -class Acls(ConfigBase): - """ - The ios_acls class - """ - - gather_subset = [ - '!all', - '!min', - ] - - gather_network_resources = [ - 'acls', - ] - - def __init__(self, module): - super(Acls, self).__init__(module) - - def get_acl_facts(self, data=None): - """ Get the 'facts' (the current configuration) - - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources, data=data) - acl_facts = facts['ansible_network_resources'].get('acls') - if not acl_facts: - return [] - - return acl_facts - - def execute_module(self): - """ Execute the module - - :rtype: A dictionary - :returns: The result from moduel execution - """ - result = {'changed': False} - commands = list() - warnings = list() - - if self.state in self.ACTION_STATES: - existing_acl_facts = self.get_acl_facts() - else: - existing_acl_facts = [] - - if self.state in self.ACTION_STATES or self.state == 'rendered': - commands.extend(self.set_config(existing_acl_facts)) - - if commands and self.state in self.ACTION_STATES: - if not self._module.check_mode: - self._connection.edit_config(commands) - result['changed'] = True - - if self.state in self.ACTION_STATES: - result['commands'] = commands - - if self.state in self.ACTION_STATES or self.state == 'gathered': - changed_acl_facts = self.get_acl_facts() - elif self.state == 'rendered': - result['rendered'] = commands - elif self.state == 'parsed': - running_config = self._module.params['running_config'] - if not running_config: - self._module.fail_json(msg="value of running_config parameter must not be empty for state parsed") - result['parsed'] = self.get_acl_facts(data=running_config) - else: - changed_acl_facts = [] - - if self.state in self.ACTION_STATES: - result['before'] = existing_acl_facts - if result['changed']: - result['after'] = changed_acl_facts - elif self.state == 'gathered': - result['gathered'] = changed_acl_facts - - result['warnings'] = warnings - - return result - - def set_config(self, existing_acl_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - want = self._module.params['config'] - have = existing_acl_facts - resp = self.set_state(want, have) - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - commands = [] - - state = self._module.params['state'] - if state in ('overridden', 'merged', 'replaced', 'rendered') and not want: - self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(state)) - - if state == 'overridden': - commands = self._state_overridden(want, have) - elif state == 'deleted': - commands = self._state_deleted(want, have) - elif state == 'merged' or state == 'rendered': - commands = self._state_merged(want, have) - elif state == 'replaced': - commands = self._state_replaced(want, have) - - return commands - - def _state_replaced(self, want, have): - """ The command generator when state is replaced - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - commands = [] - - for config_want in want: - for acls_want in config_want.get('acls'): - for ace_want in acls_want.get('aces'): - check = False - for config_have in have: - for acls_have in config_have.get('acls'): - for ace_have in acls_have.get('aces'): - if acls_want.get('name') == acls_have.get('name'): - ace_want = remove_empties(ace_want) - acls_want = remove_empties(acls_want) - cmd, change = self._set_config(ace_want, - ace_have, - acls_want, - config_want['afi']) - if cmd: - for temp_acls_have in config_have.get('acls'): - for temp_ace_have in temp_acls_have.get('aces'): - if acls_want.get('name') == temp_acls_have.get('name'): - commands.extend( - self._clear_config(temp_acls_have, - config_have, - temp_ace_have.get('sequence'))) - commands.extend(cmd) - check = True - if check: - break - if check: - break - if not check: - # For configuring any non-existing want config - ace_want = remove_empties(ace_want) - cmd, change = self._set_config(ace_want, - {}, - acls_want, - config_want['afi']) - commands.extend(cmd) - # Split and arrange the config commands - commands = self.split_set_cmd(commands) - - return commands - - def _state_overridden(self, want, have): - """ The command generator when state is overridden - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - # Creating a copy of want, so that want dict is intact even after delete operation - # performed during override want n have comparison - temp_want = copy.deepcopy(want) - - for config_have in have: - for acls_have in config_have.get('acls'): - for ace_have in acls_have.get('aces'): - check = False - for config_want in temp_want: - count = 0 - for acls_want in config_want.get('acls'): - for ace_want in acls_want.get('aces'): - if acls_want.get('name') == acls_have.get('name'): - ace_want = remove_empties(ace_want) - acls_want = remove_empties(acls_want) - cmd, change = self._set_config(ace_want, ace_have, acls_want, config_want['afi']) - if cmd: - for temp_acls_have in config_have.get('acls'): - for temp_ace_have in temp_acls_have.get('aces'): - if acls_want.get('name') == temp_acls_have.get('name'): - commands.extend( - self._clear_config(temp_acls_have, - config_have, - temp_ace_have.get('sequence'))) - commands.extend(cmd) - check = True - if check: - del config_want.get('acls')[count] - else: - count += 1 - if check: - break - if check: - break - if not check: - # Delete the config not present in want config - commands.extend(self._clear_config(acls_have, config_have)) - - # For configuring any non-existing want config - for config_want in temp_want: - for acls_want in config_want.get('acls'): - for ace_want in acls_want.get('aces'): - ace_want = remove_empties(ace_want) - cmd, change = self._set_config(ace_want, - {}, - acls_want, - config_want['afi']) - commands.extend(cmd) - - # Split and arrange the config commands - commands = self.split_set_cmd(commands) - # Arranging the cmds suct that all delete cmds are fired before all set cmds - negate_commands = [each for each in commands if 'no' in each and 'access-list' in each] - negate_commands.extend([each for each in commands if each not in negate_commands]) - commands = negate_commands - - return commands - - def _state_merged(self, want, have): - """ The command generator when state is merged - - :param want: the additive configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - - for config_want in want: - for acls_want in config_want.get('acls'): - for ace_want in acls_want.get('aces'): - check = False - for config_have in have: - for acls_have in config_have.get('acls'): - for ace_have in acls_have.get('aces'): - if acls_want.get('name') == acls_have.get('name') and \ - ace_want.get('sequence') == ace_have.get('sequence'): - ace_want = remove_empties(ace_want) - cmd, change = self._set_config(ace_want, - ace_have, - acls_want, - config_want['afi']) - # clear config will be fired only when there's command wrt to config - if config_want.get('afi') == 'ipv4' and change: - # for ipv4 only inplace update cannot be done, so deleting the sequence ace - # and then updating the want ace changes - commands.extend(self._clear_config(acls_want, - config_want, - ace_want.get('sequence'))) - commands.extend(cmd) - check = True - elif acls_want.get('name') == acls_have.get('name'): - ace_want = remove_empties(ace_want) - cmd, check = self.common_condition_check(ace_want, - ace_have, - acls_want, - config_want, - check, - acls_have) - if acls_have.get('acl_type') == 'standard': - check = True - commands.extend(cmd) - if check: - break - if check: - break - if not check: - # For configuring any non-existing want config - ace_want = remove_empties(ace_want) - cmd, change = self._set_config(ace_want, - {}, - acls_want, - config_want['afi']) - commands.extend(cmd) - # Split and arrange the config commands - commands = self.split_set_cmd(commands) - - return commands - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - - :param want: the objects from which the configuration should be removed - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - if want: - for config_want in want: - if config_want.get('acls'): - for acls_want in config_want.get('acls'): - if acls_want.get('aces'): - for ace_want in acls_want.get('aces'): - for config_have in have: - for acls_have in config_have.get('acls'): - if acls_want.get('name') == acls_have.get('name'): - if ace_want.get('sequence'): - commands.extend(self._clear_config(acls_want, - config_want, - ace_want.get('sequence'))) - else: - commands.extend(self._clear_config(acls_want, - config_want)) - else: - for config_have in have: - for acls_have in config_have.get('acls'): - if acls_want.get('name') == acls_have.get('name'): - commands.extend(self._clear_config(acls_want, - config_want)) - else: - afi_want = config_want.get('afi') - for config_have in have: - if config_have.get('afi') == afi_want: - for acls_have in config_have.get('acls'): - commands.extend(self._clear_config(acls_have, config_want)) - # Split and arrange the config commands - commands = self.split_set_cmd(commands) - else: - for config_have in have: - for acls_have in config_have.get('acls'): - commands.extend(self._clear_config(acls_have, config_have)) - - return commands - - def common_condition_check(self, want, have, acls_want, config_want, check, state='', acls_have=None): - """ The command formatter from the generated command - :param want: want config - :param have: have config - :param acls_want: acls want config - :param config_want: want config list - :param check: for same acls in want and have config, check=True - :param state: operation state - :rtype: A list - :returns: commands generated from want n have config diff - """ - commands = [] - - if want.get('source') and want.get('destination') and have.get('source') and have.get('destination'): - if want.get('destination') and have.get('destination') or \ - want.get('source').get('address') and have.get('source'): - if want.get('destination').get('address') == \ - have.get('destination').get('address') and \ - want.get('source').get('address') == \ - have.get('source').get('address'): - cmd, change = self._set_config(want, - have, - acls_want, - config_want['afi']) - commands.extend(cmd) - check = True - if commands: - if state == 'replaced' or state == 'overridden': - commands.extend(self._clear_config(acls_want, config_want)) - elif want.get('destination').get('any') == \ - have.get('destination').get('any') and \ - want.get('source').get('address') == \ - have.get('source').get('address') and \ - want.get('destination').get('any'): - cmd, change = self._set_config(want, - have, - acls_want, - config_want['afi']) - commands.extend(cmd) - check = True - if commands: - if state == 'replaced' or state == 'overridden': - commands.extend(self._clear_config(acls_want, config_want)) - elif want.get('destination').get('address') == \ - have.get('destination').get('address') and \ - want.get('source').get('any') == have.get('source').get('any') and \ - want.get('source').get('any'): - cmd, change = self._set_config(want, - have, - acls_want, - config_want['afi']) - commands.extend(cmd) - check = True - if commands: - if state == 'replaced' or state == 'overridden': - commands.extend(self._clear_config(acls_want, config_want)) - elif want.get('destination').get('any') == \ - have.get('destination').get('any') and \ - want.get('source').get('any') == have.get('source').get('any') and \ - want.get('destination').get('any'): - cmd, change = self._set_config(want, - have, - acls_want, - config_want['afi']) - commands.extend(cmd) - check = True - if commands: - if state == 'replaced' or state == 'overridden': - commands.extend(self._clear_config(acls_want, config_want)) - elif acls_have and acls_have.get('acl_type') == 'standard': - check = True - if want.get('source') == have.get('source'): - cmd, change = self._set_config(want, - have, - acls_want, - config_want['afi']) - commands.extend(cmd) - - return commands, check - - def split_set_cmd(self, cmds): - """ The command formatter from the generated command - :param cmds: generated command - :rtype: A list - :returns: the formatted commands which is compliant and - actually fired on the device - """ - command = [] - - def common_code(access_grant, cmd, command): - cmd = cmd.split(access_grant) - access_list = cmd[0].strip(' ') - if access_list not in command: - command.append(access_list) - command_items = len(command) - # get the last index of the list and push the trimmed cmd at the end of list - index = command.index(access_list) + (command_items - command.index(access_list)) - cmd = access_grant + cmd[1] - command.insert(index + 1, cmd) - - def sequence_common_code(sequence_index, each_list, command): - # Command to split - def join_list_to_str(temp_list, cmd=''): - for item in temp_list: - cmd += item - cmd += ' ' - return cmd - - temp_list = each_list[:sequence_index] - cmd = join_list_to_str(temp_list).rstrip(' ') - if cmd not in command: - command.append(cmd) - temp_list = each_list[sequence_index:] - cmd = join_list_to_str(temp_list).rstrip(' ') - command.append(cmd) - - def grant_common_code(cmd_list, grant_type, command): - index = cmd_list.index(grant_type) - if 'extended' in each_list: - if cmd_list.index('extended') == (index - 2): - common_code(grant_type, each, command) - else: - sequence_common_code((index - 1), each_list, command) - elif 'standard' in each_list: - if cmd_list.index('standard') == (index - 2): - common_code(grant_type, each, command) - else: - sequence_common_code((index - 1), each_list, command) - elif 'ipv6' in each_list: - if 'sequence' in each_list: - sequence_index = each_list.index('sequence') - sequence_common_code(sequence_index, each_list, command) - else: - common_code(grant_type, each, command) - return command - - for each in cmds: - each_list = each.split(' ') - if 'no' in each: - if each_list.index('no') == 0: - command.append(each) - else: - common_code('no', each, command) - if 'deny' in each: - grant_common_code(each_list, 'deny', command) - if 'permit' in each: - grant_common_code(each_list, 'permit', command) - - return command - - def source_dest_config(self, config, cmd, protocol_option): - """ Function to populate source/destination address and port protocol options - :param config: want and have diff config - :param cmd: source/destination command - :param protocol_option: source/destination protocol option - :rtype: A list - :returns: the commands generated based on input source/destination params - """ - if 'ipv6' in cmd: - address = config.get('address') - host = config.get('host') - if (address and '::' not in address) or (host and '::' not in host): - self._module.fail_json(msg='Incorrect IPV6 address!') - else: - address = config.get('address') - wildcard = config.get('wildcard_bits') - host = config.get('host') - any = config.get('any') - if 'standard' in cmd and address and not wildcard: - cmd = cmd + ' {0}'.format(address) - elif address and wildcard: - cmd = cmd + ' {0} {1}'.format(address, wildcard) - elif host: - cmd = cmd + ' host {0}'.format(host) - if any: - cmd = cmd + ' {0}'.format('any') - port_protocol = config.get('port_protocol') - if port_protocol and (protocol_option.get('tcp') or protocol_option.get('udp')): - cmd = cmd + ' {0} {1}'.format(list(port_protocol)[0], list(port_protocol.values())[0]) - elif port_protocol and not (protocol_option.get('tcp') or protocol_option.get('udp')): - self._module.fail_json(msg='Port Protocol option is valid only with TCP/UDP Protocol option!') - - return cmd - - def _set_config(self, want, have, acl_want, afi): - """ Function that sets the acls config based on the want and have config - :param want: want config - :param have: have config - :param acl_want: want acls config - :param afi: acls afi type - :rtype: A list - :returns: the commands generated based on input want/have params - """ - commands = [] - change = False - want_set = set() - have_set = set() - # Convert the want and have dict to its respective set for taking the set diff - new_dict_to_set(want, [], want_set) - new_dict_to_set(have, [], have_set) - diff = want_set - have_set - - # Populate the config only when there's a diff b/w want and have config - if diff: - name = acl_want.get('name') - if afi == 'ipv4': - try: - name = int(name) - # If name is numbered acls - if name <= 99: - cmd = 'ip access-list standard {0}'.format(name) - elif name >= 100: - cmd = 'ip access-list extended {0}'.format(name) - except ValueError: - # If name is named acls - acl_type = acl_want.get('acl_type') - if acl_type: - cmd = 'ip access-list {0} {1}'.format(acl_type, name) - else: - self._module.fail_json(msg='ACL type value is required for Named ACL!') - - elif afi == 'ipv6': - cmd = 'ipv6 access-list {0}'.format(name) - - # Get all of aces option values from diff dict - sequence = want.get('sequence') - grant = want.get('grant') - source = want.get('source') - destination = want.get('destination') - po = want.get('protocol_options') - protocol = want.get('protocol') - dscp = want.get('dscp') - fragments = want.get('fragments') - log = want.get('log') - log_input = want.get('log_input') - option = want.get('option') - precedence = want.get('precedence') - time_range = want.get('time_range') - tos = want.get('tos') - ttl = want.get('ttl') - - if sequence: - if afi == 'ipv6': - cmd = cmd + ' sequence {0}'.format(sequence) - else: - cmd = cmd + ' {0}'.format(sequence) - if grant: - cmd = cmd + ' {0}'.format(grant) - if po and isinstance(po, dict): - po_key = list(po)[0] - if protocol and protocol != po_key: - self._module.fail_json(msg='Protocol value cannot be different from Protocol option protocol value!') - cmd = cmd + ' {0}'.format(po_key) - if po.get('icmp'): - po_val = po.get('icmp') - elif po.get('igmp'): - po_val = po.get('igmp') - elif po.get('tcp'): - po_val = po.get('tcp') - elif protocol: - cmd = cmd + ' {0}'.format(protocol) - if source: - cmd = self.source_dest_config(source, cmd, po) - if destination: - cmd = self.source_dest_config(destination, cmd, po) - if po: - cmd = cmd + ' {0}'.format(list(po_val)[0]) - if dscp: - cmd = cmd + ' dscp {0}'.format(dscp) - if fragments: - cmd = cmd + ' fragments {0}'.format(fragments) - if log: - cmd = cmd + ' log {0}'.format(log) - if log_input: - cmd = cmd + ' log-input {0}'.format(log_input) - if option: - cmd = cmd + ' option {0}'.format(list(option)[0]) - if precedence: - cmd = cmd + ' precedence {0}'.format(precedence) - if time_range: - cmd = cmd + ' time-range {0}'.format(time_range) - if tos: - for k, v in iteritems(tos): - if k == 'service_value': - cmd = cmd + ' tos {0}'.format(v) - else: - cmd = cmd + ' tos {0}'.format(v) - if ttl: - for k, v in iteritems(ttl): - if k == 'range' and v: - start = v.get('start') - end = v.get('start') - cmd = cmd + ' ttl {0} {1}'.format(start, end) - elif v: - cmd = cmd + ' ttl {0} {1}'.format(k, v) - - commands.append(cmd) - if commands: - change = True - - return commands, change - - def _clear_config(self, acls, config, sequence=''): - """ Function that deletes the acls config based on the want and have config - :param acls: acls config - :param config: config - :rtype: A list - :returns: the commands generated based on input acls/config params - """ - commands = [] - afi = config.get('afi') - name = acls.get('name') - if afi == 'ipv4' and name: - try: - name = int(name) - if name <= 99 and not sequence: - cmd = 'no ip access-list standard {0}'.format(name) - elif name >= 100 and not sequence: - cmd = 'no ip access-list extended {0}'.format(name) - elif sequence: - if name <= 99: - cmd = 'ip access-list standard {0} '.format(name) - elif name >= 100: - cmd = 'ip access-list extended {0} '.format(name) - cmd += 'no {0}'.format(sequence) - except ValueError: - acl_type = acls.get('acl_type') - if acl_type == 'extended' and not sequence: - cmd = 'no ip access-list extended {0}'.format(name) - elif acl_type == 'standard' and not sequence: - cmd = 'no ip access-list standard {0}'.format(name) - elif sequence: - if acl_type == 'extended': - cmd = 'ip access-list extended {0} '.format(name) - elif acl_type == 'standard': - cmd = 'ip access-list standard {0}'.format(name) - cmd += 'no {0}'.format(sequence) - else: - self._module.fail_json(msg="ACL type value is required for Named ACL!") - elif afi == 'ipv6' and name: - if sequence: - cmd = 'no sequence {0}'.format(sequence) - else: - cmd = 'no ipv6 access-list {0}'.format(name) - commands.append(cmd) - - return commands diff --git a/lib/ansible/module_utils/network/ios/config/interfaces/interfaces.py b/lib/ansible/module_utils/network/ios/config/interfaces/interfaces.py deleted file mode 100644 index bcf817f4d89..00000000000 --- a/lib/ansible/module_utils/network/ios/config/interfaces/interfaces.py +++ /dev/null @@ -1,295 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_interfaces class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to it's desired end-state is -created -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.network.ios.utils.utils import get_interface_type, dict_to_set -from ansible.module_utils.network.ios.utils.utils import remove_command_from_config_list, add_command_to_config_list -from ansible.module_utils.network.ios.utils.utils import filter_dict_having_none_value, remove_duplicate_interface - - -class Interfaces(ConfigBase): - """ - The ios_interfaces class - """ - - gather_subset = [ - '!all', - '!min', - ] - - gather_network_resources = [ - 'interfaces', - ] - - params = ('description', 'mtu', 'speed', 'duplex') - - def __init__(self, module): - super(Interfaces, self).__init__(module) - - def get_interfaces_facts(self): - """ Get the 'facts' (the current configuration) - - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) - interfaces_facts = facts['ansible_network_resources'].get('interfaces') - if not interfaces_facts: - return [] - - return interfaces_facts - - def execute_module(self): - """ Execute the module - - :rtype: A dictionary - :returns: The result from moduel execution - """ - result = {'changed': False} - commands = list() - warnings = list() - - existing_interfaces_facts = self.get_interfaces_facts() - commands.extend(self.set_config(existing_interfaces_facts)) - - if commands: - if not self._module.check_mode: - self._connection.edit_config(commands) - result['changed'] = True - result['commands'] = commands - - changed_interfaces_facts = self.get_interfaces_facts() - - result['before'] = existing_interfaces_facts - if result['changed']: - result['after'] = changed_interfaces_facts - result['warnings'] = warnings - - return result - - def set_config(self, existing_interfaces_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - want = self._module.params['config'] - have = existing_interfaces_facts - resp = self.set_state(want, have) - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - commands = [] - - state = self._module.params['state'] - if state in ('overridden', 'merged', 'replaced') and not want: - self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(state)) - - if state == 'overridden': - commands = self._state_overridden(want, have) - elif state == 'deleted': - commands = self._state_deleted(want, have) - elif state == 'merged': - commands = self._state_merged(want, have) - elif state == 'replaced': - commands = self._state_replaced(want, have) - - return commands - - def _state_replaced(self, want, have): - """ The command generator when state is replaced - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :param interface_type: interface type - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - commands = [] - - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - elif interface['name'] in each['name']: - break - else: - # configuring non-existing interface - commands.extend(self._set_config(interface, dict())) - continue - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each)) - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_overridden(self, want, have): - """ The command generator when state is overridden - - :param want: the desired configuration as a dictionary - :param obj_in_have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - for each in have: - for interface in want: - count = 0 - if each['name'] == interface['name']: - break - elif interface['name'] in each['name']: - break - count += 1 - else: - # We didn't find a matching desired state, which means we can - # pretend we received an empty desired state. - interface = dict(name=each['name']) - commands.extend(self._clear_config(interface, each)) - continue - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each)) - # as the pre-existing interface are now configured by - # above set_config call, deleting the respective - # interface entry from the want list - del want[count] - - # Iterating through want list which now only have new interfaces to be - # configured - for each in want: - commands.extend(self._set_config(each, dict())) - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_merged(self, want, have): - """ The command generator when state is merged - - :param want: the additive configuration as a dictionary - :param obj_in_have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - # configuring non-existing interface - commands.extend(self._set_config(interface, dict())) - continue - commands.extend(self._set_config(interface, each)) - - return commands - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - - :param want: the objects from which the configuration should be removed - :param obj_in_have: the current configuration as a dictionary - :param interface_type: interface type - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - - if want: - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - continue - interface = dict(name=interface['name']) - commands.extend(self._clear_config(interface, each)) - else: - for each in have: - want = dict() - commands.extend(self._clear_config(want, each)) - - return commands - - def _set_config(self, want, have): - # Set the interface config based on the want and have config - commands = [] - interface = 'interface ' + want['name'] - - # Get the diff b/w want and have - want_dict = dict_to_set(want) - have_dict = dict_to_set(have) - diff = want_dict - have_dict - - if diff: - diff = dict(diff) - for item in self.params: - if diff.get(item): - cmd = item + ' ' + str(want.get(item)) - add_command_to_config_list(interface, cmd, commands) - if diff.get('enabled'): - add_command_to_config_list(interface, 'no shutdown', commands) - elif diff.get('enabled') is False: - add_command_to_config_list(interface, 'shutdown', commands) - - return commands - - def _clear_config(self, want, have): - # Delete the interface config based on the want and have config - commands = [] - - if want.get('name'): - interface_type = get_interface_type(want['name']) - interface = 'interface ' + want['name'] - else: - interface_type = get_interface_type(have['name']) - interface = 'interface ' + have['name'] - - if have.get('description') and want.get('description') != have.get('description'): - remove_command_from_config_list(interface, 'description', commands) - if not have.get('enabled') and want.get('enabled') != have.get('enabled'): - # if enable is False set enable as True which is the default behavior - remove_command_from_config_list(interface, 'shutdown', commands) - - if interface_type.lower() == 'gigabitethernet': - if have.get('speed') and have.get('speed') != 'auto' and want.get('speed') != have.get('speed'): - remove_command_from_config_list(interface, 'speed', commands) - if have.get('duplex') and have.get('duplex') != 'auto' and want.get('duplex') != have.get('duplex'): - remove_command_from_config_list(interface, 'duplex', commands) - if have.get('mtu') and want.get('mtu') != have.get('mtu'): - remove_command_from_config_list(interface, 'mtu', commands) - - return commands diff --git a/lib/ansible/module_utils/network/ios/config/l2_interfaces/l2_interfaces.py b/lib/ansible/module_utils/network/ios/config/l2_interfaces/l2_interfaces.py deleted file mode 100644 index 1ebfcbda587..00000000000 --- a/lib/ansible/module_utils/network/ios/config/l2_interfaces/l2_interfaces.py +++ /dev/null @@ -1,336 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_l2_interfaces class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to it's desired end-state is -created -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.network.ios.utils.utils import dict_to_set -from ansible.module_utils.network.ios.utils.utils import remove_command_from_config_list, add_command_to_config_list -from ansible.module_utils.network.ios.utils.utils import filter_dict_having_none_value, remove_duplicate_interface - - -class L2_Interfaces(ConfigBase): - """ - The ios_l2_interfaces class - """ - - gather_subset = [ - '!all', - '!min', - ] - - gather_network_resources = [ - 'l2_interfaces', - ] - - access_cmds = {'access_vlan': 'switchport access vlan'} - voice_cmds = {'voice_vlan': 'switchport voice vlan'} - trunk_cmds = {'encapsulation': 'switchport trunk encapsulation', 'pruning_vlans': 'switchport trunk pruning vlan', - 'native_vlan': 'switchport trunk native vlan', 'allowed_vlans': 'switchport trunk allowed vlan'} - - def get_interfaces_facts(self): - """ Get the 'facts' (the current configuration) - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) - interfaces_facts = facts['ansible_network_resources'].get('l2_interfaces') - if not interfaces_facts: - return [] - - return interfaces_facts - - def execute_module(self): - """ Execute the module - :rtype: A dictionary - :returns: The result from moduel execution - """ - result = {'changed': False} - commands = [] - warnings = [] - existing_facts = self.get_interfaces_facts() - commands.extend(self.set_config(existing_facts)) - result['before'] = existing_facts - if commands: - if not self._module.check_mode: - self._connection.edit_config(commands) - result['changed'] = True - result['commands'] = commands - - interfaces_facts = self.get_interfaces_facts() - - if result['changed']: - result['after'] = interfaces_facts - result['warnings'] = warnings - return result - - def set_config(self, existing_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - - want = self._module.params['config'] - have = existing_facts - resp = self.set_state(want, have) - - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - commands = [] - - state = self._module.params['state'] - if state in ('overridden', 'merged', 'replaced') and not want: - self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(state)) - - if state == 'overridden': - commands = self._state_overridden(want, have, self._module) - elif state == 'deleted': - commands = self._state_deleted(want, have) - elif state == 'merged': - commands = self._state_merged(want, have, self._module) - elif state == 'replaced': - commands = self._state_replaced(want, have, self._module) - - return commands - - def _state_replaced(self, want, have, module): - """ The command generator when state is replaced - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :param interface_type: interface type - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - commands = [] - - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - continue - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each, module)) - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_overridden(self, want, have, module): - """ The command generator when state is overridden - :param want: the desired configuration as a dictionary - :param obj_in_have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - for each in have: - for interface in want: - if each['name'] == interface['name']: - break - else: - # We didn't find a matching desired state, which means we can - # pretend we received an empty desired state. - interface = dict(name=each['name']) - kwargs = {'want': interface, 'have': each} - commands.extend(self._clear_config(**kwargs)) - continue - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each, module)) - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_merged(self, want, have, module): - """ The command generator when state is merged - :param want: the additive configuration as a dictionary - :param obj_in_have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - continue - commands.extend(self._set_config(interface, each, module)) - - return commands - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - :param want: the objects from which the configuration should be removed - :param obj_in_have: the current configuration as a dictionary - :param interface_type: interface type - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - - if want: - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - continue - interface = dict(name=interface['name']) - commands.extend(self._clear_config(interface, each)) - else: - for each in have: - want = dict() - commands.extend(self._clear_config(want, each)) - - return commands - - def _check_for_correct_vlan_range(self, vlan, module): - # Function to check if the VLAN range passed is Valid - for each in vlan: - vlan_range = each.split('-') - if len(vlan_range) > 1: - if vlan_range[0] < vlan_range[1]: - return True - else: - module.fail_json(msg='Command rejected: Bad VLAN list - end of range not larger than the' - ' start of range!') - else: - return True - - def _set_config(self, want, have, module): - # Set the interface config based on the want and have config - commands = [] - interface = 'interface ' + want['name'] - - # Get the diff b/w want and have - want_dict = dict_to_set(want) - have_dict = dict_to_set(have) - want_trunk = dict(want_dict).get('trunk') - have_trunk = dict(have_dict).get('trunk') - if want_trunk and have_trunk: - diff = set(tuple(dict(want_dict).get('trunk'))) - set(tuple(dict(have_dict).get('trunk'))) - else: - diff = want_dict - have_dict - - if diff: - diff = dict(diff) - mode = diff.get('mode') - access = diff.get('access') - trunk = diff.get('trunk') - - if access: - cmd = 'switchport access vlan {0}'.format(access[0][1]) - add_command_to_config_list(interface, cmd, commands) - - if diff.get('voice'): - cmd = 'switchport voice vlan {0}'.format(diff.get('voice')[0][1]) - add_command_to_config_list(interface, cmd, commands) - - if want_trunk: - if trunk: - diff = dict(trunk) - if diff.get('encapsulation'): - cmd = self.trunk_cmds['encapsulation'] + ' {0}'.format(diff.get('encapsulation')) - add_command_to_config_list(interface, cmd, commands) - if diff.get('native_vlan'): - cmd = self.trunk_cmds['native_vlan'] + ' {0}'.format(diff.get('native_vlan')) - add_command_to_config_list(interface, cmd, commands) - allowed_vlans = diff.get('allowed_vlans') - pruning_vlans = diff.get('pruning_vlans') - - if allowed_vlans and self._check_for_correct_vlan_range(allowed_vlans, module): - allowed_vlans = ','.join(allowed_vlans) - cmd = self.trunk_cmds['allowed_vlans'] + ' {0}'.format(allowed_vlans) - add_command_to_config_list(interface, cmd, commands) - if pruning_vlans and self._check_for_correct_vlan_range(pruning_vlans, module): - pruning_vlans = ','.join(pruning_vlans) - cmd = self.trunk_cmds['pruning_vlans'] + ' {0}'.format(pruning_vlans) - add_command_to_config_list(interface, cmd, commands) - - if mode: - cmd = 'switchport mode {0}'.format(mode) - add_command_to_config_list(interface, cmd, commands) - - return commands - - def _clear_config(self, want, have): - # Delete the interface config based on the want and have config - commands = [] - if want.get('name'): - interface = 'interface ' + want['name'] - else: - interface = 'interface ' + have['name'] - - if have.get('mode') or want.get('mode'): - remove_command_from_config_list(interface, 'switchport mode', commands) - - if have.get('access') and want.get('access') is None: - remove_command_from_config_list(interface, L2_Interfaces.access_cmds['access_vlan'], commands) - elif have.get('access') and want.get('access'): - if have.get('access').get('vlan') != want.get('access').get('vlan'): - remove_command_from_config_list(interface, L2_Interfaces.access_cmds['access_vlan'], commands) - - if have.get('voice') and want.get('voice') is None: - remove_command_from_config_list(interface, L2_Interfaces.voice_cmds['voice_vlan'], commands) - elif have.get('voice') and want.get('voice'): - if have.get('voice').get('vlan') != want.get('voice').get('vlan'): - remove_command_from_config_list(interface, L2_Interfaces.voice_cmds['voice_vlan'], commands) - - if have.get('trunk') and want.get('trunk') is None: - # Check when no config is passed - if have.get('trunk').get('encapsulation'): - remove_command_from_config_list(interface, self.trunk_cmds['encapsulation'], commands) - if have.get('trunk').get('native_vlan'): - remove_command_from_config_list(interface, self.trunk_cmds['native_vlan'], commands) - if have.get('trunk').get('allowed_vlans'): - remove_command_from_config_list(interface, self.trunk_cmds['allowed_vlans'], commands) - if have.get('trunk').get('pruning_vlans'): - remove_command_from_config_list(interface, self.trunk_cmds['pruning_vlans'], commands) - elif have.get('trunk') and want.get('trunk'): - # Check when config is passed, also used in replaced and override state - if have.get('trunk').get('encapsulation')\ - and have.get('trunk').get('encapsulation') != want.get('trunk').get('encapsulation'): - remove_command_from_config_list(interface, self.trunk_cmds['encapsulation'], commands) - if have.get('trunk').get('native_vlan') \ - and have.get('trunk').get('native_vlan') != want.get('trunk').get('native_vlan'): - remove_command_from_config_list(interface, self.trunk_cmds['native_vlan'], commands) - if have.get('trunk').get('allowed_vlans') \ - and have.get('trunk').get('allowed_vlans') != want.get('trunk').get('allowed_vlans'): - remove_command_from_config_list(interface, self.trunk_cmds['allowed_vlans'], commands) - if have.get('trunk').get('pruning_vlans') \ - and have.get('trunk').get('pruning_vlans') != want.get('trunk').get('pruning_vlans'): - remove_command_from_config_list(interface, self.trunk_cmds['pruning_vlans'], commands) - - return commands diff --git a/lib/ansible/module_utils/network/ios/config/l3_interfaces/l3_interfaces.py b/lib/ansible/module_utils/network/ios/config/l3_interfaces/l3_interfaces.py deleted file mode 100644 index 221f276ab2c..00000000000 --- a/lib/ansible/module_utils/network/ios/config/l3_interfaces/l3_interfaces.py +++ /dev/null @@ -1,328 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_l3_interfaces class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to it's desired end-state is -created -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.network.ios.utils.utils import dict_to_set -from ansible.module_utils.network.ios.utils.utils import remove_command_from_config_list, add_command_to_config_list -from ansible.module_utils.network.ios.utils.utils import filter_dict_having_none_value, remove_duplicate_interface -from ansible.module_utils.network.ios.utils.utils import validate_n_expand_ipv4, validate_ipv6 - - -class L3_Interfaces(ConfigBase): - """ - The ios_l3_interfaces class - """ - - gather_subset = [ - '!all', - '!min', - ] - - gather_network_resources = [ - 'l3_interfaces' - ] - - def get_l3_interfaces_facts(self): - """ Get the 'facts' (the current configuration) - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) - l3_interfaces_facts = facts['ansible_network_resources'].get('l3_interfaces') - if not l3_interfaces_facts: - return [] - - return l3_interfaces_facts - - def execute_module(self): - """ Execute the module - :rtype: A dictionary - :returns: The result from module execution - """ - result = {'changed': False} - commands = list() - warnings = list() - - existing_l3_interfaces_facts = self.get_l3_interfaces_facts() - commands.extend(self.set_config(existing_l3_interfaces_facts)) - if commands: - if not self._module.check_mode: - self._connection.edit_config(commands) - result['changed'] = True - result['commands'] = commands - - changed_l3_interfaces_facts = self.get_l3_interfaces_facts() - - result['before'] = existing_l3_interfaces_facts - if result['changed']: - result['after'] = changed_l3_interfaces_facts - - result['warnings'] = warnings - return result - - def set_config(self, existing_l3_interfaces_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - want = self._module.params['config'] - have = existing_l3_interfaces_facts - resp = self.set_state(want, have) - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - state = self._module.params['state'] - if state in ('overridden', 'merged', 'replaced') and not want: - self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(state)) - - if state == 'overridden': - commands = self._state_overridden(want, have, self._module) - elif state == 'deleted': - commands = self._state_deleted(want, have) - elif state == 'merged': - commands = self._state_merged(want, have, self._module) - elif state == 'replaced': - commands = self._state_replaced(want, have, self._module) - - return commands - - def _state_replaced(self, want, have, module): - """ The command generator when state is replaced - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - if '.' in interface['name']: - commands.extend(self._set_config(interface, dict(), module)) - continue - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each, module)) - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_overridden(self, want, have, module): - """ The command generator when state is overridden - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - for each in have: - for interface in want: - if each['name'] == interface['name']: - break - else: - # We didn't find a matching desired state, which means we can - # pretend we received an empty desired state. - interface = dict(name=each['name']) - kwargs = {'want': interface, 'have': each} - commands.extend(self._clear_config(**kwargs)) - continue - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each, module)) - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_merged(self, want, have, module): - """ The command generator when state is merged - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - if '.' in interface['name']: - commands.extend(self._set_config(interface, dict(), module)) - continue - commands.extend(self._set_config(interface, each, module)) - - return commands - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - - if want: - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - elif interface['name'] in each['name']: - break - else: - continue - interface = dict(name=interface['name']) - commands.extend(self._clear_config(interface, each)) - else: - for each in have: - want = dict() - commands.extend(self._clear_config(want, each)) - - return commands - - def verify_diff_again(self, want, have): - """ - Verify the IPV4 difference again as sometimes due to - change in order of set, set difference may result into change, - when there's actually no difference between want and have - :param want: want_dict IPV4 - :param have: have_dict IPV4 - :return: diff - """ - diff = False - for each in want: - each_want = dict(each) - for every in have: - every_have = dict(every) - if each_want.get('address') != every_have.get('address') and \ - each_want.get('secondary') != every_have.get('secondary') and \ - len(each_want.keys()) == len(every_have.keys()): - diff = True - break - elif each_want.get('dhcp_client') != every_have.get('dhcp_client') and each_want.get( - 'dhcp_client') is not None: - diff = True - break - elif each_want.get('dhcp_hostname') != every_have.get('dhcp_hostname') and each_want.get( - 'dhcp_hostname') is not None: - diff = True - break - elif each_want.get('address') != every_have.get('address') and len(each_want.keys()) == len( - every_have.keys()): - diff = True - break - if diff: - break - - return diff - - def _set_config(self, want, have, module): - # Set the interface config based on the want and have config - commands = [] - interface = 'interface ' + want['name'] - - # To handle L3 IPV4 configuration - if want.get("ipv4"): - for each in want.get("ipv4"): - if each.get('address') != 'dhcp': - ip_addr_want = validate_n_expand_ipv4(module, each) - each['address'] = ip_addr_want - - # Convert the want and have dict to set - want_dict = dict_to_set(want) - have_dict = dict_to_set(have) - - # To handle L3 IPV4 configuration - if want.get('ipv4'): - # Get the diff b/w want and have IPV4 - if have.get('ipv4'): - ipv4 = tuple(set(dict(want_dict).get('ipv4')) - set(dict(have_dict).get('ipv4'))) - if ipv4: - ipv4 = ipv4 if self.verify_diff_again(dict(want_dict).get('ipv4'), dict(have_dict).get('ipv4')) else () - else: - diff = want_dict - have_dict - ipv4 = dict(diff).get('ipv4') - if ipv4: - for each in ipv4: - ipv4_dict = dict(each) - if ipv4_dict.get('address') != 'dhcp': - cmd = "ip address {0}".format(ipv4_dict['address']) - if ipv4_dict.get("secondary"): - cmd += " secondary" - elif ipv4_dict.get('address') == 'dhcp': - cmd = "ip address dhcp" - if ipv4_dict.get('dhcp_client') is not None and ipv4_dict.get('dhcp_hostname'): - cmd = "ip address dhcp client-id GigabitEthernet 0/{0} hostname {1}"\ - .format(ipv4_dict.get('dhcp_client'), ipv4_dict.get('dhcp_hostname')) - elif ipv4_dict.get('dhcp_client') and not ipv4_dict.get('dhcp_hostname'): - cmd = "ip address dhcp client-id GigabitEthernet 0/{0}"\ - .format(ipv4_dict.get('dhcp_client')) - elif not ipv4_dict.get('dhcp_client') and ipv4_dict.get('dhcp_hostname'): - cmd = "ip address dhcp hostname {0}".format(ipv4_dict.get('dhcp_client')) - - add_command_to_config_list(interface, cmd, commands) - - # To handle L3 IPV6 configuration - if want.get('ipv6'): - # Get the diff b/w want and have IPV6 - if have.get('ipv6'): - ipv6 = tuple(set(dict(want_dict).get('ipv6')) - set(dict(have_dict).get('ipv6'))) - else: - diff = want_dict - have_dict - ipv6 = dict(diff).get('ipv6') - if ipv6: - for each in ipv6: - ipv6_dict = dict(each) - validate_ipv6(ipv6_dict.get('address'), module) - cmd = "ipv6 address {0}".format(ipv6_dict.get('address')) - add_command_to_config_list(interface, cmd, commands) - - return commands - - def _clear_config(self, want, have): - # Delete the interface config based on the want and have config - count = 0 - commands = [] - if want.get('name'): - interface = 'interface ' + want['name'] - else: - interface = 'interface ' + have['name'] - - if have.get('ipv4') and want.get('ipv4'): - for each in have.get('ipv4'): - if each.get('secondary') and not (want.get('ipv4')[count].get('secondary')): - cmd = 'ipv4 address {0} secondary'.format(each.get('address')) - remove_command_from_config_list(interface, cmd, commands) - count += 1 - if have.get('ipv4') and not want.get('ipv4'): - remove_command_from_config_list(interface, 'ip address', commands) - if have.get('ipv6') and not want.get('ipv6'): - remove_command_from_config_list(interface, 'ipv6 address', commands) - return commands diff --git a/lib/ansible/module_utils/network/ios/config/lacp/lacp.py b/lib/ansible/module_utils/network/ios/config/lacp/lacp.py deleted file mode 100644 index 3f6bc0c0eb5..00000000000 --- a/lib/ansible/module_utils/network/ios/config/lacp/lacp.py +++ /dev/null @@ -1,189 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_lacp class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to it's desired end-state is -created -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.network.ios.utils.utils import dict_to_set - - -class Lacp(ConfigBase): - """ - The ios_lacp class - """ - - gather_subset = [ - '!all', - '!min', - ] - - gather_network_resources = [ - 'lacp', - ] - - def __init__(self, module): - super(Lacp, self).__init__(module) - - def get_lacp_facts(self): - """ Get the 'facts' (the current configuration) - - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) - lacp_facts = facts['ansible_network_resources'].get('lacp') - if not lacp_facts: - return [] - - return lacp_facts - - def execute_module(self): - """ Execute the module - - :rtype: A dictionary - :returns: The result from module execution - """ - result = {'changed': False} - commands = list() - warnings = list() - - existing_lacp_facts = self.get_lacp_facts() - commands.extend(self.set_config(existing_lacp_facts)) - if commands: - if not self._module.check_mode: - self._connection.edit_config(commands) - result['changed'] = True - result['commands'] = commands - - changed_lacp_facts = self.get_lacp_facts() - - result['before'] = existing_lacp_facts - if result['changed']: - result['after'] = changed_lacp_facts - result['warnings'] = warnings - - return result - - def set_config(self, existing_lacp_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - want = self._module.params['config'] - have = existing_lacp_facts - resp = self.set_state(want, have) - - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - state = self._module.params['state'] - if state in ('merged', 'replaced') and not want: - self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(state)) - - if state == 'deleted': - commands = self._state_deleted(want, have) - elif state == 'merged': - commands = self._state_merged(want, have) - elif state == 'replaced': - commands = self._state_replaced(want, have) - - return commands - - def _state_replaced(self, want, have): - """ The command generator when state is replaced - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - commands.extend(self._set_config(want, have)) - - return commands - - def _state_merged(self, want, have): - """ The command generator when state is merged - - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - - commands.extend(self._set_config(want, have)) - - return commands - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - - if want: - commands.extend(self._clear_config(have)) - else: - commands.extend(self._clear_config(have)) - - return commands - - def _remove_command_from_config_list(self, cmd, commands): - commands.append('no %s' % cmd) - return commands - - def _add_command_to_config_list(self, cmd, commands): - if cmd not in commands: - commands.append(cmd) - - def _set_config(self, want, have): - # Set the interface config based on the want and have config - commands = [] - - want_dict = dict_to_set(want) - have_dict = dict_to_set(have) - diff = want_dict - have_dict - - if diff: - cmd = 'lacp system-priority {0}'.format(want.get('system').get('priority')) - self._add_command_to_config_list(cmd, commands) - - return commands - - def _clear_config(self, have): - # Delete the interface config based on the want and have config - commands = [] - - if have.get('system').get('priority') and have.get('system').get('priority') != 32768: - cmd = 'lacp system-priority' - self._remove_command_from_config_list(cmd, commands) - - return commands diff --git a/lib/ansible/module_utils/network/ios/config/lacp_interfaces/lacp_interfaces.py b/lib/ansible/module_utils/network/ios/config/lacp_interfaces/lacp_interfaces.py deleted file mode 100644 index 71ac96d0c38..00000000000 --- a/lib/ansible/module_utils/network/ios/config/lacp_interfaces/lacp_interfaces.py +++ /dev/null @@ -1,260 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_lacp_interfaces class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to it's desired end-state is -created -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.network.ios.utils.utils import dict_to_set -from ansible.module_utils.network.ios.utils.utils import remove_command_from_config_list, add_command_to_config_list -from ansible.module_utils.network.ios.utils.utils import filter_dict_having_none_value, remove_duplicate_interface - - -class Lacp_Interfaces(ConfigBase): - """ - The ios_lacp_interfaces class - """ - - gather_subset = [ - '!all', - '!min', - ] - - gather_network_resources = [ - 'lacp_interfaces', - ] - - def __init__(self, module): - super(Lacp_Interfaces, self).__init__(module) - - def get_lacp_interfaces_facts(self): - """ Get the 'facts' (the current configuration) - - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) - lacp_interfaces_facts = facts['ansible_network_resources'].get('lacp_interfaces') - - if not lacp_interfaces_facts: - return [] - return lacp_interfaces_facts - - def execute_module(self): - """ Execute the module - - :rtype: A dictionary - :returns: The result from module execution - """ - result = {'changed': False} - commands = list() - warnings = list() - - existing_lacp_interfaces_facts = self.get_lacp_interfaces_facts() - commands.extend(self.set_config(existing_lacp_interfaces_facts)) - if commands: - if not self._module.check_mode: - self._connection.edit_config(commands) - result['changed'] = True - result['commands'] = commands - - changed_lacp_interfaces_facts = self.get_lacp_interfaces_facts() - - result['before'] = existing_lacp_interfaces_facts - if result['changed']: - result['after'] = changed_lacp_interfaces_facts - - result['warnings'] = warnings - - return result - - def set_config(self, existing_lacp_interfaces_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - want = self._module.params['config'] - have = existing_lacp_interfaces_facts - resp = self.set_state(want, have) - - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - state = self._module.params['state'] - if state in ('overridden', 'merged', 'replaced') and not want: - self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(state)) - - if state == 'overridden': - commands = self._state_overridden(want, have) - elif state == 'deleted': - commands = self._state_deleted(want, have) - elif state == 'merged': - commands = self._state_merged(want, have) - elif state == 'replaced': - commands = self._state_replaced(want, have) - - return commands - - def _state_replaced(self, want, have): - """ The command generator when state is replaced - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - continue - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each)) - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_overridden(self, want, have): - """ The command generator when state is overridden - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - for each in have: - for interface in want: - if each['name'] == interface['name']: - break - else: - # We didn't find a matching desired state, which means we can - # pretend we received an empty desired state. - interface = dict(name=each['name']) - commands.extend(self._clear_config(interface, each)) - continue - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each)) - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_merged(self, want, have): - """ The command generator when state is merged - - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - - for interface in want: - for each in have: - if interface['name'] == each['name']: - break - else: - continue - commands.extend(self._set_config(interface, each)) - - return commands - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - - if want: - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - continue - interface = dict(name=interface['name']) - commands.extend(self._clear_config(interface, each)) - else: - for each in have: - commands.extend(self._clear_config(dict(), each)) - - return commands - - def _set_config(self, want, have): - # Set the interface config based on the want and have config - commands = [] - interface = 'interface ' + have['name'] - - want_dict = dict_to_set(want) - have_dict = dict_to_set(have) - diff = want_dict - have_dict - - if diff: - port_priotity = dict(diff).get('port_priority') - max_bundle = dict(diff).get('max_bundle') - fast_switchover = dict(diff).get('fast_switchover') - if port_priotity: - cmd = 'lacp port-priority {0}'.format(port_priotity) - add_command_to_config_list(interface, cmd, commands) - if max_bundle: - cmd = 'lacp max-bundle {0}'.format(max_bundle) - add_command_to_config_list(interface, cmd, commands) - if fast_switchover: - cmd = 'lacp fast-switchover' - add_command_to_config_list(interface, cmd, commands) - - return commands - - def _clear_config(self, want, have): - # Delete the interface config based on the want and have config - commands = [] - if want.get('name'): - interface = 'interface ' + want['name'] - else: - interface = 'interface ' + have['name'] - - if have.get('port_priority') and have.get('port_priority') != want.get('port_priority'): - cmd = 'lacp port-priority' - remove_command_from_config_list(interface, cmd, commands) - if have.get('max_bundle') and have.get('max_bundle') != want.get('max_bundle'): - cmd = 'lacp max-bundle' - remove_command_from_config_list(interface, cmd, commands) - if have.get('fast_switchover'): - cmd = 'lacp fast-switchover' - remove_command_from_config_list(interface, cmd, commands) - - return commands diff --git a/lib/ansible/module_utils/network/ios/config/lag_interfaces/lag_interfaces.py b/lib/ansible/module_utils/network/ios/config/lag_interfaces/lag_interfaces.py deleted file mode 100644 index c4760c1061c..00000000000 --- a/lib/ansible/module_utils/network/ios/config/lag_interfaces/lag_interfaces.py +++ /dev/null @@ -1,296 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_lag_interfaces class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to it's desired end-state is -created -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -import re -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.network.ios.utils.utils import dict_to_set -from ansible.module_utils.network.ios.utils.utils import filter_dict_having_none_value, remove_duplicate_interface - - -class Lag_interfaces(ConfigBase): - """ - The ios_lag_interfaces class - """ - - gather_subset = [ - '!all', - '!min', - ] - - gather_network_resources = [ - 'lag_interfaces', - ] - - def __init__(self, module): - super(Lag_interfaces, self).__init__(module) - - def get_lag_interfaces_facts(self): - """ Get the 'facts' (the current configuration) - - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) - lag_interfaces_facts = facts['ansible_network_resources'].get('lag_interfaces') - if not lag_interfaces_facts: - return [] - return lag_interfaces_facts - - def execute_module(self): - """ Execute the module - - :rtype: A dictionary - :returns: The result from module execution - """ - result = {'changed': False} - commands = list() - warnings = list() - - existing_lag_interfaces_facts = self.get_lag_interfaces_facts() - commands.extend(self.set_config(existing_lag_interfaces_facts)) - if commands: - if not self._module.check_mode: - self._connection.edit_config(commands) - result['changed'] = True - result['commands'] = commands - - changed_lag_interfaces_facts = self.get_lag_interfaces_facts() - - result['before'] = existing_lag_interfaces_facts - if result['changed']: - result['after'] = changed_lag_interfaces_facts - - result['warnings'] = warnings - return result - - def set_config(self, existing_lag_interfaces_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - want = self._module.params['config'] - have = existing_lag_interfaces_facts - resp = self.set_state(want, have) - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - - state = self._module.params['state'] - if state in ('overridden', 'merged', 'replaced') and not want: - self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(state)) - - module = self._module - if state == 'overridden': - commands = self._state_overridden(want, have, module) - elif state == 'deleted': - commands = self._state_deleted(want, have) - elif state == 'merged': - commands = self._state_merged(want, have, module) - elif state == 'replaced': - commands = self._state_replaced(want, have, module) - return commands - - def _state_replaced(self, want, have, module): - """ The command generator when state is replaced - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - for interface in want: - for each_interface in interface.get('members'): - for each in have: - if each.get('members'): - for every in each.get('members'): - match = False - if every['member'] == each_interface['member']: - match = True - break - else: - continue - if match: - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each, module)) - elif each.get('name') == each_interface['member']: - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each, module)) - break - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_overridden(self, want, have, module): - """ The command generator when state is overridden - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - for interface in want: - for each_interface in interface.get('members'): - for each in have: - if each.get('members'): - for every in each.get('members'): - match = False - if every['member'] == each_interface['member']: - match = True - break - else: - commands.extend(self._clear_config(interface, each)) - continue - if match: - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each, module)) - elif each.get('name') == each_interface['member']: - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each, module)) - break - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_merged(self, want, have, module): - """ The command generator when state is merged - - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - - for interface in want: - for each_interface in interface.get('members'): - for each in have: - if each.get('members'): - for every in each.get('members'): - if every['member'] == each_interface['member']: - break - elif each.get('name') == each_interface['member']: - break - else: - continue - commands.extend(self._set_config(interface, each, module)) - - return commands - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - - if want: - for interface in want: - for each in have: - if each.get('name') == interface['name']: - break - else: - continue - commands.extend(self._clear_config(interface, each)) - else: - for each in have: - commands.extend(self._clear_config(dict(), each)) - - return commands - - def remove_command_from_config_list(self, interface, cmd, commands): - # To delete the passed config - if interface not in commands: - commands.append(interface) - commands.append('no %s' % cmd) - return commands - - def add_command_to_config_list(self, interface, cmd, commands): - # To set the passed config - if interface not in commands: - commands.append(interface) - commands.append(cmd) - return commands - - def _set_config(self, want, have, module): - # Set the interface config based on the want and have config - commands = [] - - # To remove keys with None values from want dict - want = utils.remove_empties(want) - # Get the diff b/w want and have - want_dict = dict_to_set(want) - have_dict = dict_to_set(have) - diff = want_dict - have_dict - - # To get the channel-id from lag port-channel name - lag_config = dict(diff).get('members') - channel_name = re.search(r'(\d+)', want.get('name')) - if channel_name: - channel_id = channel_name.group() - else: - module.fail_json(msg="Lag Interface Name is not correct!") - if lag_config: - for each in lag_config: - each = dict(each) - each_interface = 'interface {0}'.format(each.get('member')) - if have.get('name') == want['members'][0]['member'] or have.get('name').lower().startswith('po'): - if each.get('mode'): - cmd = 'channel-group {0} mode {1}'.format(channel_id, each.get('mode')) - self.add_command_to_config_list(each_interface, cmd, commands) - elif each.get('link'): - cmd = 'channel-group {0} link {1}'.format(channel_id, each.get('link')) - self.add_command_to_config_list(each_interface, cmd, commands) - - return commands - - def _clear_config(self, want, have): - # Delete the interface config based on the want and have config - commands = [] - - if have.get('members'): - for each in have['members']: - interface = 'interface ' + each['member'] - if want.get('members'): - if each.get('member') and each.get('member') != want['members'][0]['member']: - self.remove_command_from_config_list(interface, 'channel-group', commands) - elif each.get('member'): - self.remove_command_from_config_list(interface, 'channel-group', commands) - - return commands diff --git a/lib/ansible/module_utils/network/ios/config/lldp_global/lldp_global.py b/lib/ansible/module_utils/network/ios/config/lldp_global/lldp_global.py deleted file mode 100644 index a3f6dd6091a..00000000000 --- a/lib/ansible/module_utils/network/ios/config/lldp_global/lldp_global.py +++ /dev/null @@ -1,238 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat Inc. -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_lldp_global class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to its desired end-state is -created -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -from ansible.module_utils.six import iteritems -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.network.ios.utils.utils import dict_to_set -from ansible.module_utils.network.ios.utils.utils import filter_dict_having_none_value - - -class Lldp_global(ConfigBase): - """ - The ios_lldp_global class - """ - - gather_subset = [ - '!all', - '!min', - ] - - gather_network_resources = [ - 'lldp_global', - ] - - tlv_select_params = {'four_wire_power_management': '4-wire-power-management', 'mac_phy_cfg': 'mac-phy-cfg', - 'management_address': 'management-address', 'port_description': 'port-description', - 'port_vlan': 'port-vlan', 'power_management': 'power-management', - 'system_capabilities': 'system-capabilities', 'system_description': 'system-description', - 'system_name': 'system-name'} - - def __init__(self, module): - super(Lldp_global, self).__init__(module) - - def get_lldp_global_facts(self): - """ Get the 'facts' (the current configuration) - - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) - lldp_global_facts = facts['ansible_network_resources'].get('lldp_global') - if not lldp_global_facts: - return {} - - return lldp_global_facts - - def execute_module(self): - """ Execute the module - - :rtype: A dictionary - :returns: The result from moduel execution - """ - result = {'changed': False} - commands = list() - warnings = list() - - existing_lldp_global_facts = self.get_lldp_global_facts() - commands.extend(self.set_config(existing_lldp_global_facts)) - - if commands: - if not self._module.check_mode: - self._connection.edit_config(commands) - result['changed'] = True - result['commands'] = commands - - changed_lldp_global_facts = self.get_lldp_global_facts() - - result['before'] = existing_lldp_global_facts - if result['changed']: - result['after'] = changed_lldp_global_facts - result['warnings'] = warnings - - return result - - def set_config(self, existing_lldp_global_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - want = self._module.params['config'] - have = existing_lldp_global_facts - resp = self.set_state(want, have) - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - commands = [] - state = self._module.params['state'] - if state in ('merged', 'replaced') and not want: - self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(state)) - - if state == 'overridden': - commands = self._state_overridden(want, have) - elif state == 'deleted': - commands = self._state_deleted(want, have) - elif state == 'merged': - commands = self._state_merged(want, have) - elif state == 'replaced': - commands = self._state_replaced(want, have) - - return commands - - def _state_replaced(self, want, have): - """ The command generator when state is replaced - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :param interface_type: interface type - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the deisred configuration - """ - commands = [] - - have_dict = filter_dict_having_none_value(want, have) - commands.extend(self._clear_config(have_dict)) - commands.extend(self._set_config(want, have)) - - return commands - - def _state_merged(self, want, have): - """ The command generator when state is merged - - :param want: the additive configuration as a dictionary - :param obj_in_have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - - commands.extend(self._set_config(want, have)) - - return commands - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - - :param want: the objects from which the configuration should be removed - :param obj_in_have: the current configuration as a dictionary - :param interface_type: interface type - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - - commands.extend(self._clear_config(have)) - - return commands - - def _remove_command_from_config_list(self, cmd, commands): - if cmd not in commands: - commands.append('no %s' % cmd) - - def add_command_to_config_list(self, cmd, commands): - if cmd not in commands: - commands.append(cmd) - - def _set_config(self, want, have): - # Set the interface config based on the want and have config - commands = [] - - # Get the diff b/w want and have - want_dict = dict_to_set(want) - have_dict = dict_to_set(have) - diff = want_dict - have_dict - - if diff: - diff = dict(diff) - holdtime = diff.get('holdtime') - enabled = diff.get('enabled') - timer = diff.get('timer') - reinit = diff.get('reinit') - tlv_select = diff.get('tlv_select') - - if holdtime: - cmd = 'lldp holdtime {0}'.format(holdtime) - self.add_command_to_config_list(cmd, commands) - if enabled: - cmd = 'lldp run' - self.add_command_to_config_list(cmd, commands) - if timer: - cmd = 'lldp timer {0}'.format(timer) - self.add_command_to_config_list(cmd, commands) - if reinit: - cmd = 'lldp reinit {0}'.format(reinit) - self.add_command_to_config_list(cmd, commands) - if tlv_select: - tlv_selec_dict = dict(tlv_select) - for k, v in iteritems(self.tlv_select_params): - if k in tlv_selec_dict and tlv_selec_dict[k]: - cmd = 'lldp tlv-select {0}'.format(v) - self.add_command_to_config_list(cmd, commands) - - return commands - - def _clear_config(self, have): - # Delete the interface config based on the want and have config - commands = [] - - if have.get('holdtime'): - cmd = 'lldp holdtime' - self._remove_command_from_config_list(cmd, commands) - if have.get('enabled'): - cmd = 'lldp run' - self._remove_command_from_config_list(cmd, commands) - if have.get('timer'): - cmd = 'lldp timer' - self._remove_command_from_config_list(cmd, commands) - if have.get('reinit'): - cmd = 'lldp reinit' - self._remove_command_from_config_list(cmd, commands) - - return commands diff --git a/lib/ansible/module_utils/network/ios/config/lldp_interfaces/lldp_interfaces.py b/lib/ansible/module_utils/network/ios/config/lldp_interfaces/lldp_interfaces.py deleted file mode 100644 index 57a6a3cd4cc..00000000000 --- a/lib/ansible/module_utils/network/ios/config/lldp_interfaces/lldp_interfaces.py +++ /dev/null @@ -1,270 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_lldp_interfaces class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to its desired end-state is -created -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.network.ios.utils.utils import dict_to_set -from ansible.module_utils.network.ios.utils.utils import remove_command_from_config_list, add_command_to_config_list -from ansible.module_utils.network.ios.utils.utils import filter_dict_having_none_value, remove_duplicate_interface - - -class Lldp_Interfaces(ConfigBase): - """ - The ios_lldp_interfaces class - """ - - gather_subset = [ - '!all', - '!min', - ] - - gather_network_resources = [ - 'lldp_interfaces', - ] - - def __init__(self, module): - super(Lldp_Interfaces, self).__init__(module) - - def get_lldp_interfaces_facts(self): - """ Get the 'facts' (the current configuration) - - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) - lldp_interfaces_facts = facts['ansible_network_resources'].get('lldp_interfaces') - - if not lldp_interfaces_facts: - return [] - return lldp_interfaces_facts - - def execute_module(self): - """ Execute the module - - :rtype: A dictionary - :returns: The result from module execution - """ - result = {'changed': False} - commands = list() - warnings = list() - - existing_lldp_interfaces_facts = self.get_lldp_interfaces_facts() - commands.extend(self.set_config(existing_lldp_interfaces_facts)) - if commands: - if not self._module.check_mode: - self._connection.edit_config(commands) - result['changed'] = True - result['commands'] = commands - - changed_lldp_interfaces_facts = self.get_lldp_interfaces_facts() - - result['before'] = existing_lldp_interfaces_facts - if result['changed']: - result['after'] = changed_lldp_interfaces_facts - - result['warnings'] = warnings - - return result - - def set_config(self, existing_lldp_interfaces_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - want = self._module.params['config'] - have = existing_lldp_interfaces_facts - resp = self.set_state(want, have) - - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - state = self._module.params['state'] - if state in ('overridden', 'merged', 'replaced') and not want: - self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(state)) - - if state == 'overridden': - commands = self._state_overridden(want, have) - elif state == 'deleted': - commands = self._state_deleted(want, have) - elif state == 'merged': - commands = self._state_merged(want, have) - elif state == 'replaced': - commands = self._state_replaced(want, have) - - return commands - - def _state_replaced(self, want, have): - """ The command generator when state is replaced - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - continue - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each)) - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_overridden(self, want, have): - """ The command generator when state is overridden - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - for each in have: - for interface in want: - if each['name'] == interface['name']: - break - else: - # We didn't find a matching desired state, which means we can - # pretend we received an empty desired state. - interface = dict(name=each['name']) - commands.extend(self._clear_config(interface, each)) - continue - have_dict = filter_dict_having_none_value(interface, each) - commands.extend(self._clear_config(dict(), have_dict)) - commands.extend(self._set_config(interface, each)) - # Remove the duplicate interface call - commands = remove_duplicate_interface(commands) - - return commands - - def _state_merged(self, want, have): - """ The command generator when state is merged - - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - - for interface in want: - for each in have: - if interface['name'] == each['name']: - break - else: - continue - commands.extend(self._set_config(interface, each)) - - return commands - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - - if want: - for interface in want: - for each in have: - if each['name'] == interface['name']: - break - else: - continue - interface = dict(name=interface['name']) - commands.extend(self._clear_config(interface, each)) - else: - for each in have: - commands.extend(self._clear_config(dict(), each)) - - return commands - - def _set_config(self, want, have): - # Set the interface config based on the want and have config - commands = [] - - interface = 'interface ' + have['name'] - # Get the diff b/w want and have - want_dict = dict_to_set(want) - have_dict = dict_to_set(have) - diff = want_dict - have_dict - - if diff: - diff = dict(diff) - receive = diff.get('receive') - transmit = diff.get('transmit') - med_tlv_select = diff.get('med_tlv_select') - tlv_select = diff.get('tlv_select') - if receive: - cmd = 'lldp receive' - add_command_to_config_list(interface, cmd, commands) - elif receive is False: - cmd = 'no lldp receive' - add_command_to_config_list(interface, cmd, commands) - if transmit: - cmd = 'lldp transmit' - add_command_to_config_list(interface, cmd, commands) - elif transmit is False: - cmd = 'no lldp transmit' - add_command_to_config_list(interface, cmd, commands) - - if med_tlv_select: - med_tlv_select = dict(med_tlv_select) - if med_tlv_select.get('inventory_management'): - add_command_to_config_list(interface, 'lldp med-tlv-select inventory-management', commands) - if tlv_select: - tlv_select = dict(tlv_select) - if tlv_select.get('power_management'): - add_command_to_config_list(interface, 'lldp tlv-select power-management', commands) - - return commands - - def _clear_config(self, want, have): - # Delete the interface config based on the want and have config - commands = [] - if want.get('name'): - interface = 'interface ' + want['name'] - else: - interface = 'interface ' + have['name'] - - if have.get('receive') and have.get('receive') != want.get('receive'): - cmd = 'lldp receive' - remove_command_from_config_list(interface, cmd, commands) - if have.get('transmit') and have.get('transmit') != want.get('transmit'): - cmd = 'lldp transmit' - remove_command_from_config_list(interface, cmd, commands) - - return commands diff --git a/lib/ansible/module_utils/network/ios/config/static_routes/static_routes.py b/lib/ansible/module_utils/network/ios/config/static_routes/static_routes.py deleted file mode 100644 index 0e3eb4a66be..00000000000 --- a/lib/ansible/module_utils/network/ios/config/static_routes/static_routes.py +++ /dev/null @@ -1,532 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_static_routes class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to it's desired end-state is -created -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -import copy -from ansible.module_utils.six import iteritems -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.network.ios.utils.utils import new_dict_to_set, validate_n_expand_ipv4, filter_dict_having_none_value - - -class Static_Routes(ConfigBase): - """ - The ios_static_routes class - """ - - gather_subset = [ - '!all', - '!min', - ] - - gather_network_resources = [ - 'static_routes', - ] - - def __init__(self, module): - super(Static_Routes, self).__init__(module) - - def get_static_routes_facts(self, data=None): - """ Get the 'facts' (the current configuration) - - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources, data=data) - static_routes_facts = facts['ansible_network_resources'].get('static_routes') - if not static_routes_facts: - return [] - return static_routes_facts - - def execute_module(self): - """ Execute the module - - :rtype: A dictionary - :returns: The result from module execution - """ - result = {'changed': False} - commands = list() - warnings = list() - - if self.state in self.ACTION_STATES: - existing_static_routes_facts = self.get_static_routes_facts() - else: - existing_static_routes_facts = [] - - if self.state in self.ACTION_STATES or self.state == 'rendered': - commands.extend(self.set_config(existing_static_routes_facts)) - - if commands and self.state in self.ACTION_STATES: - if not self._module.check_mode: - self._connection.edit_config(commands) - result['changed'] = True - - if self.state in self.ACTION_STATES: - result['commands'] = commands - - if self.state in self.ACTION_STATES or self.state == 'gathered': - changed_static_routes_facts = self.get_static_routes_facts() - elif self.state == 'rendered': - result['rendered'] = commands - elif self.state == 'parsed': - running_config = self._module.params['running_config'] - if not running_config: - self._module.fail_json( - msg="value of running_config parameter must not be empty for state parsed" - ) - result['parsed'] = self.get_static_routes_facts(data=running_config) - else: - changed_static_routes_facts = [] - - if self.state in self.ACTION_STATES: - result['before'] = existing_static_routes_facts - if result['changed']: - result['after'] = changed_static_routes_facts - elif self.state == 'gathered': - result['gathered'] = changed_static_routes_facts - - result['warnings'] = warnings - - return result - - def set_config(self, existing_static_routes_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - want = self._module.params['config'] - have = existing_static_routes_facts - resp = self.set_state(want, have) - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - state = self._module.params['state'] - if state in ('overridden', 'merged', 'replaced', 'rendered') and not want: - self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(state)) - commands = [] - if state == 'overridden': - commands = self._state_overridden(want, have) - elif state == 'deleted': - commands = self._state_deleted(want, have) - elif state == 'merged' or state == 'rendered': - commands = self._state_merged(want, have) - elif state == 'replaced': - commands = self._state_replaced(want, have) - return commands - - def _state_replaced(self, want, have): - """ The command generator when state is replaced - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - - commands = [] - - # Drill each iteration of want n have and then based on dest and afi tyoe comparison take config call - for w in want: - for addr_want in w.get('address_families'): - for route_want in addr_want.get('routes'): - check = False - for h in have: - if h.get('address_families'): - for addr_have in h.get('address_families'): - for route_have in addr_have.get('routes'): - if route_want.get('dest') == route_have.get('dest')\ - and addr_want['afi'] == addr_have['afi']: - check = True - have_set = set() - new_hops = [] - for each in route_want.get('next_hops'): - want_set = set() - new_dict_to_set(each, [], want_set, 0) - new_hops.append(want_set) - new_dict_to_set(addr_have, [], have_set, 0) - # Check if the have dict next_hops value is diff from want dict next_hops - have_dict = filter_dict_having_none_value(route_want.get('next_hops')[0], - route_have.get('next_hops')[0]) - # update the have_dict with forward_router_address - have_dict.update({'forward_router_address': route_have.get('next_hops')[0]. - get('forward_router_address')}) - # updating the have_dict with next_hops val that's not None - new_have_dict = {} - for k, v in have_dict.items(): - if v is not None: - new_have_dict.update({k: v}) - - # Set the new config from the user provided want config - cmd = self._set_config(w, h, addr_want, route_want, route_have, new_hops, have_set) - - if cmd: - # since inplace update isn't allowed for static routes, preconfigured - # static routes needs to be deleted before the new want static routes changes - # are applied - clear_route_have = copy.deepcopy(route_have) - # inplace update is allowed in case of ipv6 static routes, so not deleting it - # before applying the want changes - if ':' not in route_want.get('dest'): - commands.extend(self._clear_config({}, h, {}, addr_have, - {}, clear_route_have)) - commands.extend(cmd) - if check: - break - if check: - break - if not check: - # For configuring any non-existing want config - new_hops = [] - for each in route_want.get('next_hops'): - want_set = set() - new_dict_to_set(each, [], want_set, 0) - new_hops.append(want_set) - commands.extend(self._set_config(w, {}, addr_want, route_want, {}, new_hops, set())) - commands = [each for each in commands if 'no' in each] + \ - [each for each in commands if 'no' not in each] - - return commands - - def _state_overridden(self, want, have): - """ The command generator when state is overridden - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - - commands = [] - # Creating a copy of want, so that want dict is intact even after delete operation - # performed during override want n have comparison - temp_want = copy.deepcopy(want) - - # Drill each iteration of want n have and then based on dest and afi tyoe comparison take config call - for h in have: - if h.get('address_families'): - for addr_have in h.get('address_families'): - for route_have in addr_have.get('routes'): - check = False - for w in temp_want: - for addr_want in w.get('address_families'): - count = 0 - for route_want in addr_want.get('routes'): - if route_want.get('dest') == route_have.get('dest') \ - and addr_want['afi'] == addr_have['afi']: - check = True - have_set = set() - new_hops = [] - for each in route_want.get('next_hops'): - want_set = set() - new_dict_to_set(each, [], want_set, 0) - new_hops.append(want_set) - new_dict_to_set(addr_have, [], have_set, 0) - commands.extend(self._clear_config(w, h, addr_want, addr_have, - route_want, route_have)) - commands.extend(self._set_config(w, h, addr_want, - route_want, route_have, new_hops, have_set)) - del addr_want.get('routes')[count] - count += 1 - if check: - break - if check: - break - if not check: - commands.extend(self._clear_config({}, h, {}, addr_have, {}, route_have)) - # For configuring any non-existing want config - for w in temp_want: - for addr_want in w.get('address_families'): - for route_want in addr_want.get('routes'): - new_hops = [] - for each in route_want.get('next_hops'): - want_set = set() - new_dict_to_set(each, [], want_set, 0) - new_hops.append(want_set) - commands.extend(self._set_config(w, {}, addr_want, route_want, {}, new_hops, set())) - # Arranging the cmds suct that all delete cmds are fired before all set cmds - commands = [each for each in sorted(commands) if 'no' in each] + \ - [each for each in sorted(commands) if 'no' not in each] - - return commands - - def _state_merged(self, want, have): - """ The command generator when state is merged - - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - - # Drill each iteration of want n have and then based on dest and afi tyoe comparison take config call - for w in want: - for addr_want in w.get('address_families'): - for route_want in addr_want.get('routes'): - check = False - for h in have: - if h.get('address_families'): - for addr_have in h.get('address_families'): - for route_have in addr_have.get('routes'): - if route_want.get('dest') == route_have.get('dest')\ - and addr_want['afi'] == addr_have['afi']: - check = True - have_set = set() - new_hops = [] - for each in route_want.get('next_hops'): - want_set = set() - new_dict_to_set(each, [], want_set, 0) - new_hops.append(want_set) - new_dict_to_set(addr_have, [], have_set, 0) - commands.extend(self._set_config(w, h, addr_want, - route_want, route_have, new_hops, have_set)) - if check: - break - if check: - break - if not check: - # For configuring any non-existing want config - new_hops = [] - for each in route_want.get('next_hops'): - want_set = set() - new_dict_to_set(each, [], want_set, 0) - new_hops.append(want_set) - commands.extend(self._set_config(w, {}, addr_want, route_want, {}, new_hops, set())) - - return commands - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - - if want: - # Drill each iteration of want n have and then based on dest and afi type comparison fire delete config call - for w in want: - if w.get('address_families'): - for addr_want in w.get('address_families'): - for route_want in addr_want.get('routes'): - check = False - for h in have: - if h.get('address_families'): - for addr_have in h.get('address_families'): - for route_have in addr_have.get('routes'): - if route_want.get('dest') == route_have.get('dest') \ - and addr_want['afi'] == addr_have['afi']: - check = True - if route_want.get('next_hops'): - commands.extend(self._clear_config({}, w, {}, addr_want, {}, route_want)) - else: - commands.extend(self._clear_config({}, h, {}, addr_have, {}, route_have)) - if check: - break - if check: - break - else: - for h in have: - for addr_have in h.get('address_families'): - for route_have in addr_have.get('routes'): - if w.get('vrf') == h.get('vrf'): - commands.extend(self._clear_config({}, h, {}, addr_have, {}, route_have)) - else: - # Drill each iteration of have and then based on dest and afi type comparison fire delete config call - for h in have: - for addr_have in h.get('address_families'): - for route_have in addr_have.get('routes'): - commands.extend(self._clear_config({}, h, {}, addr_have, {}, route_have)) - - return commands - - def prepare_config_commands(self, config_dict, cmd): - """ - function to parse the input dict and form the prepare the config commands - :rtype: A str - :returns: The command necessary to configure the static routes - """ - - dhcp = config_dict.get('dhcp') - distance_metric = config_dict.get('distance_metric') - forward_router_address = config_dict.get('forward_router_address') - global_route_config = config_dict.get('global') - interface = config_dict.get('interface') - multicast = config_dict.get('multicast') - name = config_dict.get('name') - permanent = config_dict.get('permanent') - tag = config_dict.get('tag') - track = config_dict.get('track') - dest = config_dict.get('dest') - temp_dest = dest.split('/') - if temp_dest and ':' not in dest: - dest = validate_n_expand_ipv4(self._module, {'address': dest}) - - cmd = cmd + dest - if interface: - cmd = cmd + ' {0}'.format(interface) - if forward_router_address: - cmd = cmd + ' {0}'.format(forward_router_address) - if dhcp: - cmd = cmd + ' DHCP' - if distance_metric: - cmd = cmd + ' {0}'.format(distance_metric) - if global_route_config: - cmd = cmd + ' global' - if multicast: - cmd = cmd + ' multicast' - if name: - cmd = cmd + ' name {0}'.format(name) - if permanent: - cmd = cmd + ' permanent' - elif track: - cmd = cmd + ' track {0}'.format(track) - if tag: - cmd = cmd + ' tag {0}'.format(tag) - - return cmd - - def _set_config(self, want, have, addr_want, route_want, route_have, hops, have_set): - """ - Set the interface config based on the want and have config - :rtype: A list - :returns: The commands necessary to configure the static routes - """ - - commands = [] - cmd = None - - vrf_diff = False - topology_diff = False - want_vrf = want.get('vrf') - have_vrf = have.get('vrf') - if want_vrf != have_vrf: - vrf_diff = True - want_topology = want.get('topology') - have_topology = have.get('topology') - if want_topology != have_topology: - topology_diff = True - - have_dest = route_have.get('dest') - if have_dest: - have_set.add(tuple(iteritems({'dest': have_dest}))) - - # configure set cmd for each hops under the same destination - for each in hops: - diff = each - have_set - if vrf_diff: - each.add(tuple(iteritems({'vrf': want_vrf}))) - if topology_diff: - each.add(tuple(iteritems({'topology': want_topology}))) - if diff or vrf_diff or topology_diff: - if want_vrf and not vrf_diff: - each.add(tuple(iteritems({'vrf': want_vrf}))) - if want_topology and not vrf_diff: - each.add(tuple(iteritems({'topology': want_topology}))) - each.add(tuple(iteritems({'afi': addr_want.get('afi')}))) - each.add(tuple(iteritems({'dest': route_want.get('dest')}))) - temp_want = {} - for each_want in each: - temp_want.update(dict(each_want)) - - if temp_want.get('afi') == 'ipv4': - cmd = 'ip route ' - vrf = temp_want.get('vrf') - if vrf: - cmd = cmd + 'vrf {0} '.format(vrf) - cmd = self.prepare_config_commands(temp_want, cmd) - elif temp_want.get('afi') == 'ipv6': - cmd = 'ipv6 route ' - cmd = self.prepare_config_commands(temp_want, cmd) - commands.append(cmd) - - return commands - - def _clear_config(self, want, have, addr_want, addr_have, route_want, route_have): - """ - Delete the interface config based on the want and have config - :rtype: A list - :returns: The commands necessary to configure the static routes - """ - - commands = [] - cmd = None - - vrf_diff = False - topology_diff = False - want_vrf = want.get('vrf') - have_vrf = have.get('vrf') - if want_vrf != have_vrf: - vrf_diff = True - want_topology = want.get('topology') - have_topology = have.get('topology') - if want_topology != have_topology: - topology_diff = True - - want_set = set() - new_dict_to_set(addr_want, [], want_set, 0) - - have_hops = [] - for each in route_have.get('next_hops'): - temp_have_set = set() - new_dict_to_set(each, [], temp_have_set, 0) - have_hops.append(temp_have_set) - - # configure delete cmd for each hops under the same destination - for each in have_hops: - diff = each - want_set - if vrf_diff: - each.add(tuple(iteritems({'vrf': have_vrf}))) - if topology_diff: - each.add(tuple(iteritems({'topology': want_topology}))) - if diff or vrf_diff or topology_diff: - if want_vrf and not vrf_diff: - each.add(tuple(iteritems({'vrf': want_vrf}))) - if want_topology and not vrf_diff: - each.add(tuple(iteritems({'topology': want_topology}))) - if addr_want: - each.add(tuple(iteritems({'afi': addr_want.get('afi')}))) - else: - each.add(tuple(iteritems({'afi': addr_have.get('afi')}))) - if route_want: - each.add(tuple(iteritems({'dest': route_want.get('dest')}))) - else: - each.add(tuple(iteritems({'dest': route_have.get('dest')}))) - temp_want = {} - for each_want in each: - temp_want.update(dict(each_want)) - - if temp_want.get('afi') == 'ipv4': - cmd = 'no ip route ' - vrf = temp_want.get('vrf') - if vrf: - cmd = cmd + 'vrf {0} '.format(vrf) - cmd = self.prepare_config_commands(temp_want, cmd) - elif temp_want.get('afi') == 'ipv6': - cmd = 'no ipv6 route ' - cmd = self.prepare_config_commands(temp_want, cmd) - commands.append(cmd) - - return commands diff --git a/lib/ansible/module_utils/network/ios/config/vlans/vlans.py b/lib/ansible/module_utils/network/ios/config/vlans/vlans.py deleted file mode 100644 index d77e2987703..00000000000 --- a/lib/ansible/module_utils/network/ios/config/vlans/vlans.py +++ /dev/null @@ -1,292 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_vlans class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to it's desired end-state is -created -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.network.ios.utils.utils import dict_to_set - - -class Vlans(ConfigBase): - """ - The ios_vlans class - """ - - gather_subset = [ - '!all', - '!min', - ] - - gather_network_resources = [ - 'vlans', - ] - - def __init__(self, module): - super(Vlans, self).__init__(module) - - def get_interfaces_facts(self): - """ Get the 'facts' (the current configuration) - - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) - interfaces_facts = facts['ansible_network_resources'].get('vlans') - if not interfaces_facts: - return [] - return interfaces_facts - - def execute_module(self): - """ Execute the module - - :rtype: A dictionary - :returns: The result from module execution - """ - result = {'changed': False} - commands = list() - warnings = list() - - existing_interfaces_facts = self.get_interfaces_facts() - commands.extend(self.set_config(existing_interfaces_facts)) - if commands: - if not self._module.check_mode: - self._connection.edit_config(commands) - result['changed'] = True - result['commands'] = commands - - changed_interfaces_facts = self.get_interfaces_facts() - - result['before'] = existing_interfaces_facts - if result['changed']: - result['after'] = changed_interfaces_facts - - result['warnings'] = warnings - return result - - def set_config(self, existing_interfaces_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - want = self._module.params['config'] - have = existing_interfaces_facts - resp = self.set_state(want, have) - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - state = self._module.params['state'] - if state in ('overridden', 'merged', 'replaced') and not want: - self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(state)) - - if state == 'overridden': - commands = self._state_overridden(want, have, state) - elif state == 'deleted': - commands = self._state_deleted(want, have, state) - elif state == 'merged': - commands = self._state_merged(want, have) - elif state == 'replaced': - commands = self._state_replaced(want, have) - return commands - - def _state_replaced(self, want, have): - """ The command generator when state is replaced - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - check = False - for each in want: - for every in have: - if every['vlan_id'] == each['vlan_id']: - check = True - break - else: - continue - if check: - commands.extend(self._set_config(each, every)) - else: - commands.extend(self._set_config(each, dict())) - - return commands - - def _state_overridden(self, want, have, state): - """ The command generator when state is overridden - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - - want_local = want - for each in have: - count = 0 - for every in want_local: - if each['vlan_id'] == every['vlan_id']: - break - count += 1 - else: - # We didn't find a matching desired state, which means we can - # pretend we received an empty desired state. - commands.extend(self._clear_config(every, each, state)) - continue - commands.extend(self._set_config(every, each)) - # as the pre-existing VLAN are now configured by - # above set_config call, deleting the respective - # VLAN entry from the want_local list - del want_local[count] - - # Iterating through want_local list which now only have new VLANs to be - # configured - for each in want_local: - commands.extend(self._set_config(each, dict())) - - return commands - - def _state_merged(self, want, have): - """ The command generator when state is merged - - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - - check = False - for each in want: - for every in have: - if each.get('vlan_id') == every.get('vlan_id'): - check = True - break - else: - continue - if check: - commands.extend(self._set_config(each, every)) - else: - commands.extend(self._set_config(each, dict())) - - return commands - - def _state_deleted(self, want, have, state): - """ The command generator when state is deleted - - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - - if want: - check = False - for each in want: - for every in have: - if each.get('vlan_id') == every.get('vlan_id'): - check = True - break - else: - check = False - continue - if check: - commands.extend(self._clear_config(each, every, state)) - else: - for each in have: - commands.extend(self._clear_config(dict(), each, state)) - - return commands - - def remove_command_from_config_list(self, vlan, cmd, commands): - if vlan not in commands and cmd != 'vlan': - commands.insert(0, vlan) - elif cmd == 'vlan': - commands.append('no %s' % vlan) - return commands - commands.append('no %s' % cmd) - return commands - - def add_command_to_config_list(self, vlan_id, cmd, commands): - if vlan_id not in commands: - commands.insert(0, vlan_id) - if cmd not in commands: - commands.append(cmd) - - def _set_config(self, want, have): - # Set the interface config based on the want and have config - commands = [] - vlan = 'vlan {0}'.format(want.get('vlan_id')) - - # Get the diff b/w want n have - want_dict = dict_to_set(want) - have_dict = dict_to_set(have) - diff = want_dict - have_dict - - if diff: - name = dict(diff).get('name') - state = dict(diff).get('state') - shutdown = dict(diff).get('shutdown') - mtu = dict(diff).get('mtu') - remote_span = dict(diff).get('remote_span') - if name: - cmd = 'name {0}'.format(name) - self.add_command_to_config_list(vlan, cmd, commands) - if state: - cmd = 'state {0}'.format(state) - self.add_command_to_config_list(vlan, cmd, commands) - if mtu: - cmd = 'mtu {0}'.format(mtu) - self.add_command_to_config_list(vlan, cmd, commands) - if remote_span: - self.add_command_to_config_list(vlan, 'remote-span', commands) - if shutdown == 'enabled': - self.add_command_to_config_list(vlan, 'shutdown', commands) - elif shutdown == 'disabled': - self.add_command_to_config_list(vlan, 'no shutdown', commands) - - return commands - - def _clear_config(self, want, have, state): - # Delete the interface config based on the want and have config - commands = [] - vlan = 'vlan {0}'.format(have.get('vlan_id')) - - if have.get('vlan_id') and 'default' not in have.get('name')\ - and (have.get('vlan_id') != want.get('vlan_id') or state == 'deleted'): - self.remove_command_from_config_list(vlan, 'vlan', commands) - elif 'default' not in have.get('name'): - if have.get('mtu') != want.get('mtu'): - self.remove_command_from_config_list(vlan, 'mtu', commands) - if have.get('remote_span') != want.get('remote_span') and want.get('remote_span'): - self.remove_command_from_config_list(vlan, 'remote-span', commands) - if have.get('shutdown') != want.get('shutdown') and want.get('shutdown'): - self.remove_command_from_config_list(vlan, 'shutdown', commands) - if have.get('state') != want.get('state') and want.get('state'): - self.remove_command_from_config_list(vlan, 'state', commands) - - return commands diff --git a/lib/ansible/module_utils/network/ios/facts/acl_interfaces/acl_interfaces.py b/lib/ansible/module_utils/network/ios/facts/acl_interfaces/acl_interfaces.py deleted file mode 100644 index c80939aeba5..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/acl_interfaces/acl_interfaces.py +++ /dev/null @@ -1,122 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_acl_interfaces fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -import re -from copy import deepcopy - -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.ios.utils.utils import get_interface_type -from ansible.module_utils.network.ios.argspec.acl_interfaces.acl_interfaces import Acl_InterfacesArgs - - -class Acl_InterfacesFacts(object): - """ The ios_acl_interfaces fact class - """ - - def __init__(self, module, subspec='config', options='options'): - self._module = module - self.argument_spec = Acl_InterfacesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def get_acl_interfaces_data(self, connection): - return connection.get('sh running-config | include interface|ip access-group|ipv6 traffic-filter') - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for interfaces - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - objs = [] - - if not data: - data = self.get_acl_interfaces_data(connection) - # operate on a collection of resource x - config = data.split('interface ') - for conf in config: - if conf: - obj = self.render_config(self.generated_spec, conf) - if obj: - objs.append(obj) - - facts = {} - if objs: - facts['acl_interfaces'] = [] - params = utils.validate_config(self.argument_spec, {'config': objs}) - - for cfg in params['config']: - facts['acl_interfaces'].append(utils.remove_empties(cfg)) - ansible_facts['ansible_network_resources'].update(facts) - - return ansible_facts - - def render_config(self, spec, conf): - """ - Render config as dictionary structure and delete keys - from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - config = deepcopy(spec) - match = re.search(r'^(\S+)', conf) - intf = match.group(1) - - if get_interface_type(intf) == 'unknown': - return {} - config['name'] = intf - config['access_groups'] = [] - acl_v4_config = {} - acl_v6_config = {} - - def common_iter_code(cmd, conf): - # Common code for IPV4 and IPV6 config parsing - acls = [] - re_cmd = cmd + ' (\\S+.*)' - ip_all = re.findall(re_cmd, conf) - for each in ip_all: - acl = {} - access_grp_config = each.split(' ') - acl['name'] = access_grp_config[0] - acl['direction'] = access_grp_config[1] - acls.append(acl) - return acls - - if 'ip' in conf: - acls = common_iter_code('ip access-group', conf) - acl_v4_config['afi'] = 'ipv4' - acl_v4_config['acls'] = acls - config['access_groups'].append(acl_v4_config) - if 'ipv6' in conf: - acls = common_iter_code('ipv6 traffic-filter', conf) - acl_v6_config['afi'] = 'ipv6' - acl_v6_config['acls'] = acls - config['access_groups'].append(acl_v6_config) - - return utils.remove_empties(config) diff --git a/lib/ansible/module_utils/network/ios/facts/acls/acls.py b/lib/ansible/module_utils/network/ios/facts/acls/acls.py deleted file mode 100644 index 3b99a18f5cb..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/acls/acls.py +++ /dev/null @@ -1,498 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_acls fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from copy import deepcopy -import re -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.ios.utils.utils import check_n_return_valid_ipv6_addr -from ansible.module_utils.network.ios.argspec.acls.acls import AclsArgs - - -class AclsFacts(object): - """ The ios_acls fact class - """ - - def __init__(self, module, subspec='config', options='options'): - - self._module = module - self.argument_spec = AclsArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def get_acl_data(self, connection): - # Get the access-lists from the ios router - return connection.get('sh access-list') - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for acls - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - - if not data: - data = self.get_acl_data(connection) - # operate on a collection of resource x - config = data.split('\n') - spec = {'acls': list(), 'afi': None} - if config: - objs = self.render_config(spec, config) - # check if rendered config list has only empty dict - if len(objs) == 1 and objs[0] == {}: - objs = [] - facts = {} - - if objs: - facts['acls'] = [] - params = utils.validate_config(self.argument_spec, {'config': objs}) - for cfg in params['config']: - facts['acls'].append(utils.remove_empties(cfg)) - ansible_facts['ansible_network_resources'].update(facts) - - return ansible_facts - - def create_config_dict(self, config): - """ Function that parse the acls config and convert to module usable config - :param config: config - :rtype: A dict - :returns: the config generated based on have config params - """ - conf = {} - temp_list = [] - access_list_name = '' - count = 0 - if len(config) >= 1 and config[0] != '': - for each in config: - if 'access-list' in each: - temp = each.split('access-list ')[1].split(' ')[0] - if temp == 'extended' or temp == 'standard': - temp = each.split('access-list ')[1] - if not access_list_name: - access_list_name = temp - if 'access-list' not in each: - if 'extended' in temp or 'standard' in temp: - temp_list.append('ipv4 access-list ' + temp + each) - else: - temp_list.append('ipv6 access-list ' + temp + each) - if temp == access_list_name and 'access-list' in each and \ - not ('extended' in access_list_name or 'standard' in access_list_name): - temp_list.append(each) - elif temp != access_list_name: - conf[access_list_name] = temp_list - temp_list = list() - if 'permit' in each or 'deny' in each: - temp_list.append(each) - access_list_name = temp - count += 1 - if len(config) == count: - conf[access_list_name] = temp_list - temp_list = [] - return conf - - def populate_port_protocol(self, source, destination, each_list): - """ Function Populates port portocol wrt to source and destination - :param acls: source config - :param config: destination config - :param each_list: config - :rtype: A list - :returns: the commands generated based on source and destination params - """ - operators = ['eq', 'gt', 'lt', 'neq', 'range'] - for item in operators: - if item in each_list: - index = each_list.index(item) - if source.get('address') or source.get('any') or source.get('host') and not source.get('port_protocol'): - try: - source_index = each_list.index(source.get('address')) - except ValueError: - try: - source_index = each_list.index('any') - except ValueError: - source_index = each_list.index('host') - if source.get('address'): - if (source_index + 2) == index and 'ipv6' not in each_list: - source['port_protocol'] = {item: each_list[index + 1]} - each_list.remove(item) - del each_list[index] - elif (source_index + 1) == index and 'ipv6' in each_list: - source['port_protocol'] = {item: each_list[index + 1]} - each_list.remove(item) - del each_list[source_index] - del each_list[index - 1] - elif source.get('any'): - if (source_index + 1) == index: - source['port_protocol'] = {item: each_list[index + 1]} - each_list.remove(item) - del each_list[index - 1] - del each_list[source_index] - elif source.get('host'): - if (source_index + 1) == index: - source['port_protocol'] = {item: each_list[index + 1]} - each_list.remove(item) - del each_list[index - 1] - del each_list[source_index] - if destination.get('address') or destination.get('any') or destination.get('host'): - try: - destination_index = each_list.index(destination.get('address')) - except ValueError: - try: - destination_index = each_list.index('any') - except ValueError: - destination_index = each_list.index('host') + 1 - index -= 1 - if (destination_index + 1) == index or (destination_index + 2) == index: - destination['port_protocol'] = {item: each_list[index + 1]} - each_list.remove(item) - del each_list[index] - break - if 'eq' in each_list or 'gt' in each_list or 'lt' in each_list or 'neq' in each_list or 'range' in each_list: - self.populate_port_protocol(source, destination, each_list) - - def populate_source_destination(self, each, config, source, destination): - any = [] - if 'any' in each: - any = re.findall('any', each) - if len(any) == 2: - source['any'] = True - destination['any'] = True - elif 'host' in each: - host = re.findall('host', each) - each = each.split(' ') - if len(host) == 2: - host_index = each.index('host') - source['host'] = each[host_index + 1] - del each[host_index] - host_index = each.index('host') - destination['host'] = each[host_index + 1] - else: - ip_n_wildcard_bits = re.findall(r'[0-9]+(?:\.[0-9]+){3}', each) - ip_index = None - if ip_n_wildcard_bits: - ip_index = each.index(ip_n_wildcard_bits[0]) - host_index = each.index('host') - if ip_index: - if host_index < ip_index: - source['host'] = each(host_index + 1) - destination['address'] = ip_n_wildcard_bits[0] - destination['wildcard_bits'] = ip_n_wildcard_bits[1] - elif host_index > ip_index: - destination['host'] = each(host_index + 1) - source['address'] = ip_n_wildcard_bits[0] - source['wildcard_bits'] = ip_n_wildcard_bits[1] - else: - if config['afi'] == 'ipv4': - ip_n_wildcard_bits = re.findall(r'[0-9]+(?:\.[0-9]+){3}', each) - each = each.split(' ') - if len(ip_n_wildcard_bits) == 0 and len(any) == 1: - source['any'] = True - elif len(ip_n_wildcard_bits) == 1: - source['address'] = ip_n_wildcard_bits[0] - elif len(ip_n_wildcard_bits) == 2: - if 'any' in each: - if each.index('any') > each.index(ip_n_wildcard_bits[0]): - source['address'] = ip_n_wildcard_bits[0] - source['wildcard_bits'] = ip_n_wildcard_bits[1] - destination['any'] = True - elif each.index('any') < each.index(ip_n_wildcard_bits[0]): - source['any'] = True - destination['address'] = ip_n_wildcard_bits[0] - destination['wildcard_bits'] = ip_n_wildcard_bits[1] - else: - source['address'] = ip_n_wildcard_bits[0] - source['wildcard_bits'] = ip_n_wildcard_bits[1] - elif len(ip_n_wildcard_bits) == 4: - source['address'] = ip_n_wildcard_bits[0] - source['wildcard_bits'] = ip_n_wildcard_bits[1] - destination['address'] = ip_n_wildcard_bits[2] - destination['wildcard_bits'] = ip_n_wildcard_bits[3] - elif config['afi'] == 'ipv6': - temp_ipv6 = [] - each = each.split(' ') - check_n_return_valid_ipv6_addr(self._module, each, temp_ipv6) - count = 0 - for every in each: - if len(temp_ipv6) == 2: - if temp_ipv6[0] in every or temp_ipv6[1] in every: - temp_ipv6[count] = every - count += 1 - elif len(temp_ipv6) == 1: - if temp_ipv6[0] in every: - temp_ipv6[count] = every - if 'any' in each: - if each.index('any') > each.index(temp_ipv6[0]): - source['address'] = temp_ipv6[0] - destination['any'] = True - elif each.index('any') < each.index(temp_ipv6[0]): - source['any'] = True - destination['address'] = temp_ipv6[0] - elif len(temp_ipv6) == 2: - source['address'] = temp_ipv6[0] - destination['address'] = temp_ipv6[1] - - def parsed_config_facts(self, have_config): - """ - For parsed config have_config is string of commands which - need to be splitted before passing it through render_config - from spec for null values - :param have_config: The configuration - :rtype: list of have config - :returns: The splitted generated config - """ - split_config = re.split('ip|ipv6 access-list', have_config[0]) - temp_config = [] - - # common piece of code for populating the temp_config list - def common_config_code(each, grant, temp_config): - temp = re.split(grant, each) - temp_config.append(temp[0]) - temp_config.extend([grant + item for item in temp if 'access-list' not in item]) - - for each in split_config: - if 'v6' in each: - each = 'ipv6 ' + each.split('v6 ')[1] - if 'permit' in each: - common_config_code(each, 'permit', temp_config) - elif 'deny' in each: - common_config_code(each, 'deny', temp_config) - else: - each = 'ip' + each - if 'permit' in each: - common_config_code(each, 'permit', temp_config) - if 'deny' in each: - common_config_code(each, 'deny', temp_config) - return temp_config - - def render_config(self, spec, have_config): - """ - Render config as dictionary structure and delete keys - from spec for null values - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - - # for parsed scnenario where commands are passed to generate the acls facts - if len(have_config) == 1: - have_config = self.parsed_config_facts(have_config) - - config = deepcopy(spec) - render_config = list() - acls = dict() - aces = list() - temp_name = '' - for each in have_config: - each_list = [val for val in each.split(' ') if val != ''] - if 'IPv6' in each or 'ipv6' in each: - if aces: - config['acls'].append(acls) - ip_config = config - if ip_config.get('acls'): - render_config.append(ip_config) - if not config['afi'] or config['afi'] == 'ipv4': - config = deepcopy(spec) - config['afi'] = 'ipv6' - acls = dict() - aces = list() - elif not config['afi'] and ('IP' in each or 'ip' in each): - config['afi'] = 'ipv4' - if 'access list' in each or 'access-list' in each: - try: - temp_index = each_list.index('list') - name = (each_list[temp_index + 1]) - except ValueError: - name = each_list[-1] - if temp_name != name: - if aces: - config['acls'].append(acls) - acls = dict() - aces = list() - temp_name = name - acls['name'] = name - if 'Extended' in each: - acls['acl_type'] = 'extended' - continue - elif 'Standard' in each: - acls['acl_type'] = 'standard' - continue - ace_options = {} - try: - if config['afi'] == 'ipv4': - if 'deny' in each_list or 'permit' in each_list: - ace_options['sequence'] = int(each_list[0]) - elif config['afi'] == 'ipv6': - if 'sequence' in each_list: - ace_options['sequence'] = int(each_list[each_list.index('sequence') + 1]) - except ValueError: - pass - if utils.parse_conf_arg(each, 'permit'): - ace_options['grant'] = 'permit' - each_list.remove('permit') - elif utils.parse_conf_arg(each, 'deny'): - ace_options['grant'] = 'deny' - each_list.remove('deny') - - protocol_option = ['ahp', 'eigrp', 'esp', 'gre', 'hbh', 'icmp', 'igmp', 'ip', 'ipv6', 'ipinip', 'nos', - 'ospf', 'pcp', 'pim', 'sctp', 'tcp', 'udp'] - tcp_flags = ['ack', 'established', 'fin', 'psh', 'rst', 'syn', 'urg'] - icmp_options = ['administratively_prohibited', 'alternate_address', 'conversion_error', - 'dod_host_prohibited', 'dod_net_prohibited', 'echo', 'echo_reply', - 'general_parameter_problem', 'host_isolated', 'host_precedence_unreachable', - 'host_redirect', 'host_tos_redirect', 'host_tos_unreachable', 'host_unknown', - 'host_unreachable', 'information_reply', 'information_request', 'mask_reply', - 'mask_request', 'mobile_redirect', 'net_redirect', 'net_tos_redirect', - 'net_tos_unreachable', 'net_unreachable', 'network_unknown', 'no_room_for_option', - 'option_missing', 'packet_too_big', 'parameter_problem', 'port_unreachable', - 'precedence_unreachable', 'protocol_unreachable', 'reassembly_timeout', 'redirect', - 'router_advertisement', 'router_solicitation', 'source_quench', 'source_route_failed', - 'time_exceeded', 'timestamp_reply', 'timestamp_request', 'traceroute', 'ttl_exceeded', - 'unreachable'] - igmp_options = ['dvmrp', 'host_query', 'mtrace_resp', 'mtrace_route', 'pim', 'trace', 'v1host_report', - 'v2host_report', 'v2leave_group', 'v3host_report'] - - temp_option = '' - for option in protocol_option: - if option in each_list and 'access' not in each_list[each_list.index(option) + 1]: - temp_option = option - each_list.remove(temp_option) - if temp_option == 'tcp': - temp_flag = [each_flag for each_flag in tcp_flags if each_flag in each] - if temp_flag: - flag = temp_flag[0] - if flag in each_list: - each_list.remove(flag) - temp_flag = flag - if temp_option == 'icmp': - temp_flag = [each_option for each_option in icmp_options if each_option in each] - if temp_flag: - flag = temp_flag[0] - if flag in each_list: - each_list.remove(flag) - temp_flag = flag - if temp_option == 'igmp': - temp_flag = [each_option for each_option in igmp_options if each_option in each] - if temp_flag: - flag = temp_flag[0] - if flag in each_list: - each_list.remove(flag) - temp_flag = flag - break - - dscp = utils.parse_conf_arg(each, 'dscp') - if dscp: - ace_options['dscp'] = dscp.split(' ')[0] - fragments = utils.parse_conf_arg(each, 'fragments') - if fragments: - ace_options['fragments'] = fragments.split(' ')[0] - log = utils.parse_conf_arg(each, 'log') - if log: - ace_options['log'] = log.split(' ')[0] - log_input = utils.parse_conf_arg(each, 'log_input') - if log_input: - ace_options['log_input'] = log_input.split(' ')[0] - option = utils.parse_conf_arg(each, 'option') - if option: - option = option.split(' ')[0] - option_dict = {} - option_dict[option] = True - ace_options['option'] = option_dict - precedence = utils.parse_conf_arg(each, 'precedence') - if precedence: - ace_options['precedence'] = precedence.split(' ')[0] - time_range = utils.parse_conf_arg(each, 'time_range') - if time_range: - ace_options['time_range'] = time_range.split(' ')[0] - tos = utils.parse_conf_arg(each, 'tos') - if tos: - tos_val = dict() - try: - tos_val['service_value'] = int(tos) - except ValueError: - tos = tos.replace('-', '_') - tos_val[tos] = True - ace_options['tos'] = tos_val - ttl = utils.parse_conf_arg(each, 'ttl') - if ttl: - temp_ttl = ttl.split(' ') - ttl = {} - ttl[temp_ttl[0]] = temp_ttl[1] - each_list = [item for item in each_list[:each_list.index('ttl')]] - ace_options['ttl'] = ttl - - source = {} - destination = {} - self.populate_source_destination(each, config, source, destination) - - if source.get('address') and source.get('address') == destination.get('address'): - self._module.fail_json(msg='Source and Destination address cannot be same!') - else: - self.populate_port_protocol(source, destination, each_list) - - if source: - ace_options['source'] = source - if destination: - ace_options['destination'] = destination - if temp_option: - protocol_options = {} - ace_options['protocol'] = temp_option - if temp_option == 'tcp': - tcp = {} - if temp_flag: - tcp[temp_flag] = True - else: - tcp['set'] = True - protocol_options[temp_option] = tcp - elif temp_option == 'icmp': - icmp = dict() - if temp_flag: - icmp[temp_flag] = True - else: - icmp['set'] = True - protocol_options[temp_option] = icmp - elif temp_option == 'igmp': - igmp = dict() - if temp_flag: - igmp[temp_flag] = True - else: - igmp['set'] = True - protocol_options[temp_option] = igmp - else: - protocol_options[temp_option] = True - ace_options['protocol_options'] = protocol_options - if ace_options: - aces.append(ace_options) - acls['aces'] = aces - if acls: - if not config.get('acls'): - config['acls'] = list() - config['acls'].append(acls) - - if config not in render_config: - render_config.append(utils.remove_empties(config)) - # delete the populated config - del config - - return render_config diff --git a/lib/ansible/module_utils/network/ios/facts/facts.py b/lib/ansible/module_utils/network/ios/facts/facts.py deleted file mode 100644 index 8d66e87963d..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/facts.py +++ /dev/null @@ -1,79 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The facts class for ios -this file validates each subset of facts and selectively -calls the appropriate facts gathering function -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from ansible.module_utils.network.common.facts.facts import FactsBase -from ansible.module_utils.network.ios.facts.interfaces.interfaces import InterfacesFacts -from ansible.module_utils.network.ios.facts.l2_interfaces.l2_interfaces import L2_InterfacesFacts -from ansible.module_utils.network.ios.facts.vlans.vlans import VlansFacts -from ansible.module_utils.network.ios.facts.lag_interfaces.lag_interfaces import Lag_interfacesFacts -from ansible.module_utils.network.ios.facts.lacp.lacp import LacpFacts -from ansible.module_utils.network.ios.facts.lacp_interfaces.lacp_interfaces import Lacp_InterfacesFacts -from ansible.module_utils.network.ios.facts.lldp_global.lldp_global import Lldp_globalFacts -from ansible.module_utils.network.ios.facts.lldp_interfaces.lldp_interfaces import Lldp_InterfacesFacts -from ansible.module_utils.network.ios.facts.l3_interfaces.l3_interfaces import L3_InterfacesFacts -from ansible.module_utils.network.ios.facts.acl_interfaces.acl_interfaces import Acl_InterfacesFacts -from ansible.module_utils.network.ios.facts.static_routes.static_routes import Static_RoutesFacts -from ansible.module_utils.network.ios.facts.acls.acls import AclsFacts -from ansible.module_utils.network.ios.facts.legacy.base import Default, Hardware, Interfaces, Config - - -FACT_LEGACY_SUBSETS = dict( - default=Default, - hardware=Hardware, - interfaces=Interfaces, - config=Config -) - -FACT_RESOURCE_SUBSETS = dict( - interfaces=InterfacesFacts, - l2_interfaces=L2_InterfacesFacts, - vlans=VlansFacts, - lag_interfaces=Lag_interfacesFacts, - lacp=LacpFacts, - lacp_interfaces=Lacp_InterfacesFacts, - lldp_global=Lldp_globalFacts, - lldp_interfaces=Lldp_InterfacesFacts, - l3_interfaces=L3_InterfacesFacts, - acl_interfaces=Acl_InterfacesFacts, - static_routes=Static_RoutesFacts, - acls=AclsFacts, -) - - -class Facts(FactsBase): - """ The fact class for ios - """ - - VALID_LEGACY_GATHER_SUBSETS = frozenset(FACT_LEGACY_SUBSETS.keys()) - VALID_RESOURCE_SUBSETS = frozenset(FACT_RESOURCE_SUBSETS.keys()) - - def __init__(self, module): - super(Facts, self).__init__(module) - - def get_facts(self, legacy_facts_type=None, resource_facts_type=None, data=None): - """ Collect the facts for ios - :param legacy_facts_type: List of legacy facts types - :param resource_facts_type: List of resource fact types - :param data: previously collected conf - :rtype: dict - :return: the facts gathered - """ - if self.VALID_RESOURCE_SUBSETS: - self.get_network_resources_facts(FACT_RESOURCE_SUBSETS, resource_facts_type, data) - - if self.VALID_LEGACY_GATHER_SUBSETS: - self.get_network_legacy_facts(FACT_LEGACY_SUBSETS, legacy_facts_type) - - return self.ansible_facts, self._warnings diff --git a/lib/ansible/module_utils/network/ios/facts/interfaces/interfaces.py b/lib/ansible/module_utils/network/ios/facts/interfaces/interfaces.py deleted file mode 100644 index a6802bd2e84..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/interfaces/interfaces.py +++ /dev/null @@ -1,97 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios interfaces fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from copy import deepcopy -import re -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.ios.utils.utils import get_interface_type, normalize_interface -from ansible.module_utils.network.ios.argspec.interfaces.interfaces import InterfacesArgs - - -class InterfacesFacts(object): - """ The ios interfaces fact class - """ - - def __init__(self, module, subspec='config', options='options'): - self._module = module - self.argument_spec = InterfacesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for interfaces - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - objs = [] - - if not data: - data = connection.get('show running-config | section ^interface') - # operate on a collection of resource x - config = data.split('interface ') - for conf in config: - if conf: - obj = self.render_config(self.generated_spec, conf) - if obj: - objs.append(obj) - facts = {} - - if objs: - facts['interfaces'] = [] - params = utils.validate_config(self.argument_spec, {'config': objs}) - for cfg in params['config']: - facts['interfaces'].append(utils.remove_empties(cfg)) - ansible_facts['ansible_network_resources'].update(facts) - - return ansible_facts - - def render_config(self, spec, conf): - """ - Render config as dictionary structure and delete keys from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - config = deepcopy(spec) - match = re.search(r'^(\S+)', conf) - intf = match.group(1) - - if get_interface_type(intf) == 'unknown': - return {} - # populate the facts from the configuration - config['name'] = normalize_interface(intf) - config['description'] = utils.parse_conf_arg(conf, 'description') - config['speed'] = utils.parse_conf_arg(conf, 'speed') - if utils.parse_conf_arg(conf, 'mtu'): - config['mtu'] = int(utils.parse_conf_arg(conf, 'mtu')) - config['duplex'] = utils.parse_conf_arg(conf, 'duplex') - enabled = utils.parse_conf_cmd_arg(conf, 'shutdown', False) - config['enabled'] = enabled if enabled is not None else True - - return utils.remove_empties(config) diff --git a/lib/ansible/module_utils/network/ios/facts/l2_interfaces/l2_interfaces.py b/lib/ansible/module_utils/network/ios/facts/l2_interfaces/l2_interfaces.py deleted file mode 100644 index 8f6ddf2698d..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/l2_interfaces/l2_interfaces.py +++ /dev/null @@ -1,114 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios interfaces fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -from copy import deepcopy -import re -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.ios.utils.utils import get_interface_type, normalize_interface -from ansible.module_utils.network.ios.argspec.l2_interfaces.l2_interfaces import L2_InterfacesArgs - - -class L2_InterfacesFacts(object): - """ The ios l2 interfaces fact class - """ - - def __init__(self, module, subspec='config', options='options'): - self._module = module - self.argument_spec = L2_InterfacesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for interfaces - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - objs = [] - - if not data: - data = connection.get('show running-config | section ^interface') - # operate on a collection of resource x - config = data.split('interface ') - for conf in config: - if conf: - obj = self.render_config(self.generated_spec, conf) - if obj: - objs.append(obj) - - facts = {} - if objs: - facts['l2_interfaces'] = [] - params = utils.validate_config(self.argument_spec, {'config': objs}) - for cfg in params['config']: - facts['l2_interfaces'].append(utils.remove_empties(cfg)) - ansible_facts['ansible_network_resources'].update(facts) - - return ansible_facts - - def render_config(self, spec, conf): - """ - Render config as dictionary structure and delete keys from spec for null values - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - config = deepcopy(spec) - match = re.search(r'^(\S+)', conf) - intf = match.group(1) - - if get_interface_type(intf) == 'unknown': - return {} - - if intf.upper()[:2] in ('HU', 'FO', 'TW', 'TE', 'GI', 'FA', 'ET', 'PO'): - # populate the facts from the configuration - config['name'] = normalize_interface(intf) - has_mode = utils.parse_conf_arg(conf, 'switchport mode') - if has_mode: - config['mode'] = has_mode - has_access = utils.parse_conf_arg(conf, 'switchport access vlan') - if has_access: - config["access"] = {"vlan": int(has_access)} - - has_voice = utils.parse_conf_arg(conf, 'switchport voice vlan') - if has_voice: - config["voice"] = {"vlan": int(has_voice)} - - trunk = dict() - trunk["encapsulation"] = utils.parse_conf_arg(conf, 'encapsulation') - native_vlan = utils.parse_conf_arg(conf, 'native vlan') - if native_vlan: - trunk["native_vlan"] = int(native_vlan) - allowed_vlan = utils.parse_conf_arg(conf, 'allowed vlan') - if allowed_vlan: - trunk["allowed_vlans"] = allowed_vlan.split(',') - pruning_vlan = utils.parse_conf_arg(conf, 'pruning vlan') - if pruning_vlan: - trunk['pruning_vlans'] = pruning_vlan.split(',') - - config['trunk'] = trunk - - return utils.remove_empties(config) diff --git a/lib/ansible/module_utils/network/ios/facts/l3_interfaces/l3_interfaces.py b/lib/ansible/module_utils/network/ios/facts/l3_interfaces/l3_interfaces.py deleted file mode 100644 index 5afab57b372..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/l3_interfaces/l3_interfaces.py +++ /dev/null @@ -1,124 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_l3_interfaces fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from copy import deepcopy -import re -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.ios.utils.utils import get_interface_type, normalize_interface -from ansible.module_utils.network.ios.argspec.l3_interfaces.l3_interfaces import L3_InterfacesArgs - - -class L3_InterfacesFacts(object): - """ The ios l3 interfaces fact class - """ - - def __init__(self, module, subspec='config', options='options'): - self._module = module - self.argument_spec = L3_InterfacesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for l3 interfaces - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - objs = [] - - if not data: - data = connection.get('show running-config | section ^interface') - # operate on a collection of resource x - config = data.split('interface ') - for conf in config: - if conf: - obj = self.render_config(self.generated_spec, conf) - if obj: - objs.append(obj) - facts = {} - - if objs: - facts['l3_interfaces'] = [] - params = utils.validate_config(self.argument_spec, {'config': objs}) - for cfg in params['config']: - facts['l3_interfaces'].append(utils.remove_empties(cfg)) - ansible_facts['ansible_network_resources'].update(facts) - - return ansible_facts - - def render_config(self, spec, conf): - """ - Render config as dictionary structure and delete keys from spec for null values - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - config = deepcopy(spec) - match = re.search(r'^(\S+)', conf) - intf = match.group(1) - - if get_interface_type(intf) == 'unknown': - return {} - # populate the facts from the configuration - config['name'] = normalize_interface(intf) - - ipv4 = [] - ipv4_all = re.findall(r"ip address (\S+.*)", conf) - for each in ipv4_all: - each_ipv4 = dict() - if 'secondary' not in each and 'dhcp' not in each: - each_ipv4['address'] = each - elif 'secondary' in each: - each_ipv4['address'] = each.split(' secondary')[0] - each_ipv4['secondary'] = True - elif 'dhcp' in each: - each_ipv4['address'] = 'dhcp' - if 'client-id' in each: - each_ipv4['dhcp_client'] = int(each.split(' hostname ')[0].split('/')[-1]) - if 'hostname' in each: - each_ipv4["dhcp_hostname"] = each.split(' hostname ')[-1] - if 'client-id' in each and each_ipv4['dhcp_client'] is None: - each_ipv4['dhcp_client'] = int(each.split('/')[-1]) - if 'hostname' in each and not each_ipv4["dhcp_hostname"]: - each_ipv4["dhcp_hostname"] = each.split(' hostname ')[-1] - ipv4.append(each_ipv4) - config['ipv4'] = ipv4 - - # Get the configured IPV6 details - ipv6 = [] - ipv6_all = re.findall(r"ipv6 address (\S+)", conf) - for each in ipv6_all: - each_ipv6 = dict() - if 'autoconfig' in each: - each_ipv6['autoconfig'] = True - if 'dhcp' in each: - each_ipv6['dhcp'] = True - each_ipv6['address'] = each.lower() - ipv6.append(each_ipv6) - config['ipv6'] = ipv6 - - return utils.remove_empties(config) diff --git a/lib/ansible/module_utils/network/ios/facts/lacp/lacp.py b/lib/ansible/module_utils/network/ios/facts/lacp/lacp.py deleted file mode 100644 index 455460fc941..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/lacp/lacp.py +++ /dev/null @@ -1,83 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios lacp fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from copy import deepcopy -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.ios.argspec.lacp.lacp import LacpArgs - - -class LacpFacts(object): - """ The ios lacp fact class - """ - - def __init__(self, module, subspec='config', options='options'): - self._module = module - self.argument_spec = LacpArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for lacp - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - if connection: - pass - - if not data: - data = connection.get('show lacp sys-id') - - obj = {} - if data: - lacp_obj = self.render_config(self.generated_spec, data) - if lacp_obj: - obj = lacp_obj - - ansible_facts['ansible_network_resources'].pop('lacp', None) - facts = {} - - params = utils.validate_config(self.argument_spec, {'config': obj}) - facts['lacp'] = utils.remove_empties(params['config']) - ansible_facts['ansible_network_resources'].update(facts) - - return ansible_facts - - def render_config(self, spec, conf): - """ - Render config as dictionary structure and delete keys - from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - config = deepcopy(spec) - - config['system']['priority'] = int(conf.split(',')[0]) - - return utils.remove_empties(config) diff --git a/lib/ansible/module_utils/network/ios/facts/lacp_interfaces/lacp_interfaces.py b/lib/ansible/module_utils/network/ios/facts/lacp_interfaces/lacp_interfaces.py deleted file mode 100644 index 722557e2694..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/lacp_interfaces/lacp_interfaces.py +++ /dev/null @@ -1,102 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_lacp_interfaces fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -import re -from copy import deepcopy -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.ios.utils.utils import get_interface_type, normalize_interface -from ansible.module_utils.network.ios.argspec.lacp_interfaces.lacp_interfaces import Lacp_InterfacesArgs - - -class Lacp_InterfacesFacts(object): - """ The ios_lacp_interfaces fact class - """ - - def __init__(self, module, subspec='config', options='options'): - - self._module = module - self.argument_spec = Lacp_InterfacesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for lacp_interfaces - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - if connection: - pass - - objs = [] - if not data: - data = connection.get('show running-config | section ^interface') - # operate on a collection of resource x - config = data.split('interface ') - - for conf in config: - if conf: - obj = self.render_config(self.generated_spec, conf) - if obj: - objs.append(obj) - facts = {} - - if objs: - facts['lacp_interfaces'] = [] - params = utils.validate_config(self.argument_spec, {'config': objs}) - for cfg in params['config']: - facts['lacp_interfaces'].append(utils.remove_empties(cfg)) - ansible_facts['ansible_network_resources'].update(facts) - - return ansible_facts - - def render_config(self, spec, conf): - """ - Render config as dictionary structure and delete keys - from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - config = deepcopy(spec) - match = re.search(r'^(\S+)', conf) - intf = match.group(1) - if get_interface_type(intf) == 'unknown': - return {} - - config['name'] = normalize_interface(intf) - port_priority = utils.parse_conf_arg(conf, 'lacp port-priority') - max_bundle = utils.parse_conf_arg(conf, 'lacp max-bundle') - if port_priority: - config['port_priority'] = int(port_priority) - if 'lacp fast-switchover' in conf: - config['fast_switchover'] = True - if max_bundle: - config['max_bundle'] = int(max_bundle) - - return utils.remove_empties(config) diff --git a/lib/ansible/module_utils/network/ios/facts/lag_interfaces/lag_interfaces.py b/lib/ansible/module_utils/network/ios/facts/lag_interfaces/lag_interfaces.py deleted file mode 100644 index e396bb0b511..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/lag_interfaces/lag_interfaces.py +++ /dev/null @@ -1,118 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios lag_interfaces fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -import re -from copy import deepcopy - -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.ios.utils.utils import get_interface_type, normalize_interface -from ansible.module_utils.network.ios.argspec.lag_interfaces.lag_interfaces import Lag_interfacesArgs - - -class Lag_interfacesFacts(object): - """ The ios_lag_interfaces fact class - """ - - def __init__(self, module, subspec='config', options='options'): - self._module = module - self.argument_spec = Lag_interfacesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for interfaces - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - objs = [] - - if not data: - data = connection.get('show running-config | section ^interface') - # operate on a collection of resource x - config = data.split('interface ') - for conf in config: - if conf: - obj = self.render_config(self.generated_spec, conf) - if obj: - if not obj.get('members'): - obj.update({'members': []}) - objs.append(obj) - - # for appending members configured with same channel-group - for each in range(len(objs)): - if each < (len(objs) - 1): - if objs[each]['name'] == objs[each + 1]['name']: - objs[each]['members'].append(objs[each + 1]['members'][0]) - del objs[each + 1] - facts = {} - - if objs: - facts['lag_interfaces'] = [] - params = utils.validate_config(self.argument_spec, {'config': objs}) - - for cfg in params['config']: - facts['lag_interfaces'].append(utils.remove_empties(cfg)) - ansible_facts['ansible_network_resources'].update(facts) - - return ansible_facts - - def render_config(self, spec, conf): - """ - Render config as dictionary structure and delete keys - from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - config = deepcopy(spec) - match = re.search(r'^(\S+)', conf) - intf = match.group(1) - - if get_interface_type(intf) == 'unknown': - return {} - member_config = {} - channel_group = utils.parse_conf_arg(conf, 'channel-group') - if intf.startswith('Gi'): - config['name'] = intf - config['members'] = [] - if channel_group: - channel_group = channel_group.split(' ') - id = channel_group[0] - config['name'] = 'Port-channel{0}'.format(str(id)) - if 'mode' in channel_group: - mode = channel_group[2] - member_config.update({'mode': mode}) - if 'link' in channel_group: - link = channel_group[2] - member_config.update({'link': link}) - if member_config.get('mode') or member_config.get('link'): - member_config['member'] = normalize_interface(intf) - config['members'].append(member_config) - - return utils.remove_empties(config) diff --git a/lib/ansible/module_utils/network/ios/facts/legacy/base.py b/lib/ansible/module_utils/network/ios/facts/legacy/base.py deleted file mode 100644 index 75a7e9974df..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/legacy/base.py +++ /dev/null @@ -1,380 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -""" -The ios legacy fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -import platform -import re - -from ansible.module_utils.network.ios.ios import run_commands, get_capabilities -from ansible.module_utils.network.ios.ios import normalize_interface -from ansible.module_utils.six import iteritems -from ansible.module_utils.six.moves import zip - - -class FactsBase(object): - - COMMANDS = list() - - def __init__(self, module): - self.module = module - self.facts = dict() - self.warnings = list() - self.responses = None - - def populate(self): - self.responses = run_commands(self.module, commands=self.COMMANDS, check_rc=False) - - def run(self, cmd): - return run_commands(self.module, commands=cmd, check_rc=False) - - -class Default(FactsBase): - - COMMANDS = ['show version'] - - def populate(self): - super(Default, self).populate() - self.facts.update(self.platform_facts()) - data = self.responses[0] - if data: - self.facts['iostype'] = self.parse_iostype(data) - self.facts['serialnum'] = self.parse_serialnum(data) - self.parse_stacks(data) - - def parse_iostype(self, data): - match = re.search(r'\S+(X86_64_LINUX_IOSD-UNIVERSALK9-M)(\S+)', data) - if match: - return "IOS-XE" - else: - return "IOS" - - def parse_serialnum(self, data): - match = re.search(r'board ID (\S+)', data) - if match: - return match.group(1) - - def parse_stacks(self, data): - match = re.findall(r'^Model [Nn]umber\s+: (\S+)', data, re.M) - if match: - self.facts['stacked_models'] = match - - match = re.findall(r'^System [Ss]erial [Nn]umber\s+: (\S+)', data, re.M) - if match: - self.facts['stacked_serialnums'] = match - - def platform_facts(self): - platform_facts = {} - - resp = get_capabilities(self.module) - device_info = resp['device_info'] - - platform_facts['system'] = device_info['network_os'] - - for item in ('model', 'image', 'version', 'platform', 'hostname'): - val = device_info.get('network_os_%s' % item) - if val: - platform_facts[item] = val - - platform_facts['api'] = resp['network_api'] - platform_facts['python_version'] = platform.python_version() - - return platform_facts - - -class Hardware(FactsBase): - - COMMANDS = [ - 'dir', - 'show memory statistics' - ] - - def populate(self): - warnings = list() - super(Hardware, self).populate() - data = self.responses[0] - if data: - self.facts['filesystems'] = self.parse_filesystems(data) - self.facts['filesystems_info'] = self.parse_filesystems_info(data) - - data = self.responses[1] - if data: - if 'Invalid input detected' in data: - warnings.append('Unable to gather memory statistics') - else: - processor_line = [l for l in data.splitlines() - if 'Processor' in l].pop() - match = re.findall(r'\s(\d+)\s', processor_line) - if match: - self.facts['memtotal_mb'] = int(match[0]) / 1024 - self.facts['memfree_mb'] = int(match[3]) / 1024 - - def parse_filesystems(self, data): - return re.findall(r'^Directory of (\S+)/', data, re.M) - - def parse_filesystems_info(self, data): - facts = dict() - fs = '' - for line in data.split('\n'): - match = re.match(r'^Directory of (\S+)/', line) - if match: - fs = match.group(1) - facts[fs] = dict() - continue - match = re.match(r'^(\d+) bytes total \((\d+) bytes free\)', line) - if match: - facts[fs]['spacetotal_kb'] = int(match.group(1)) / 1024 - facts[fs]['spacefree_kb'] = int(match.group(2)) / 1024 - return facts - - -class Config(FactsBase): - - COMMANDS = ['show running-config'] - - def populate(self): - super(Config, self).populate() - data = self.responses[0] - if data: - data = re.sub( - r'^Building configuration...\s+Current configuration : \d+ bytes\n', - '', data, flags=re.MULTILINE) - self.facts['config'] = data - - -class Interfaces(FactsBase): - - COMMANDS = [ - 'show interfaces', - 'show ip interface', - 'show ipv6 interface', - 'show lldp', - 'show cdp' - ] - - def populate(self): - super(Interfaces, self).populate() - - self.facts['all_ipv4_addresses'] = list() - self.facts['all_ipv6_addresses'] = list() - self.facts['neighbors'] = {} - - data = self.responses[0] - if data: - interfaces = self.parse_interfaces(data) - self.facts['interfaces'] = self.populate_interfaces(interfaces) - - data = self.responses[1] - if data: - data = self.parse_interfaces(data) - self.populate_ipv4_interfaces(data) - - data = self.responses[2] - if data: - data = self.parse_interfaces(data) - self.populate_ipv6_interfaces(data) - - data = self.responses[3] - lldp_errs = ['Invalid input', 'LLDP is not enabled'] - - if data and not any(err in data for err in lldp_errs): - neighbors = self.run(['show lldp neighbors detail']) - if neighbors: - self.facts['neighbors'].update(self.parse_neighbors(neighbors[0])) - - data = self.responses[4] - cdp_errs = ['CDP is not enabled'] - - if data and not any(err in data for err in cdp_errs): - cdp_neighbors = self.run(['show cdp neighbors detail']) - if cdp_neighbors: - self.facts['neighbors'].update(self.parse_cdp_neighbors(cdp_neighbors[0])) - - def populate_interfaces(self, interfaces): - facts = dict() - for key, value in iteritems(interfaces): - intf = dict() - intf['description'] = self.parse_description(value) - intf['macaddress'] = self.parse_macaddress(value) - - intf['mtu'] = self.parse_mtu(value) - intf['bandwidth'] = self.parse_bandwidth(value) - intf['mediatype'] = self.parse_mediatype(value) - intf['duplex'] = self.parse_duplex(value) - intf['lineprotocol'] = self.parse_lineprotocol(value) - intf['operstatus'] = self.parse_operstatus(value) - intf['type'] = self.parse_type(value) - - facts[key] = intf - return facts - - def populate_ipv4_interfaces(self, data): - for key, value in data.items(): - self.facts['interfaces'][key]['ipv4'] = list() - primary_address = addresses = [] - primary_address = re.findall(r'Internet address is (.+)$', value, re.M) - addresses = re.findall(r'Secondary address (.+)$', value, re.M) - if len(primary_address) == 0: - continue - addresses.append(primary_address[0]) - for address in addresses: - addr, subnet = address.split("/") - ipv4 = dict(address=addr.strip(), subnet=subnet.strip()) - self.add_ip_address(addr.strip(), 'ipv4') - self.facts['interfaces'][key]['ipv4'].append(ipv4) - - def populate_ipv6_interfaces(self, data): - for key, value in iteritems(data): - try: - self.facts['interfaces'][key]['ipv6'] = list() - except KeyError: - self.facts['interfaces'][key] = dict() - self.facts['interfaces'][key]['ipv6'] = list() - addresses = re.findall(r'\s+(.+), subnet', value, re.M) - subnets = re.findall(r', subnet is (.+)$', value, re.M) - for addr, subnet in zip(addresses, subnets): - ipv6 = dict(address=addr.strip(), subnet=subnet.strip()) - self.add_ip_address(addr.strip(), 'ipv6') - self.facts['interfaces'][key]['ipv6'].append(ipv6) - - def add_ip_address(self, address, family): - if family == 'ipv4': - self.facts['all_ipv4_addresses'].append(address) - else: - self.facts['all_ipv6_addresses'].append(address) - - def parse_neighbors(self, neighbors): - facts = dict() - for entry in neighbors.split('------------------------------------------------'): - if entry == '': - continue - intf = self.parse_lldp_intf(entry) - if intf is None: - return facts - intf = normalize_interface(intf) - if intf not in facts: - facts[intf] = list() - fact = dict() - fact['host'] = self.parse_lldp_host(entry) - fact['port'] = self.parse_lldp_port(entry) - facts[intf].append(fact) - return facts - - def parse_cdp_neighbors(self, neighbors): - facts = dict() - for entry in neighbors.split('-------------------------'): - if entry == '': - continue - intf_port = self.parse_cdp_intf_port(entry) - if intf_port is None: - return facts - intf, port = intf_port - if intf not in facts: - facts[intf] = list() - fact = dict() - fact['host'] = self.parse_cdp_host(entry) - fact['port'] = port - facts[intf].append(fact) - return facts - - def parse_interfaces(self, data): - parsed = dict() - key = '' - for line in data.split('\n'): - if len(line) == 0: - continue - elif line[0] == ' ': - parsed[key] += '\n%s' % line - else: - match = re.match(r'^(\S+)', line) - if match: - key = match.group(1) - parsed[key] = line - return parsed - - def parse_description(self, data): - match = re.search(r'Description: (.+)$', data, re.M) - if match: - return match.group(1) - - def parse_macaddress(self, data): - match = re.search(r'Hardware is (?:.*), address is (\S+)', data) - if match: - return match.group(1) - - def parse_ipv4(self, data): - match = re.search(r'Internet address is (\S+)', data) - if match: - addr, masklen = match.group(1).split('/') - return dict(address=addr, masklen=int(masklen)) - - def parse_mtu(self, data): - match = re.search(r'MTU (\d+)', data) - if match: - return int(match.group(1)) - - def parse_bandwidth(self, data): - match = re.search(r'BW (\d+)', data) - if match: - return int(match.group(1)) - - def parse_duplex(self, data): - match = re.search(r'(\w+) Duplex', data, re.M) - if match: - return match.group(1) - - def parse_mediatype(self, data): - match = re.search(r'media type is (.+)$', data, re.M) - if match: - return match.group(1) - - def parse_type(self, data): - match = re.search(r'Hardware is (.+),', data, re.M) - if match: - return match.group(1) - - def parse_lineprotocol(self, data): - match = re.search(r'line protocol is (\S+)\s*$', data, re.M) - if match: - return match.group(1) - - def parse_operstatus(self, data): - match = re.search(r'^(?:.+) is (.+),', data, re.M) - if match: - return match.group(1) - - def parse_lldp_intf(self, data): - match = re.search(r'^Local Intf: (.+)$', data, re.M) - if match: - return match.group(1) - - def parse_lldp_host(self, data): - match = re.search(r'System Name: (.+)$', data, re.M) - if match: - return match.group(1) - - def parse_lldp_port(self, data): - match = re.search(r'Port id: (.+)$', data, re.M) - if match: - return match.group(1) - - def parse_cdp_intf_port(self, data): - match = re.search(r'^Interface: (.+), Port ID \(outgoing port\): (.+)$', data, re.M) - if match: - return match.group(1), match.group(2) - - def parse_cdp_host(self, data): - match = re.search(r'^Device ID: (.+)$', data, re.M) - if match: - return match.group(1) diff --git a/lib/ansible/module_utils/network/ios/facts/lldp_global/lldp_global.py b/lib/ansible/module_utils/network/ios/facts/lldp_global/lldp_global.py deleted file mode 100644 index 1643d524763..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/lldp_global/lldp_global.py +++ /dev/null @@ -1,90 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios lldp_global fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from copy import deepcopy -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.ios.argspec.lldp_global.lldp_global import Lldp_globalArgs - - -class Lldp_globalFacts(object): - """ The ios lldp_global fact class - """ - - def __init__(self, module, subspec='config', options='options'): - self._module = module - self.argument_spec = Lldp_globalArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for lldp_global - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - objs = dict() - if not data: - data = connection.get('show running-config | section ^lldp') - # operate on a collection of resource x - config = data.split('\n') - for conf in config: - if conf: - obj = self.render_config(self.generated_spec, conf) - if obj: - objs.update(obj) - facts = {} - - if objs: - params = utils.validate_config(self.argument_spec, {'config': utils.remove_empties(objs)}) - facts['lldp_global'] = utils.remove_empties(params['config']) - ansible_facts['ansible_network_resources'].update(facts) - - return ansible_facts - - def render_config(self, spec, conf): - """ - Render config as dictionary structure and delete keys from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - config = deepcopy(spec) - - holdtime = utils.parse_conf_arg(conf, 'lldp holdtime') - timer = utils.parse_conf_arg(conf, 'lldp timer') - reinit = utils.parse_conf_arg(conf, 'lldp reinit') - if holdtime: - config['holdtime'] = int(holdtime) - if 'lldp run' in conf: - config['enabled'] = True - if timer: - config['timer'] = int(timer) - if reinit: - config['reinit'] = int(reinit) - - return utils.remove_empties(config) diff --git a/lib/ansible/module_utils/network/ios/facts/lldp_interfaces/lldp_interfaces.py b/lib/ansible/module_utils/network/ios/facts/lldp_interfaces/lldp_interfaces.py deleted file mode 100644 index f97f87fbc45..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/lldp_interfaces/lldp_interfaces.py +++ /dev/null @@ -1,108 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_lldp_interfaces fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -import re -from copy import deepcopy -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.ios.utils.utils import get_interface_type, normalize_interface -from ansible.module_utils.network.ios.argspec.lldp_interfaces.lldp_interfaces import Lldp_InterfacesArgs - - -class Lldp_InterfacesFacts(object): - """ The ios_lldp_interfaces fact class - """ - - def __init__(self, module, subspec='config', options='options'): - - self._module = module - self.argument_spec = Lldp_InterfacesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for lldp_interfaces - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - if connection: - pass - - objs = [] - if not data: - data = connection.get('show lldp interface') - # operate on a collection of resource x - config = data.split('\n\n') - - for conf in config: - if conf: - obj = self.render_config(self.generated_spec, conf) - if obj: - objs.append(obj) - facts = {} - - if objs: - facts['lldp_interfaces'] = [] - params = utils.validate_config(self.argument_spec, {'config': objs}) - for cfg in params['config']: - facts['lldp_interfaces'].append(utils.remove_empties(cfg)) - ansible_facts['ansible_network_resources'].update(facts) - - return ansible_facts - - def render_config(self, spec, conf): - """ - Render config as dictionary structure and delete keys - from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - config = deepcopy(spec) - match = re.search(r'^(\S+)(:)', conf) - intf = '' - if match: - intf = match.group(1) - - if get_interface_type(intf) == 'unknown': - return {} - if intf.lower().startswith('gi'): - config['name'] = normalize_interface(intf) - receive = utils.parse_conf_arg(conf, 'Rx:') - transmit = utils.parse_conf_arg(conf, 'Tx:') - - if receive == 'enabled': - config['receive'] = True - elif receive == 'disabled': - config['receive'] = False - if transmit == 'enabled': - config['transmit'] = True - elif transmit == 'disabled': - config['transmit'] = False - - return utils.remove_empties(config) diff --git a/lib/ansible/module_utils/network/ios/facts/static_routes/static_routes.py b/lib/ansible/module_utils/network/ios/facts/static_routes/static_routes.py deleted file mode 100644 index f7ada0b3f50..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/static_routes/static_routes.py +++ /dev/null @@ -1,225 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios_static_routes fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from copy import deepcopy -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.ios.utils.utils import netmask_to_cidr -from ansible.module_utils.network.ios.argspec.static_routes.static_routes import Static_RoutesArgs - - -class Static_RoutesFacts(object): - """ The ios_static_routes fact class - """ - - def __init__(self, module, subspec='config', options='options'): - - self._module = module - self.argument_spec = Static_RoutesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def get_static_routes_data(self, connection): - return connection.get('sh running-config | include ip route|ipv6 route') - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for static_routes - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - - objs = [] - if not data: - data = self.get_static_routes_data(connection) - # operate on a collection of resource x - config = data.split('\n') - - same_dest = self.populate_destination(config) - for key in same_dest.keys(): - if key: - obj = self.render_config(self.generated_spec, key, same_dest[key]) - if obj: - objs.append(obj) - facts = {} - - # append all static routes address_family with NO VRF together - no_vrf_address_family = { - 'address_families': [each.get('address_families')[0] for each in objs if each.get('vrf') is None] - } - - temp_objs = [each for each in objs if each.get('vrf') is not None] - temp_objs.append(no_vrf_address_family) - objs = temp_objs - - if objs: - facts['static_routes'] = [] - params = utils.validate_config(self.argument_spec, {'config': objs}) - for cfg in params['config']: - facts['static_routes'].append(utils.remove_empties(cfg)) - ansible_facts['ansible_network_resources'].update(facts) - - return ansible_facts - - def update_netmask_to_cidr(self, filter, pos, del_pos): - netmask = filter.split(' ') - dest = netmask[pos] + '/' + netmask_to_cidr(netmask[del_pos]) - netmask[pos] = dest - del netmask[del_pos] - filter_vrf = ' ' - return filter_vrf.join(netmask), dest - - def populate_destination(self, config): - same_dest = {} - ip_str = '' - for i in sorted(config): - if i: - if '::' in i and 'vrf' in i: - ip_str = 'ipv6 route vrf' - elif '::' in i and 'vrf' not in i: - ip_str = 'ipv6 route' - elif '.' in i and 'vrf' in i: - ip_str = 'ip route vrf' - elif '.' in i and 'vrf' not in i: - ip_str = 'ip route' - - if 'vrf' in i: - filter_vrf = utils.parse_conf_arg(i, ip_str) - if '/' not in filter_vrf and '::' not in filter_vrf: - filter_vrf, dest_vrf = self.update_netmask_to_cidr(filter_vrf, 1, 2) - dest_vrf = dest_vrf + '_vrf' - else: - dest_vrf = filter_vrf.split(' ')[1] - if dest_vrf not in same_dest.keys(): - same_dest[dest_vrf] = [] - same_dest[dest_vrf].append('vrf ' + filter_vrf) - elif 'vrf' not in same_dest[dest_vrf][0]: - same_dest[dest_vrf] = [] - same_dest[dest_vrf].append('vrf ' + filter_vrf) - else: - same_dest[dest_vrf].append(('vrf ' + filter_vrf)) - else: - filter = utils.parse_conf_arg(i, ip_str) - if '/' not in filter and '::' not in filter: - filter, dest = self.update_netmask_to_cidr(filter, 0, 1) - else: - dest = filter.split(' ')[0] - if dest not in same_dest.keys(): - same_dest[dest] = [] - same_dest[dest].append(filter) - elif 'vrf' in same_dest[dest][0]: - same_dest[dest] = [] - same_dest[dest].append(filter) - else: - same_dest[dest].append(filter) - return same_dest - - def render_config(self, spec, conf, conf_val): - """ - Render config as dictionary structure and delete keys - from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - config = deepcopy(spec) - config['address_families'] = [] - route_dict = dict() - final_route = dict() - afi = dict() - final_route['routes'] = [] - next_hops = [] - hops = {} - vrf = '' - address_family = dict() - for each in conf_val: - route = each.split(' ') - if 'vrf' in conf_val[0]: - vrf = route[route.index('vrf') + 1] - route_dict['dest'] = conf.split('_')[0] - else: - route_dict['dest'] = conf - if 'vrf' in conf_val[0]: - hops = {} - if '::' in conf: - hops['forward_router_address'] = route[3] - afi['afi'] = 'ipv6' - elif '.' in conf: - hops['forward_router_address'] = route[3] - afi['afi'] = "ipv4" - else: - hops['interface'] = conf - else: - - if '::' in conf: - hops['forward_router_address'] = route[1] - afi['afi'] = 'ipv6' - elif '.' in conf: - hops['forward_router_address'] = route[1] - afi['afi'] = "ipv4" - else: - hops['interface'] = route[1] - try: - temp_list = each.split(' ') - if 'tag' in temp_list: - del temp_list[temp_list.index('tag') + 1] - if 'track' in temp_list: - del temp_list[temp_list.index('track') + 1] - # find distance metric - dist_metrics = int( - [i for i in temp_list if '.' not in i and ':' not in i and ord(i[0]) > 48 and ord(i[0]) < 57][0] - ) - except IndexError: - dist_metrics = None - if dist_metrics: - hops['distance_metric'] = dist_metrics - if 'name' in route: - hops['name'] = route[route.index('name') + 1] - if 'multicast' in route: - hops['multicast'] = True - if 'dhcp' in route: - hops['dhcp'] = True - if 'global' in route: - hops['global'] = True - if 'permanent' in route: - hops['permanent'] = True - if 'tag' in route: - hops['tag'] = route[route.index('tag') + 1] - if 'track' in route: - hops['track'] = route[route.index('track') + 1] - next_hops.append(hops) - hops = {} - route_dict['next_hops'] = next_hops - if route_dict: - final_route['routes'].append(route_dict) - address_family.update(afi) - address_family.update(final_route) - config['address_families'].append(address_family) - if vrf: - config['vrf'] = vrf - - return utils.remove_empties(config) diff --git a/lib/ansible/module_utils/network/ios/facts/vlans/vlans.py b/lib/ansible/module_utils/network/ios/facts/vlans/vlans.py deleted file mode 100644 index b499be5ce9a..00000000000 --- a/lib/ansible/module_utils/network/ios/facts/vlans/vlans.py +++ /dev/null @@ -1,144 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The ios vlans fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from copy import deepcopy -from ansible.module_utils.network.common import utils -from ansible.module_utils.network.ios.argspec.vlans.vlans import VlansArgs - - -class VlansFacts(object): - """ The ios vlans fact class - """ - - def __init__(self, module, subspec='config', options='options'): - self._module = module - self.argument_spec = VlansArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for vlans - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - if connection: - pass - - objs = [] - mtu_objs = [] - remote_objs = [] - final_objs = [] - if not data: - data = connection.get('show vlan') - # operate on a collection of resource x - config = data.split('\n') - # Get individual vlan configs separately - vlan_info = '' - for conf in config: - if 'Name' in conf: - vlan_info = 'Name' - elif 'Type' in conf: - vlan_info = 'Type' - elif 'Remote' in conf: - vlan_info = 'Remote' - if conf and ' ' not in filter(None, conf.split('-')): - obj = self.render_config(self.generated_spec, conf, vlan_info) - if 'mtu' in obj: - mtu_objs.append(obj) - elif 'remote_span' in obj: - remote_objs = obj - elif obj: - objs.append(obj) - # Appending MTU value to the retrieved dictionary - for o, m in zip(objs, mtu_objs): - o.update(m) - final_objs.append(o) - - # Appending Remote Span value to related VLAN: - if remote_objs: - if remote_objs.get('remote_span'): - for each in remote_objs.get('remote_span'): - for every in final_objs: - if each == every.get('vlan_id'): - every.update({'remote_span': True}) - break - - facts = {} - if final_objs: - facts['vlans'] = [] - params = utils.validate_config(self.argument_spec, {'config': objs}) - - for cfg in params['config']: - facts['vlans'].append(utils.remove_empties(cfg)) - ansible_facts['ansible_network_resources'].update(facts) - - return ansible_facts - - def render_config(self, spec, conf, vlan_info): - """ - Render config as dictionary structure and delete keys - from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - config = deepcopy(spec) - - if vlan_info == 'Name' and 'Name' not in conf: - conf = list(filter(None, conf.split(' '))) - config['vlan_id'] = int(conf[0]) - config['name'] = conf[1] - if len(conf[2].split('/')) > 1: - if conf[2].split('/')[0] == 'sus': - config['state'] = 'suspend' - elif conf[2].split('/')[0] == 'act': - config['state'] = 'active' - config['shutdown'] = 'enabled' - else: - if conf[2] == 'suspended': - config['state'] = 'suspend' - elif conf[2] == 'active': - config['state'] = 'active' - config['shutdown'] = 'disabled' - elif vlan_info == 'Type' and 'Type' not in conf: - conf = list(filter(None, conf.split(' '))) - config['mtu'] = int(conf[3]) - elif vlan_info == 'Remote': - if len(conf.split(',')) > 1 or conf.isdigit(): - remote_span_vlan = [] - if len(conf.split(',')) > 1: - remote_span_vlan = conf.split(',') - else: - remote_span_vlan.append(conf) - remote_span = [] - for each in remote_span_vlan: - remote_span.append(int(each)) - config['remote_span'] = remote_span - - return utils.remove_empties(config) diff --git a/lib/ansible/module_utils/network/ios/ios.py b/lib/ansible/module_utils/network/ios/ios.py deleted file mode 100644 index 3e1c680aa30..00000000000 --- a/lib/ansible/module_utils/network/ios/ios.py +++ /dev/null @@ -1,183 +0,0 @@ -# This code is part of Ansible, but is an independent component. -# This particular file snippet, and this file snippet only, is BSD licensed. -# Modules you write using this snippet, which is embedded dynamically by Ansible -# still belong to the author of the module, and may assign their own license -# to the complete work. -# -# (c) 2016 Red Hat Inc. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -import json - -from ansible.module_utils._text import to_text -from ansible.module_utils.basic import env_fallback -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.connection import Connection, ConnectionError - -_DEVICE_CONFIGS = {} - -ios_provider_spec = { - 'host': dict(), - 'port': dict(type='int'), - 'username': dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME'])), - 'password': dict(fallback=(env_fallback, ['ANSIBLE_NET_PASSWORD']), no_log=True), - 'ssh_keyfile': dict(fallback=(env_fallback, ['ANSIBLE_NET_SSH_KEYFILE']), type='path'), - 'authorize': dict(fallback=(env_fallback, ['ANSIBLE_NET_AUTHORIZE']), type='bool'), - 'auth_pass': dict(fallback=(env_fallback, ['ANSIBLE_NET_AUTH_PASS']), no_log=True), - 'timeout': dict(type='int') -} -ios_argument_spec = { - 'provider': dict(type='dict', options=ios_provider_spec, removed_in_version=2.14), -} - - -def get_provider_argspec(): - return ios_provider_spec - - -def get_connection(module): - if hasattr(module, '_ios_connection'): - return module._ios_connection - - capabilities = get_capabilities(module) - network_api = capabilities.get('network_api') - if network_api == 'cliconf': - module._ios_connection = Connection(module._socket_path) - else: - module.fail_json(msg='Invalid connection type %s' % network_api) - - return module._ios_connection - - -def get_capabilities(module): - if hasattr(module, '_ios_capabilities'): - return module._ios_capabilities - try: - capabilities = Connection(module._socket_path).get_capabilities() - except ConnectionError as exc: - module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) - module._ios_capabilities = json.loads(capabilities) - return module._ios_capabilities - - -def get_defaults_flag(module): - connection = get_connection(module) - try: - out = connection.get_defaults_flag() - except ConnectionError as exc: - module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) - return to_text(out, errors='surrogate_then_replace').strip() - - -def get_config(module, flags=None): - flags = to_list(flags) - - section_filter = False - if flags and 'section' in flags[-1]: - section_filter = True - - flag_str = ' '.join(flags) - - try: - return _DEVICE_CONFIGS[flag_str] - except KeyError: - connection = get_connection(module) - try: - out = connection.get_config(flags=flags) - except ConnectionError as exc: - if section_filter: - # Some ios devices don't understand `| section foo` - out = get_config(module, flags=flags[:-1]) - else: - module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) - cfg = to_text(out, errors='surrogate_then_replace').strip() - _DEVICE_CONFIGS[flag_str] = cfg - return cfg - - -def run_commands(module, commands, check_rc=True): - connection = get_connection(module) - try: - return connection.run_commands(commands=commands, check_rc=check_rc) - except ConnectionError as exc: - module.fail_json(msg=to_text(exc)) - - -def load_config(module, commands): - connection = get_connection(module) - - try: - resp = connection.edit_config(commands) - return resp.get('response') - except ConnectionError as exc: - module.fail_json(msg=to_text(exc)) - - -def normalize_interface(name): - """Return the normalized interface name - """ - if not name: - return - - def _get_number(name): - digits = '' - for char in name: - if char.isdigit() or char in '/.': - digits += char - return digits - - if name.lower().startswith('gi'): - if_type = 'GigabitEthernet' - elif name.lower().startswith('te'): - if_type = 'TenGigabitEthernet' - elif name.lower().startswith('fa'): - if_type = 'FastEthernet' - elif name.lower().startswith('fo'): - if_type = 'FortyGigabitEthernet' - elif name.lower().startswith('et'): - if_type = 'Ethernet' - elif name.lower().startswith('vl'): - if_type = 'Vlan' - elif name.lower().startswith('lo'): - if_type = 'loopback' - elif name.lower().startswith('po'): - if_type = 'port-channel' - elif name.lower().startswith('nv'): - if_type = 'nve' - elif name.lower().startswith('twe'): - if_type = 'TwentyFiveGigE' - elif name.lower().startswith('hu'): - if_type = 'HundredGigE' - else: - if_type = None - - number_list = name.split(' ') - if len(number_list) == 2: - if_number = number_list[-1].strip() - else: - if_number = _get_number(name) - - if if_type: - proper_interface = if_type + if_number - else: - proper_interface = name - - return proper_interface diff --git a/lib/ansible/module_utils/network/ios/providers/cli/config/base.py b/lib/ansible/module_utils/network/ios/providers/cli/config/base.py deleted file mode 100644 index eade249a09c..00000000000 --- a/lib/ansible/module_utils/network/ios/providers/cli/config/base.py +++ /dev/null @@ -1,77 +0,0 @@ -# -# (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 ansible.module_utils.six import iteritems -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.common.config import NetworkConfig - - -class ConfigBase(object): - - argument_spec = {} - - mutually_exclusive = [] - - identifier = () - - def __init__(self, **kwargs): - self.values = {} - self._rendered_configuration = {} - self.active_configuration = None - - for item in self.identifier: - self.values[item] = kwargs.pop(item) - - for key, value in iteritems(kwargs): - if key in self.argument_spec: - setattr(self, key, value) - - for key, value in iteritems(self.argument_spec): - if value.get('default'): - if not getattr(self, key, None): - setattr(self, key, value.get('default')) - - def __getattr__(self, key): - if key in self.argument_spec: - return self.values.get(key) - - def __setattr__(self, key, value): - if key in self.argument_spec: - if key in self.identifier: - raise TypeError('cannot set value') - elif value is not None: - self.values[key] = value - else: - super(ConfigBase, self).__setattr__(key, value) - - def context_config(self, cmd): - if 'context' not in self._rendered_configuration: - self._rendered_configuration['context'] = list() - self._rendered_configuration['context'].extend(to_list(cmd)) - - def global_config(self, cmd): - if 'global' not in self._rendered_configuration: - self._rendered_configuration['global'] = list() - self._rendered_configuration['global'].extend(to_list(cmd)) - - def get_rendered_configuration(self): - config = list() - for section in ('context', 'global'): - config.extend(self._rendered_configuration.get(section, [])) - return config - - def set_active_configuration(self, config): - self.active_configuration = config - - def render(self, config=None): - raise NotImplementedError - - def get_section(self, config, section): - if config is not None: - netcfg = NetworkConfig(indent=1, contents=config) - try: - config = netcfg.get_block_config(to_list(section)) - except ValueError: - config = None - return config diff --git a/lib/ansible/module_utils/network/ios/providers/cli/config/bgp/address_family.py b/lib/ansible/module_utils/network/ios/providers/cli/config/bgp/address_family.py deleted file mode 100644 index 366f6413c1b..00000000000 --- a/lib/ansible/module_utils/network/ios/providers/cli/config/bgp/address_family.py +++ /dev/null @@ -1,140 +0,0 @@ -# -# (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) -# -import re - -from ansible.module_utils.six import iteritems -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.providers.providers import CliProvider -from ansible.module_utils.network.ios.providers.cli.config.bgp.neighbors import AFNeighbors -from ansible.module_utils.common.network import to_netmask - - -class AddressFamily(CliProvider): - - def render(self, config=None): - commands = list() - safe_list = list() - - router_context = 'router bgp %s' % self.get_value('config.bgp_as') - context_config = None - - for item in self.get_value('config.address_family'): - context = 'address-family %s' % item['afi'] - if item['safi'] != 'unicast': - context += ' %s' % item['safi'] - context_commands = list() - - if config: - context_path = [router_context, context] - context_config = self.get_config_context(config, context_path, indent=1) - - for key, value in iteritems(item): - if value is not None: - meth = getattr(self, '_render_%s' % key, None) - if meth: - resp = meth(item, context_config) - if resp: - context_commands.extend(to_list(resp)) - - if context_commands: - commands.append(context) - commands.extend(context_commands) - commands.append('exit-address-family') - - safe_list.append(context) - - if self.params['operation'] == 'replace': - if config: - resp = self._negate_config(config, safe_list) - commands.extend(resp) - - return commands - - def _negate_config(self, config, safe_list=None): - commands = list() - matches = re.findall(r'(address-family .+)$', config, re.M) - for item in set(matches).difference(safe_list): - commands.append('no %s' % item) - return commands - - def _render_auto_summary(self, item, config=None): - cmd = 'auto-summary' - if item['auto_summary'] is False: - cmd = 'no %s' % cmd - if not config or cmd not in config: - return cmd - - def _render_synchronization(self, item, config=None): - cmd = 'synchronization' - if item['synchronization'] is False: - cmd = 'no %s' % cmd - if not config or cmd not in config: - return cmd - - def _render_networks(self, item, config=None): - commands = list() - safe_list = list() - - for entry in item['networks']: - network = entry['prefix'] - cmd = 'network %s' % network - if entry['masklen']: - cmd += ' mask %s' % to_netmask(entry['masklen']) - network += ' mask %s' % to_netmask(entry['masklen']) - if entry['route_map']: - cmd += ' route-map %s' % entry['route_map'] - network += ' route-map %s' % entry['route_map'] - - safe_list.append(network) - - if not config or cmd not in config: - commands.append(cmd) - - if self.params['operation'] == 'replace': - if config: - matches = re.findall(r'network (.*)', config, re.M) - for entry in set(matches).difference(safe_list): - commands.append('no network %s' % entry) - - return commands - - def _render_redistribute(self, item, config=None): - commands = list() - safe_list = list() - - for entry in item['redistribute']: - option = entry['protocol'] - - cmd = 'redistribute %s' % entry['protocol'] - - if entry['id'] and entry['protocol'] in ('ospf', 'ospfv3', 'eigrp'): - cmd += ' %s' % entry['id'] - option += ' %s' % entry['id'] - - if entry['metric']: - cmd += ' metric %s' % entry['metric'] - - if entry['route_map']: - cmd += ' route-map %s' % entry['route_map'] - - if not config or cmd not in config: - commands.append(cmd) - - safe_list.append(option) - - if self.params['operation'] == 'replace': - if config: - matches = re.findall(r'redistribute (\S+)(?:\s*)(\d*)', config, re.M) - for i in range(0, len(matches)): - matches[i] = ' '.join(matches[i]).strip() - for entry in set(matches).difference(safe_list): - commands.append('no redistribute %s' % entry) - - return commands - - def _render_neighbors(self, item, config): - """ generate bgp neighbor configuration - """ - return AFNeighbors(self.params).render(config, nbr_list=item['neighbors']) diff --git a/lib/ansible/module_utils/network/ios/providers/cli/config/bgp/neighbors.py b/lib/ansible/module_utils/network/ios/providers/cli/config/bgp/neighbors.py deleted file mode 100644 index 2cee73382a4..00000000000 --- a/lib/ansible/module_utils/network/ios/providers/cli/config/bgp/neighbors.py +++ /dev/null @@ -1,196 +0,0 @@ -# -# (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) -# -import re - -from ansible.module_utils.six import iteritems -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.providers.providers import CliProvider - - -class Neighbors(CliProvider): - - def render(self, config=None, nbr_list=None): - commands = list() - safe_list = list() - if not nbr_list: - nbr_list = self.get_value('config.neighbors') - - for item in nbr_list: - neighbor_commands = list() - context = 'neighbor %s' % item['neighbor'] - cmd = '%s remote-as %s' % (context, item['remote_as']) - - if not config or cmd not in config: - neighbor_commands.append(cmd) - - for key, value in iteritems(item): - if value is not None: - meth = getattr(self, '_render_%s' % key, None) - if meth: - resp = meth(item, config) - if resp: - neighbor_commands.extend(to_list(resp)) - - commands.extend(neighbor_commands) - safe_list.append(context) - - if self.params['operation'] == 'replace': - if config and safe_list: - commands.extend(self._negate_config(config, safe_list)) - - return commands - - def _negate_config(self, config, safe_list=None): - commands = list() - matches = re.findall(r'(neighbor \S+)', config, re.M) - for item in set(matches).difference(safe_list): - commands.append('no %s' % item) - return commands - - def _render_local_as(self, item, config=None): - cmd = 'neighbor %s local-as %s' % (item['neighbor'], item['local_as']) - if not config or cmd not in config: - return cmd - - def _render_port(self, item, config=None): - cmd = 'neighbor %s port %s' % (item['neighbor'], item['port']) - if not config or cmd not in config: - return cmd - - def _render_description(self, item, config=None): - cmd = 'neighbor %s description %s' % (item['neighbor'], item['description']) - if not config or cmd not in config: - return cmd - - def _render_enabled(self, item, config=None): - cmd = 'neighbor %s shutdown' % item['neighbor'] - if item['enabled'] is True: - if not config or cmd in config: - cmd = 'no %s' % cmd - return cmd - elif not config or cmd not in config: - return cmd - - def _render_update_source(self, item, config=None): - cmd = 'neighbor %s update-source %s' % (item['neighbor'], item['update_source']) - if not config or cmd not in config: - return cmd - - def _render_password(self, item, config=None): - cmd = 'neighbor %s password %s' % (item['neighbor'], item['password']) - if not config or cmd not in config: - return cmd - - def _render_ebgp_multihop(self, item, config=None): - cmd = 'neighbor %s ebgp-multihop %s' % (item['neighbor'], item['ebgp_multihop']) - if not config or cmd not in config: - return cmd - - def _render_peer_group(self, item, config=None): - cmd = 'neighbor %s peer-group %s' % (item['neighbor'], item['peer_group']) - if not config or cmd not in config: - return cmd - - def _render_timers(self, item, config): - """generate bgp timer related configuration - """ - keepalive = item['timers']['keepalive'] - holdtime = item['timers']['holdtime'] - min_neighbor_holdtime = item['timers']['min_neighbor_holdtime'] - neighbor = item['neighbor'] - - if keepalive and holdtime: - cmd = 'neighbor %s timers %s %s' % (neighbor, keepalive, holdtime) - if min_neighbor_holdtime: - cmd += ' %s' % min_neighbor_holdtime - if not config or cmd not in config: - return cmd - - -class AFNeighbors(CliProvider): - - def render(self, config=None, nbr_list=None): - commands = list() - if not nbr_list: - return - - for item in nbr_list: - neighbor_commands = list() - for key, value in iteritems(item): - if value is not None: - meth = getattr(self, '_render_%s' % key, None) - if meth: - resp = meth(item, config) - if resp: - neighbor_commands.extend(to_list(resp)) - - commands.extend(neighbor_commands) - - return commands - - def _render_advertisement_interval(self, item, config=None): - cmd = 'neighbor %s advertisement-interval %s' % (item['neighbor'], item['advertisement_interval']) - if not config or cmd not in config: - return cmd - - def _render_route_reflector_client(self, item, config=None): - cmd = 'neighbor %s route-reflector-client' % item['neighbor'] - if item['route_reflector_client'] is False: - if not config or cmd in config: - cmd = 'no %s' % cmd - return cmd - elif not config or cmd not in config: - return cmd - - def _render_route_server_client(self, item, config=None): - cmd = 'neighbor %s route-server-client' % item['neighbor'] - if item['route_server_client'] is False: - if not config or cmd in config: - cmd = 'no %s' % cmd - return cmd - elif not config or cmd not in config: - return cmd - - def _render_remove_private_as(self, item, config=None): - cmd = 'neighbor %s remove-private-as' % item['neighbor'] - if item['remove_private_as'] is False: - if not config or cmd in config: - cmd = 'no %s' % cmd - return cmd - elif not config or cmd not in config: - return cmd - - def _render_next_hop_self(self, item, config=None): - cmd = 'neighbor %s next-hop-self' % item['neighbor'] - if item['next_hop_self'] is False: - if not config or cmd in config: - cmd = 'no %s' % cmd - return cmd - elif not config or cmd not in config: - return cmd - - def _render_activate(self, item, config=None): - cmd = 'neighbor %s activate' % item['neighbor'] - if item['activate'] is False: - if not config or cmd in config: - cmd = 'no %s' % cmd - return cmd - elif not config or cmd not in config: - return cmd - - def _render_maximum_prefix(self, item, config=None): - cmd = 'neighbor %s maximum-prefix %s' % (item['neighbor'], item['maximum_prefix']) - if not config or cmd not in config: - return cmd - - def _render_prefix_list_in(self, item, config=None): - cmd = 'neighbor %s prefix-list %s in' % (item['neighbor'], item['prefix_list_in']) - if not config or cmd not in config: - return cmd - - def _render_prefix_list_out(self, item, config=None): - cmd = 'neighbor %s prefix-list %s out' % (item['neighbor'], item['prefix_list_out']) - if not config or cmd not in config: - return cmd diff --git a/lib/ansible/module_utils/network/ios/providers/cli/config/bgp/process.py b/lib/ansible/module_utils/network/ios/providers/cli/config/bgp/process.py deleted file mode 100644 index d74cf92773c..00000000000 --- a/lib/ansible/module_utils/network/ios/providers/cli/config/bgp/process.py +++ /dev/null @@ -1,140 +0,0 @@ -# -# (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) -# -import re - -from ansible.module_utils.six import iteritems -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.ios.providers.providers import register_provider -from ansible.module_utils.network.ios.providers.providers import CliProvider -from ansible.module_utils.network.ios.providers.cli.config.bgp.neighbors import Neighbors -from ansible.module_utils.network.ios.providers.cli.config.bgp.address_family import AddressFamily -from ansible.module_utils.common.network import to_netmask - -REDISTRIBUTE_PROTOCOLS = frozenset(['ospf', 'ospfv3', 'eigrp', 'isis', 'static', 'connected', - 'odr', 'lisp', 'mobile', 'rip']) - - -@register_provider('ios', 'ios_bgp') -class Provider(CliProvider): - - def render(self, config=None): - commands = list() - - existing_as = None - if config: - match = re.search(r'router bgp (\d+)', config, re.M) - if match: - existing_as = match.group(1) - - operation = self.params['operation'] - - context = None - if self.params['config']: - context = 'router bgp %s' % self.get_value('config.bgp_as') - - if operation == 'delete': - if existing_as: - commands.append('no router bgp %s' % existing_as) - elif context: - commands.append('no %s' % context) - - else: - self._validate_input(config) - if operation == 'replace': - if existing_as and int(existing_as) != self.get_value('config.bgp_as'): - commands.append('no router bgp %s' % existing_as) - config = None - - elif operation == 'override': - if existing_as: - commands.append('no router bgp %s' % existing_as) - config = None - - context_commands = list() - - for key, value in iteritems(self.get_value('config')): - if value is not None: - meth = getattr(self, '_render_%s' % key, None) - if meth: - resp = meth(config) - if resp: - context_commands.extend(to_list(resp)) - - if context and context_commands: - commands.append(context) - commands.extend(context_commands) - commands.append('exit') - return commands - - def _render_router_id(self, config=None): - cmd = 'bgp router-id %s' % self.get_value('config.router_id') - if not config or cmd not in config: - return cmd - - def _render_log_neighbor_changes(self, config=None): - cmd = 'bgp log-neighbor-changes' - log_neighbor_changes = self.get_value('config.log_neighbor_changes') - if log_neighbor_changes is True: - if not config or cmd not in config: - return cmd - elif log_neighbor_changes is False: - if config and cmd in config: - return 'no %s' % cmd - - def _render_networks(self, config=None): - commands = list() - safe_list = list() - - for entry in self.get_value('config.networks'): - network = entry['prefix'] - cmd = 'network %s' % network - if entry['masklen'] and entry['masklen'] not in (24, 16, 8): - cmd += ' mask %s' % to_netmask(entry['masklen']) - network += ' mask %s' % to_netmask(entry['masklen']) - - if entry['route_map']: - cmd += ' route-map %s' % entry['route_map'] - network += ' route-map %s' % entry['route_map'] - - safe_list.append(network) - - if not config or cmd not in config: - commands.append(cmd) - - if self.params['operation'] == 'replace': - if config: - matches = re.findall(r'network (.*)', config, re.M) - for entry in set(matches).difference(safe_list): - commands.append('no network %s' % entry) - - return commands - - def _render_neighbors(self, config): - """ generate bgp neighbor configuration - """ - return Neighbors(self.params).render(config) - - def _render_address_family(self, config): - """ generate address-family configuration - """ - return AddressFamily(self.params).render(config) - - def _validate_input(self, config=None): - def device_has_AF(config): - return re.search(r'address-family (?:.*)', config) - - address_family = self.get_value('config.address_family') - root_networks = self.get_value('config.networks') - operation = self.params['operation'] - - if operation == 'replace': - if address_family and root_networks: - for item in address_family: - if item['networks']: - raise ValueError('operation is replace but provided both root level network(s) and network(s) under %s %s address family' - % (item['afi'], item['safi'])) - - if root_networks and config and device_has_AF(config): - raise ValueError('operation is replace and device has one or more address family activated but root level network(s) provided') diff --git a/lib/ansible/module_utils/network/ios/providers/module.py b/lib/ansible/module_utils/network/ios/providers/module.py deleted file mode 100644 index 69c6dd96590..00000000000 --- a/lib/ansible/module_utils/network/ios/providers/module.py +++ /dev/null @@ -1,62 +0,0 @@ -# -# (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 ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.connection import Connection -from ansible.module_utils.network.ios.providers import providers -from ansible.module_utils._text import to_text - - -class NetworkModule(AnsibleModule): - - fail_on_missing_provider = True - - def __init__(self, connection=None, *args, **kwargs): - super(NetworkModule, self).__init__(*args, **kwargs) - - if connection is None: - connection = Connection(self._socket_path) - - self.connection = connection - - @property - def provider(self): - if not hasattr(self, '_provider'): - capabilities = self.from_json(self.connection.get_capabilities()) - - network_os = capabilities['device_info']['network_os'] - network_api = capabilities['network_api'] - - if network_api == 'cliconf': - connection_type = 'network_cli' - - cls = providers.get(network_os, self._name.split('.')[-1], connection_type) - - if not cls: - msg = 'unable to find suitable provider for network os %s' % network_os - if self.fail_on_missing_provider: - self.fail_json(msg=msg) - else: - self.warn(msg) - - obj = cls(self.params, self.connection, self.check_mode) - - setattr(self, '_provider', obj) - - return getattr(self, '_provider') - - def get_facts(self, subset=None): - try: - self.provider.get_facts(subset) - except Exception as exc: - self.fail_json(msg=to_text(exc)) - - def edit_config(self, config_filter=None): - current_config = self.connection.get_config(flags=config_filter) - try: - commands = self.provider.edit_config(current_config) - changed = bool(commands) - return {'commands': commands, 'changed': changed} - except Exception as exc: - self.fail_json(msg=to_text(exc)) diff --git a/lib/ansible/module_utils/network/ios/providers/providers.py b/lib/ansible/module_utils/network/ios/providers/providers.py deleted file mode 100644 index a466b033d94..00000000000 --- a/lib/ansible/module_utils/network/ios/providers/providers.py +++ /dev/null @@ -1,120 +0,0 @@ -# -# (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) -# -import json - -from threading import RLock - -from ansible.module_utils.six import itervalues -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.common.config import NetworkConfig - - -_registered_providers = {} -_provider_lock = RLock() - - -def register_provider(network_os, module_name): - def wrapper(cls): - _provider_lock.acquire() - try: - if network_os not in _registered_providers: - _registered_providers[network_os] = {} - for ct in cls.supported_connections: - if ct not in _registered_providers[network_os]: - _registered_providers[network_os][ct] = {} - for item in to_list(module_name): - for entry in itervalues(_registered_providers[network_os]): - entry[item] = cls - finally: - _provider_lock.release() - return cls - return wrapper - - -def get(network_os, module_name, connection_type): - network_os_providers = _registered_providers.get(network_os) - if network_os_providers is None: - raise ValueError('unable to find a suitable provider for this module') - if connection_type not in network_os_providers: - raise ValueError('provider does not support this connection type') - elif module_name not in network_os_providers[connection_type]: - raise ValueError('could not find a suitable provider for this module') - return network_os_providers[connection_type][module_name] - - -class ProviderBase(object): - - supported_connections = () - - def __init__(self, params, connection=None, check_mode=False): - self.params = params - self.connection = connection - self.check_mode = check_mode - - @property - def capabilities(self): - if not hasattr(self, '_capabilities'): - resp = self.from_json(self.connection.get_capabilities()) - setattr(self, '_capabilities', resp) - return getattr(self, '_capabilities') - - def get_value(self, path): - params = self.params.copy() - for key in path.split('.'): - params = params[key] - return params - - def get_facts(self, subset=None): - raise NotImplementedError(self.__class__.__name__) - - def edit_config(self): - raise NotImplementedError(self.__class__.__name__) - - -class CliProvider(ProviderBase): - - supported_connections = ('network_cli',) - - @property - def capabilities(self): - if not hasattr(self, '_capabilities'): - resp = self.from_json(self.connection.get_capabilities()) - setattr(self, '_capabilities', resp) - return getattr(self, '_capabilities') - - def get_config_context(self, config, path, indent=1): - if config is not None: - netcfg = NetworkConfig(indent=indent, contents=config) - try: - config = netcfg.get_block_config(to_list(path)) - except ValueError: - config = None - return config - - def render(self, config=None): - raise NotImplementedError(self.__class__.__name__) - - def cli(self, command): - try: - if not hasattr(self, '_command_output'): - setattr(self, '_command_output', {}) - return self._command_output[command] - except KeyError: - out = self.connection.get(command) - try: - out = json.loads(out) - except ValueError: - pass - self._command_output[command] = out - return out - - def get_facts(self, subset=None): - return self.populate() - - def edit_config(self, config=None): - commands = self.render(config) - if commands and self.check_mode is False: - self.connection.edit_config(commands) - return commands diff --git a/lib/ansible/module_utils/network/ios/utils/utils.py b/lib/ansible/module_utils/network/ios/utils/utils.py deleted file mode 100644 index cfcfe82dbce..00000000000 --- a/lib/ansible/module_utils/network/ios/utils/utils.py +++ /dev/null @@ -1,328 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# utils - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -import socket -from ansible.module_utils.six import iteritems -from ansible.module_utils.network.common.utils import is_masklen, to_netmask - - -def remove_command_from_config_list(interface, cmd, commands): - # To delete the passed config - if interface not in commands: - commands.insert(0, interface) - commands.append('no %s' % cmd) - return commands - - -def add_command_to_config_list(interface, cmd, commands): - # To set the passed config - if interface not in commands: - commands.insert(0, interface) - commands.append(cmd) - - -def check_n_return_valid_ipv6_addr(module, input_list, filtered_ipv6_list): - # To verify the valid ipv6 address - try: - for each in input_list: - if '::' in each: - if '/' in each: - each = each.split('/')[0] - if socket.inet_pton(socket.AF_INET6, each): - filtered_ipv6_list.append(each) - return filtered_ipv6_list - except socket.error: - module.fail_json(msg='Incorrect IPV6 address!') - - -def new_dict_to_set(input_dict, temp_list, test_set, count=0): - # recursive function to convert input dict to set for comparision - test_dict = dict() - if isinstance(input_dict, dict): - input_dict_len = len(input_dict) - for k, v in sorted(iteritems(input_dict)): - count += 1 - if isinstance(v, list): - temp_list.append(k) - for each in v: - if isinstance(each, dict): - if [True for i in each.values() if type(i) == list]: - new_dict_to_set(each, temp_list, test_set, count) - else: - new_dict_to_set(each, temp_list, test_set, 0) - else: - if v is not None: - test_dict.update({k: v}) - try: - if tuple(iteritems(test_dict)) not in test_set and count == input_dict_len: - test_set.add(tuple(iteritems(test_dict))) - count = 0 - except TypeError: - temp_dict = {} - - def expand_dict(dict_to_expand): - temp = dict() - for k, v in iteritems(dict_to_expand): - if isinstance(v, dict): - expand_dict(v) - else: - if v is not None: - temp.update({k: v}) - temp_dict.update(tuple(iteritems(temp))) - new_dict = {k: v} - expand_dict(new_dict) - if tuple(iteritems(temp_dict)) not in test_set: - test_set.add(tuple(iteritems(temp_dict))) - - -def dict_to_set(sample_dict): - # Generate a set with passed dictionary for comparison - test_dict = dict() - if isinstance(sample_dict, dict): - for k, v in iteritems(sample_dict): - if v is not None: - if isinstance(v, list): - if isinstance(v[0], dict): - li = [] - for each in v: - for key, value in iteritems(each): - if isinstance(value, list): - each[key] = tuple(value) - li.append(tuple(iteritems(each))) - v = tuple(li) - else: - v = tuple(v) - elif isinstance(v, dict): - li = [] - for key, value in iteritems(v): - if isinstance(value, list): - v[key] = tuple(value) - li.extend(tuple(iteritems(v))) - v = tuple(li) - test_dict.update({k: v}) - return_set = set(tuple(iteritems(test_dict))) - else: - return_set = set(sample_dict) - return return_set - - -def filter_dict_having_none_value(want, have): - # Generate dict with have dict value which is None in want dict - test_dict = dict() - name = want.get('name') - if name: - test_dict['name'] = name - diff_ip = False - for k, v in iteritems(want): - if isinstance(v, dict): - for key, value in iteritems(v): - test_key_dict = dict() - if value is None: - dict_val = have.get(k).get(key) - test_key_dict.update({key: dict_val}) - elif k == 'ipv6' and value.lower() != have.get(k)[0].get(key).lower(): - # as multiple IPV6 address can be configured on same - # interface, for replace state in place update will - # actually create new entry, which isn't as expected - # for replace state, so in case of IPV6 address - # every time 1st delete the existing IPV6 config and - # then apply the new change - dict_val = have.get(k)[0].get(key) - test_key_dict.update({key: dict_val}) - if test_key_dict: - test_dict.update({k: test_key_dict}) - if isinstance(v, list): - for key, value in iteritems(v[0]): - test_key_dict = dict() - if value is None: - dict_val = have.get(k).get(key) - test_key_dict.update({key: dict_val}) - elif k == 'ipv6' and value.lower() != have.get(k)[0].get(key).lower(): - dict_val = have.get(k)[0].get(key) - test_key_dict.update({key: dict_val}) - if test_key_dict: - test_dict.update({k: test_key_dict}) - # below conditions checks are added to check if - # secondary IP is configured, if yes then delete - # the already configured IP if want and have IP - # is different else if it's same no need to delete - for each in v: - if each.get('secondary'): - want_ip = each.get('address').split('/') - have_ip = have.get('ipv4') - if len(want_ip) > 1 and have_ip and have_ip[0].get('secondary'): - have_ip = have_ip[0]['address'].split(' ')[0] - if have_ip != want_ip[0]: - diff_ip = True - if each.get('secondary') and diff_ip is True: - test_key_dict.update({'secondary': True}) - test_dict.update({'ipv4': test_key_dict}) - if v is None: - val = have.get(k) - test_dict.update({k: val}) - return test_dict - - -def remove_duplicate_interface(commands): - # Remove duplicate interface from commands - set_cmd = [] - for each in commands: - if 'interface' in each: - if each not in set_cmd: - set_cmd.append(each) - else: - set_cmd.append(each) - - return set_cmd - - -def validate_ipv4(value, module): - if value: - address = value.split('/') - if len(address) != 2: - module.fail_json(msg='address format is /, got invalid format {0}'.format(value)) - - if not is_masklen(address[1]): - module.fail_json(msg='invalid value for mask: {0}, mask should be in range 0-32'.format(address[1])) - - -def validate_ipv6(value, module): - if value: - address = value.split('/') - if len(address) != 2: - module.fail_json(msg='address format is /, got invalid format {0}'.format(value)) - else: - if not 0 <= int(address[1]) <= 128: - module.fail_json(msg='invalid value for mask: {0}, mask should be in range 0-128'.format(address[1])) - - -def validate_n_expand_ipv4(module, want): - # Check if input IPV4 is valid IP and expand IPV4 with its subnet mask - ip_addr_want = want.get('address') - if len(ip_addr_want.split(' ')) > 1: - return ip_addr_want - validate_ipv4(ip_addr_want, module) - ip = ip_addr_want.split('/') - if len(ip) == 2: - ip_addr_want = '{0} {1}'.format(ip[0], to_netmask(ip[1])) - - return ip_addr_want - - -def netmask_to_cidr(netmask): - bit_range = [128, 64, 32, 16, 8, 4, 2, 1] - count = 0 - cidr = 0 - netmask_list = netmask.split('.') - netmask_calc = [i for i in netmask_list if int(i) != 255 and int(i) != 0] - if netmask_calc: - netmask_calc_index = netmask_list.index(netmask_calc[0]) - elif sum(list(map(int, netmask_list))) == 0: - return '32' - else: - return '24' - for each in bit_range: - if cidr == int(netmask.split('.')[2]): - if netmask_calc_index == 1: - return str(8 + count) - elif netmask_calc_index == 2: - return str(8 * 2 + count) - elif netmask_calc_index == 3: - return str(8 * 3 + count) - break - cidr += each - count += 1 - - -def normalize_interface(name): - """Return the normalized interface name - """ - if not name: - return - - def _get_number(name): - digits = '' - for char in name: - if char.isdigit() or char in '/.': - digits += char - return digits - - if name.lower().startswith('gi'): - if_type = 'GigabitEthernet' - elif name.lower().startswith('te'): - if_type = 'TenGigabitEthernet' - elif name.lower().startswith('fa'): - if_type = 'FastEthernet' - elif name.lower().startswith('fo'): - if_type = 'FortyGigabitEthernet' - elif name.lower().startswith('long'): - if_type = 'LongReachEthernet' - elif name.lower().startswith('et'): - if_type = 'Ethernet' - elif name.lower().startswith('vl'): - if_type = 'Vlan' - elif name.lower().startswith('lo'): - if_type = 'loopback' - elif name.lower().startswith('po'): - if_type = 'Port-channel' - elif name.lower().startswith('nv'): - if_type = 'nve' - elif name.lower().startswith('twe'): - if_type = 'TwentyFiveGigE' - elif name.lower().startswith('hu'): - if_type = 'HundredGigE' - else: - if_type = None - - number_list = name.split(' ') - if len(number_list) == 2: - number = number_list[-1].strip() - else: - number = _get_number(name) - - if if_type: - proper_interface = if_type + number - else: - proper_interface = name - - return proper_interface - - -def get_interface_type(interface): - """Gets the type of interface - """ - - if interface.upper().startswith('GI'): - return 'GigabitEthernet' - elif interface.upper().startswith('TE'): - return 'TenGigabitEthernet' - elif interface.upper().startswith('FA'): - return 'FastEthernet' - elif interface.upper().startswith('FO'): - return 'FortyGigabitEthernet' - elif interface.upper().startswith('LON'): - return 'LongReachEthernet' - elif interface.upper().startswith('ET'): - return 'Ethernet' - elif interface.upper().startswith('VL'): - return 'Vlan' - elif interface.upper().startswith('LO'): - return 'loopback' - elif interface.upper().startswith('PO'): - return 'Port-channel' - elif interface.upper().startswith('NV'): - return 'nve' - elif interface.upper().startswith('TWE'): - return 'TwentyFiveGigE' - elif interface.upper().startswith('HU'): - return 'HundredGigE' - else: - return 'unknown' diff --git a/lib/ansible/modules/network/ios/_ios_interface.py b/lib/ansible/modules/network/ios/_ios_interface.py deleted file mode 100644 index d6241acb163..00000000000 --- a/lib/ansible/modules/network/ios/_ios_interface.py +++ /dev/null @@ -1,495 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['deprecated'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_interface -version_added: "2.4" -author: "Ganesh Nalawade (@ganeshrn)" -short_description: Manage Interface on Cisco IOS network devices -description: - - This module provides declarative management of Interfaces - on Cisco IOS network devices. -deprecated: - removed_in: '2.13' - alternative: ios_interfaces - why: Newer and updated modules released with more functionality in Ansible 2.9 -notes: - - Tested against IOS 15.6 -options: - name: - description: - - Name of the Interface. - required: true - description: - description: - - Description of Interface. - enabled: - description: - - Interface link status. - type: bool - speed: - description: - - Interface link speed. - mtu: - description: - - Maximum size of transmit packet. - duplex: - description: - - Interface link status - default: auto - choices: ['full', 'half', 'auto'] - tx_rate: - description: - - Transmit rate in bits per second (bps). - - This is state check parameter only. - - Supports conditionals, see L(Conditionals in Networking Modules,../network/user_guide/network_working_with_command_output.html) - rx_rate: - description: - - Receiver rate in bits per second (bps). - - This is state check parameter only. - - Supports conditionals, see L(Conditionals in Networking Modules,../network/user_guide/network_working_with_command_output.html) - neighbors: - description: - - Check the operational state of given interface C(name) for CDP/LLDP neighbor. - - The following suboptions are available. - suboptions: - host: - description: - - "CDP/LLDP neighbor host for given interface C(name)." - port: - description: - - "CDP/LLDP neighbor port to which given interface C(name) is connected." - aggregate: - description: List of Interfaces definitions. - delay: - description: - - Time in seconds to wait before checking for the operational state on remote - device. This wait is applicable for operational state argument which are - I(state) with values C(up)/C(down), I(tx_rate) and I(rx_rate). - default: 10 - state: - description: - - State of the Interface configuration, C(up) means present and - operationally up and C(down) means present and operationally C(down) - default: present - choices: ['present', 'absent', 'up', 'down'] -extends_documentation_fragment: ios -""" - -EXAMPLES = """ -- name: configure interface - ios_interface: - name: GigabitEthernet0/2 - description: test-interface - speed: 100 - duplex: half - mtu: 512 - -- name: remove interface - ios_interface: - name: Loopback9 - state: absent - -- name: make interface up - ios_interface: - name: GigabitEthernet0/2 - enabled: True - -- name: make interface down - ios_interface: - name: GigabitEthernet0/2 - enabled: False - -- name: Check intent arguments - ios_interface: - name: GigabitEthernet0/2 - state: up - tx_rate: ge(0) - rx_rate: le(0) - -- name: Check neighbors intent arguments - ios_interface: - name: Gi0/0 - neighbors: - - port: eth0 - host: netdev - -- name: Config + intent - ios_interface: - name: GigabitEthernet0/2 - enabled: False - state: down - -- name: Add interface using aggregate - ios_interface: - aggregate: - - { name: GigabitEthernet0/1, mtu: 256, description: test-interface-1 } - - { name: GigabitEthernet0/2, mtu: 516, description: test-interface-2 } - duplex: full - speed: 100 - state: present - -- name: Delete interface using aggregate - ios_interface: - aggregate: - - name: Loopback9 - - name: Loopback10 - state: absent -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device. - returned: always, except for the platforms that use Netconf transport to manage the device. - type: list - sample: - - interface GigabitEthernet0/2 - - description test-interface - - duplex half - - mtu 512 -""" -import re - -from copy import deepcopy -from time import sleep - -from ansible.module_utils._text import to_text -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.connection import exec_command -from ansible.module_utils.network.ios.ios import get_config, load_config -from ansible.module_utils.network.ios.ios import ios_argument_spec -from ansible.module_utils.network.common.config import NetworkConfig -from ansible.module_utils.network.common.utils import conditional, remove_default_spec - - -def validate_mtu(value, module): - if value and not 64 <= int(value) <= 9600: - module.fail_json(msg='mtu must be between 64 and 9600') - - -def validate_param_values(module, obj, param=None): - if param is None: - param = module.params - for key in obj: - # validate the param value (if validator func exists) - validator = globals().get('validate_%s' % key) - if callable(validator): - validator(param.get(key), module) - - -def parse_shutdown(configobj, name): - cfg = configobj['interface %s' % name] - cfg = '\n'.join(cfg.children) - match = re.search(r'^shutdown', cfg, re.M) - if match: - return True - else: - return False - - -def parse_config_argument(configobj, name, arg=None): - cfg = configobj['interface %s' % name] - cfg = '\n'.join(cfg.children) - match = re.search(r'%s (.+)$' % arg, cfg, re.M) - if match: - return match.group(1) - - -def search_obj_in_list(name, lst): - for o in lst: - if o['name'] == name: - return o - - return None - - -def add_command_to_interface(interface, cmd, commands): - if interface not in commands: - commands.append(interface) - commands.append(cmd) - - -def map_config_to_obj(module): - config = get_config(module) - configobj = NetworkConfig(indent=1, contents=config) - - match = re.findall(r'^interface (\S+)', config, re.M) - if not match: - return list() - - instances = list() - - for item in set(match): - obj = { - 'name': item, - 'description': parse_config_argument(configobj, item, 'description'), - 'speed': parse_config_argument(configobj, item, 'speed'), - 'duplex': parse_config_argument(configobj, item, 'duplex'), - 'mtu': parse_config_argument(configobj, item, 'mtu'), - 'disable': True if parse_shutdown(configobj, item) else False, - 'state': 'present' - } - instances.append(obj) - return instances - - -def map_params_to_obj(module): - obj = [] - aggregate = module.params.get('aggregate') - if aggregate: - for item in aggregate: - for key in item: - if item.get(key) is None: - item[key] = module.params[key] - - validate_param_values(module, item, item) - d = item.copy() - - if d['enabled']: - d['disable'] = False - else: - d['disable'] = True - - obj.append(d) - - else: - params = { - 'name': module.params['name'], - 'description': module.params['description'], - 'speed': module.params['speed'], - 'mtu': module.params['mtu'], - 'duplex': module.params['duplex'], - 'state': module.params['state'], - 'delay': module.params['delay'], - 'tx_rate': module.params['tx_rate'], - 'rx_rate': module.params['rx_rate'], - 'neighbors': module.params['neighbors'] - } - - validate_param_values(module, params) - if module.params['enabled']: - params.update({'disable': False}) - else: - params.update({'disable': True}) - - obj.append(params) - return obj - - -def map_obj_to_commands(updates): - commands = list() - want, have = updates - - args = ('speed', 'description', 'duplex', 'mtu') - for w in want: - name = w['name'] - disable = w['disable'] - state = w['state'] - - obj_in_have = search_obj_in_list(name, have) - interface = 'interface ' + name - - if state == 'absent' and obj_in_have: - commands.append('no ' + interface) - - elif state in ('present', 'up', 'down'): - if obj_in_have: - for item in args: - candidate = w.get(item) - running = obj_in_have.get(item) - if candidate != running: - if candidate: - cmd = item + ' ' + str(candidate) - add_command_to_interface(interface, cmd, commands) - - if disable and not obj_in_have.get('disable', False): - add_command_to_interface(interface, 'shutdown', commands) - elif not disable and obj_in_have.get('disable', False): - add_command_to_interface(interface, 'no shutdown', commands) - else: - commands.append(interface) - for item in args: - value = w.get(item) - if value: - commands.append(item + ' ' + str(value)) - - if disable: - commands.append('no shutdown') - return commands - - -def check_declarative_intent_params(module, want, result): - failed_conditions = [] - have_neighbors_lldp = None - have_neighbors_cdp = None - for w in want: - want_state = w.get('state') - want_tx_rate = w.get('tx_rate') - want_rx_rate = w.get('rx_rate') - want_neighbors = w.get('neighbors') - - if want_state not in ('up', 'down') and not want_tx_rate and not want_rx_rate and not want_neighbors: - continue - - if result['changed']: - sleep(w['delay']) - - command = 'show interfaces %s' % w['name'] - rc, out, err = exec_command(module, command) - if rc != 0: - module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) - - if want_state in ('up', 'down'): - match = re.search(r'%s (\w+)' % 'line protocol is', out, re.M) - have_state = None - if match: - have_state = match.group(1) - if have_state is None or not conditional(want_state, have_state.strip()): - failed_conditions.append('state ' + 'eq(%s)' % want_state) - - if want_tx_rate: - match = re.search(r'%s (\d+)' % 'output rate', out, re.M) - have_tx_rate = None - if match: - have_tx_rate = match.group(1) - - if have_tx_rate is None or not conditional(want_tx_rate, have_tx_rate.strip(), cast=int): - failed_conditions.append('tx_rate ' + want_tx_rate) - - if want_rx_rate: - match = re.search(r'%s (\d+)' % 'input rate', out, re.M) - have_rx_rate = None - if match: - have_rx_rate = match.group(1) - - if have_rx_rate is None or not conditional(want_rx_rate, have_rx_rate.strip(), cast=int): - failed_conditions.append('rx_rate ' + want_rx_rate) - - if want_neighbors: - have_host = [] - have_port = [] - - # Process LLDP neighbors - if have_neighbors_lldp is None: - rc, have_neighbors_lldp, err = exec_command(module, 'show lldp neighbors detail') - if rc != 0: - module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) - - if have_neighbors_lldp: - lines = have_neighbors_lldp.strip().split('Local Intf: ') - for line in lines: - field = line.split('\n') - if field[0].strip() == w['name']: - for item in field: - if item.startswith('System Name:'): - have_host.append(item.split(':')[1].strip()) - if item.startswith('Port Description:'): - have_port.append(item.split(':')[1].strip()) - - # Process CDP neighbors - if have_neighbors_cdp is None: - rc, have_neighbors_cdp, err = exec_command(module, 'show cdp neighbors detail') - if rc != 0: - module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) - - if have_neighbors_cdp: - neighbors_cdp = re.findall('Device ID: (.*?)\n.*?Interface: (.*?), Port ID .outgoing port.: (.*?)\n', have_neighbors_cdp, re.S) - for host, localif, remoteif in neighbors_cdp: - if localif == w['name']: - have_host.append(host) - have_port.append(remoteif) - - for item in want_neighbors: - host = item.get('host') - port = item.get('port') - if host and host not in have_host: - failed_conditions.append('host ' + host) - if port and port not in have_port: - failed_conditions.append('port ' + port) - return failed_conditions - - -def main(): - """ main entry point for module execution - """ - neighbors_spec = dict( - host=dict(), - port=dict() - ) - - element_spec = dict( - name=dict(), - description=dict(), - speed=dict(), - mtu=dict(), - duplex=dict(choices=['full', 'half', 'auto']), - enabled=dict(default=True, type='bool'), - tx_rate=dict(), - rx_rate=dict(), - neighbors=dict(type='list', elements='dict', options=neighbors_spec), - delay=dict(default=10, type='int'), - state=dict(default='present', - choices=['present', 'absent', 'up', 'down']) - ) - - aggregate_spec = deepcopy(element_spec) - aggregate_spec['name'] = dict(required=True) - - # remove default in aggregate spec, to handle common arguments - remove_default_spec(aggregate_spec) - - argument_spec = dict( - aggregate=dict(type='list', elements='dict', options=aggregate_spec), - ) - - argument_spec.update(element_spec) - argument_spec.update(ios_argument_spec) - - required_one_of = [['name', 'aggregate']] - mutually_exclusive = [['name', 'aggregate']] - - module = AnsibleModule(argument_spec=argument_spec, - required_one_of=required_one_of, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True) - warnings = list() - - result = {'changed': False} - if warnings: - result['warnings'] = warnings - - want = map_params_to_obj(module) - have = map_config_to_obj(module) - - commands = map_obj_to_commands((want, have)) - result['commands'] = commands - - if commands: - if not module.check_mode: - load_config(module, commands) - result['changed'] = True - - failed_conditions = check_declarative_intent_params(module, want, result) - - if failed_conditions: - msg = 'One or more conditional statements have not been satisfied' - module.fail_json(msg=msg, failed_conditions=failed_conditions) - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/_ios_l2_interface.py b/lib/ansible/modules/network/ios/_ios_l2_interface.py deleted file mode 100644 index 710c435c4e7..00000000000 --- a/lib/ansible/modules/network/ios/_ios_l2_interface.py +++ /dev/null @@ -1,499 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['deprecated'], - 'supported_by': 'network'} - -DOCUMENTATION = """ ---- -module: ios_l2_interface -extends_documentation_fragment: ios -version_added: "2.5" -short_description: Manage Layer-2 interface on Cisco IOS devices. -description: - - This module provides declarative management of Layer-2 interfaces on - Cisco IOS devices. -deprecated: - removed_in: '2.13' - alternative: ios_l2_interfaces - why: Newer and updated modules released with more functionality in Ansible 2.9 -author: - - Nathaniel Case (@Qalthos) -options: - name: - description: - - Full name of the interface excluding any logical - unit number, i.e. GigabitEthernet0/1. - required: true - aliases: ['interface'] - mode: - description: - - Mode in which interface needs to be configured. - default: access - choices: ['access', 'trunk'] - access_vlan: - description: - - Configure given VLAN in access port. - If C(mode=access), used as the access VLAN ID. - trunk_vlans: - description: - - List of VLANs to be configured in trunk port. - If C(mode=trunk), used as the VLAN range to ADD or REMOVE - from the trunk. - native_vlan: - description: - - Native VLAN to be configured in trunk port. - If C(mode=trunk), used as the trunk native VLAN ID. - trunk_allowed_vlans: - description: - - List of allowed VLANs in a given trunk port. - If C(mode=trunk), these are the only VLANs that will be - configured on the trunk, i.e. "2-10,15". - aggregate: - description: - - List of Layer-2 interface definitions. - state: - description: - - Manage the state of the Layer-2 Interface configuration. - default: present - choices: ['present','absent', 'unconfigured'] -""" - -EXAMPLES = """ -- name: Ensure GigabitEthernet0/5 is in its default l2 interface state - ios_l2_interface: - name: GigabitEthernet0/5 - state: unconfigured -- name: Ensure GigabitEthernet0/5 is configured for access vlan 20 - ios_l2_interface: - name: GigabitEthernet0/5 - mode: access - access_vlan: 20 -- name: Ensure GigabitEthernet0/5 only has vlans 5-10 as trunk vlans - ios_l2_interface: - name: GigabitEthernet0/5 - mode: trunk - native_vlan: 10 - trunk_allowed_vlans: 5-10 -- name: Ensure GigabitEthernet0/5 is a trunk port and ensure 2-50 are being tagged (doesn't mean others aren't also being tagged) - ios_l2_interface: - name: GigabitEthernet0/5 - mode: trunk - native_vlan: 10 - trunk_vlans: 2-50 -- name: Ensure these VLANs are not being tagged on the trunk - ios_l2_interface: - name: GigabitEthernet0/5 - mode: trunk - trunk_vlans: 51-4094 - state: absent -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always, except for the platforms that use Netconf transport to manage the device. - type: list - sample: - - interface GigabitEthernet0/5 - - switchport access vlan 20 -""" - -import re -from copy import deepcopy - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.utils import remove_default_spec -from ansible.module_utils.network.ios.ios import load_config, run_commands -from ansible.module_utils.network.ios.ios import ios_argument_spec - - -def get_interface_type(interface): - intf_type = 'unknown' - if interface.upper()[:2] in ('ET', 'GI', 'FA', 'TE', 'FO', 'HU', 'TWE', 'TW'): - intf_type = 'ethernet' - elif interface.upper().startswith('VL'): - intf_type = 'svi' - elif interface.upper().startswith('LO'): - intf_type = 'loopback' - elif interface.upper()[:2] in ('MG', 'MA'): - intf_type = 'management' - elif interface.upper().startswith('PO'): - intf_type = 'portchannel' - elif interface.upper().startswith('NV'): - intf_type = 'nve' - - return intf_type - - -def is_switchport(name, module): - intf_type = get_interface_type(name) - - if intf_type in ('ethernet', 'portchannel'): - config = run_commands(module, ['show interface {0} switchport'.format(name)])[0] - match = re.search(r'Switchport: Enabled', config) - return bool(match) - return False - - -def interface_is_portchannel(name, module): - if get_interface_type(name) == 'ethernet': - config = run_commands(module, ['show run interface {0}'.format(name)])[0] - if any(c in config for c in ['channel group', 'channel-group']): - return True - return False - - -def get_switchport(name, module): - config = run_commands(module, ['show interface {0} switchport'.format(name)])[0] - mode = re.search(r'Administrative Mode: (?:.* )?(\w+)$', config, re.M) - access = re.search(r'Access Mode VLAN: (\d+)', config) - native = re.search(r'Trunking Native Mode VLAN: (\d+)', config) - trunk = re.search(r'Trunking VLANs Enabled: (.+)$', config, re.M) - if mode: - mode = mode.group(1) - if access: - access = access.group(1) - if native: - native = native.group(1) - if trunk: - trunk = trunk.group(1) - if trunk == 'ALL': - trunk = '1-4094' - - switchport_config = { - "interface": name, - "mode": mode, - "access_vlan": access, - "native_vlan": native, - "trunk_vlans": trunk, - } - - return switchport_config - - -def remove_switchport_config_commands(name, existing, proposed, module): - mode = proposed.get('mode') - commands = [] - command = None - - if mode == 'access': - av_check = existing.get('access_vlan') == proposed.get('access_vlan') - if av_check: - command = 'no switchport access vlan {0}'.format(existing.get('access_vlan')) - commands.append(command) - - elif mode == 'trunk': - # Supported Remove Scenarios for trunk_vlans_list - # 1) Existing: 1,2,3 Proposed: 1,2,3 - Remove all - # 2) Existing: 1,2,3 Proposed: 1,2 - Remove 1,2 Leave 3 - # 3) Existing: 1,2,3 Proposed: 2,3 - Remove 2,3 Leave 1 - # 4) Existing: 1,2,3 Proposed: 4,5,6 - None removed. - # 5) Existing: None Proposed: 1,2,3 - None removed. - existing_vlans = existing.get('trunk_vlans_list') - proposed_vlans = proposed.get('trunk_vlans_list') - vlans_to_remove = set(proposed_vlans).intersection(existing_vlans) - - if vlans_to_remove: - proposed_allowed_vlans = proposed.get('trunk_allowed_vlans') - remove_trunk_allowed_vlans = proposed.get('trunk_vlans', proposed_allowed_vlans) - command = 'switchport trunk allowed vlan remove {0}'.format(remove_trunk_allowed_vlans) - commands.append(command) - - native_check = existing.get('native_vlan') == proposed.get('native_vlan') - if native_check and proposed.get('native_vlan'): - command = 'no switchport trunk native vlan {0}'.format(existing.get('native_vlan')) - commands.append(command) - - if commands: - commands.insert(0, 'interface ' + name) - return commands - - -def get_switchport_config_commands(name, existing, proposed, module): - """Gets commands required to config a given switchport interface - """ - - proposed_mode = proposed.get('mode') - existing_mode = existing.get('mode') - commands = [] - command = None - - if proposed_mode != existing_mode: - if proposed_mode == 'trunk': - command = 'switchport mode trunk' - elif proposed_mode == 'access': - command = 'switchport mode access' - - if command: - commands.append(command) - - if proposed_mode == 'access': - av_check = str(existing.get('access_vlan')) == str(proposed.get('access_vlan')) - if not av_check: - command = 'switchport access vlan {0}'.format(proposed.get('access_vlan')) - commands.append(command) - - elif proposed_mode == 'trunk': - tv_check = existing.get('trunk_vlans_list') == proposed.get('trunk_vlans_list') - - if not tv_check: - if proposed.get('allowed'): - command = 'switchport trunk allowed vlan {0}'.format(proposed.get('trunk_allowed_vlans')) - commands.append(command) - - else: - existing_vlans = existing.get('trunk_vlans_list') - proposed_vlans = proposed.get('trunk_vlans_list') - vlans_to_add = set(proposed_vlans).difference(existing_vlans) - if vlans_to_add: - command = 'switchport trunk allowed vlan add {0}'.format(proposed.get('trunk_vlans')) - commands.append(command) - - native_check = str(existing.get('native_vlan')) == str(proposed.get('native_vlan')) - if not native_check and proposed.get('native_vlan'): - command = 'switchport trunk native vlan {0}'.format(proposed.get('native_vlan')) - commands.append(command) - - if commands: - commands.insert(0, 'interface ' + name) - return commands - - -def is_switchport_default(existing): - """Determines if switchport has a default config based on mode - Args: - existing (dict): existing switchport configuration from Ansible mod - Returns: - boolean: True if switchport has OOB Layer 2 config, i.e. - vlan 1 and trunk all and mode is access - """ - - c1 = str(existing['access_vlan']) == '1' - c2 = str(existing['native_vlan']) == '1' - c3 = existing['trunk_vlans'] == '1-4094' - c4 = existing['mode'] == 'access' - - default = c1 and c2 and c3 and c4 - - return default - - -def default_switchport_config(name): - commands = [] - commands.append('interface ' + name) - commands.append('switchport mode access') - commands.append('switch access vlan 1') - commands.append('switchport trunk native vlan 1') - commands.append('switchport trunk allowed vlan all') - return commands - - -def vlan_range_to_list(vlans): - result = [] - if vlans: - for part in vlans.split(','): - if part.lower() == 'none': - break - if part: - if '-' in part: - start, stop = (int(i) for i in part.split('-')) - result.extend(range(start, stop + 1)) - else: - result.append(int(part)) - return sorted(result) - - -def get_list_of_vlans(module): - config = run_commands(module, ['show vlan'])[0] - vlans = set() - - lines = config.strip().splitlines() - for line in lines: - line_parts = line.split() - if line_parts: - try: - int(line_parts[0]) - except ValueError: - continue - vlans.add(line_parts[0]) - - return list(vlans) - - -def flatten_list(commands): - flat_list = [] - for command in commands: - if isinstance(command, list): - flat_list.extend(command) - else: - flat_list.append(command) - return flat_list - - -def map_params_to_obj(module): - obj = [] - - aggregate = module.params.get('aggregate') - if aggregate: - for item in aggregate: - for key in item: - if item.get(key) is None: - item[key] = module.params[key] - - obj.append(item.copy()) - else: - obj.append({ - 'name': module.params['name'], - 'mode': module.params['mode'], - 'access_vlan': module.params['access_vlan'], - 'native_vlan': module.params['native_vlan'], - 'trunk_vlans': module.params['trunk_vlans'], - 'trunk_allowed_vlans': module.params['trunk_allowed_vlans'], - 'state': module.params['state'] - }) - - return obj - - -def main(): - """ main entry point for module execution - """ - element_spec = dict( - name=dict(type='str', aliases=['interface']), - mode=dict(choices=['access', 'trunk']), - access_vlan=dict(type='str'), - native_vlan=dict(type='str'), - trunk_vlans=dict(type='str'), - trunk_allowed_vlans=dict(type='str'), - state=dict(choices=['absent', 'present', 'unconfigured'], default='present') - ) - - aggregate_spec = deepcopy(element_spec) - - # remove default in aggregate spec, to handle common arguments - remove_default_spec(aggregate_spec) - - argument_spec = dict( - aggregate=dict(type='list', elements='dict', options=aggregate_spec), - ) - - argument_spec.update(element_spec) - argument_spec.update(ios_argument_spec) - - module = AnsibleModule(argument_spec=argument_spec, - mutually_exclusive=[['access_vlan', 'trunk_vlans'], - ['access_vlan', 'native_vlan'], - ['access_vlan', 'trunk_allowed_vlans']], - supports_check_mode=True) - - warnings = list() - commands = [] - result = {'changed': False, 'warnings': warnings} - - want = map_params_to_obj(module) - for w in want: - name = w['name'] - mode = w['mode'] - access_vlan = w['access_vlan'] - state = w['state'] - trunk_vlans = w['trunk_vlans'] - native_vlan = w['native_vlan'] - trunk_allowed_vlans = w['trunk_allowed_vlans'] - - args = dict(name=name, mode=mode, access_vlan=access_vlan, - native_vlan=native_vlan, trunk_vlans=trunk_vlans, - trunk_allowed_vlans=trunk_allowed_vlans) - - proposed = dict((k, v) for k, v in args.items() if v is not None) - - name = name.lower() - - if mode == 'access' and state == 'present' and not access_vlan: - module.fail_json(msg='access_vlan param is required when mode=access && state=present') - - if mode == 'trunk' and access_vlan: - module.fail_json(msg='access_vlan param not supported when using mode=trunk') - - if not is_switchport(name, module): - module.fail_json(msg='Ensure interface is configured to be a L2' - '\nport first before using this module. You can use' - '\nthe ios_interface module for this.') - - if interface_is_portchannel(name, module): - module.fail_json(msg='Cannot change L2 config on physical ' - '\nport because it is in a portchannel. ' - '\nYou should update the portchannel config.') - - # existing will never be null for Eth intfs as there is always a default - existing = get_switchport(name, module) - - # Safeguard check - # If there isn't an existing, something is wrong per previous comment - if not existing: - module.fail_json(msg='Make sure you are using the FULL interface name') - - if trunk_vlans or trunk_allowed_vlans: - if trunk_vlans: - trunk_vlans_list = vlan_range_to_list(trunk_vlans) - elif trunk_allowed_vlans: - trunk_vlans_list = vlan_range_to_list(trunk_allowed_vlans) - proposed['allowed'] = True - - existing_trunks_list = vlan_range_to_list((existing['trunk_vlans'])) - - existing['trunk_vlans_list'] = existing_trunks_list - proposed['trunk_vlans_list'] = trunk_vlans_list - - current_vlans = get_list_of_vlans(module) - - if state == 'present': - if access_vlan and access_vlan not in current_vlans: - module.fail_json(msg='You are trying to configure a VLAN' - ' on an interface that\ndoes not exist on the ' - ' switch yet!', vlan=access_vlan) - elif native_vlan and native_vlan not in current_vlans: - module.fail_json(msg='You are trying to configure a VLAN' - ' on an interface that\ndoes not exist on the ' - ' switch yet!', vlan=native_vlan) - else: - command = get_switchport_config_commands(name, existing, proposed, module) - commands.append(command) - elif state == 'unconfigured': - is_default = is_switchport_default(existing) - if not is_default: - command = default_switchport_config(name) - commands.append(command) - elif state == 'absent': - command = remove_switchport_config_commands(name, existing, proposed, module) - commands.append(command) - - if trunk_vlans or trunk_allowed_vlans: - existing.pop('trunk_vlans_list') - proposed.pop('trunk_vlans_list') - - cmds = flatten_list(commands) - if cmds: - if module.check_mode: - module.exit_json(changed=True, commands=cmds) - else: - result['changed'] = True - load_config(module, cmds) - if 'configure' in cmds: - cmds.pop(0) - - result['commands'] = cmds - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/_ios_l3_interface.py b/lib/ansible/modules/network/ios/_ios_l3_interface.py deleted file mode 100644 index 84357202406..00000000000 --- a/lib/ansible/modules/network/ios/_ios_l3_interface.py +++ /dev/null @@ -1,327 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['deprecated'], - 'supported_by': 'network'} - -DOCUMENTATION = """ ---- -module: ios_l3_interface -version_added: "2.5" -author: "Ganesh Nalawade (@ganeshrn)" -short_description: Manage Layer-3 interfaces on Cisco IOS network devices. -description: - - This module provides declarative management of Layer-3 interfaces - on IOS network devices. -deprecated: - removed_in: '2.13' - alternative: ios_l3_interfaces - why: Newer and updated modules released with more functionality in Ansible 2.9 -notes: - - Tested against IOS 15.2 -options: - name: - description: - - Name of the Layer-3 interface to be configured eg. GigabitEthernet0/2 - ipv4: - description: - - IPv4 address to be set for the Layer-3 interface mentioned in I(name) option. - The address format is /, the mask is number - in range 0-32 eg. 192.168.0.1/24 - ipv6: - description: - - IPv6 address to be set for the Layer-3 interface mentioned in I(name) option. - The address format is /, the mask is number - in range 0-128 eg. fd5d:12c9:2201:1::1/64 - aggregate: - description: - - List of Layer-3 interfaces definitions. Each of the entry in aggregate list should - define name of interface C(name) and a optional C(ipv4) or C(ipv6) address. - state: - description: - - State of the Layer-3 interface configuration. It indicates if the configuration should - be present or absent on remote device. - default: present - choices: ['present', 'absent'] -extends_documentation_fragment: ios -""" - -EXAMPLES = """ -- name: Remove GigabitEthernet0/3 IPv4 and IPv6 address - ios_l3_interface: - name: GigabitEthernet0/3 - state: absent -- name: Set GigabitEthernet0/3 IPv4 address - ios_l3_interface: - name: GigabitEthernet0/3 - ipv4: 192.168.0.1/24 -- name: Set GigabitEthernet0/3 IPv6 address - ios_l3_interface: - name: GigabitEthernet0/3 - ipv6: "fd5d:12c9:2201:1::1/64" -- name: Set GigabitEthernet0/3 in dhcp - ios_l3_interface: - name: GigabitEthernet0/3 - ipv4: dhcp - ipv6: dhcp -- name: Set interface Vlan1 (SVI) IPv4 address - ios_l3_interface: - name: Vlan1 - ipv4: 192.168.0.5/24 -- name: Set IP addresses on aggregate - ios_l3_interface: - aggregate: - - { name: GigabitEthernet0/3, ipv4: 192.168.2.10/24 } - - { name: GigabitEthernet0/3, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" } -- name: Remove IP addresses on aggregate - ios_l3_interface: - aggregate: - - { name: GigabitEthernet0/3, ipv4: 192.168.2.10/24 } - - { name: GigabitEthernet0/3, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" } - state: absent -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always, except for the platforms that use Netconf transport to manage the device. - type: list - sample: - - interface GigabitEthernet0/2 - - ip address 192.168.0.1 255.255.255.0 - - ipv6 address fd5d:12c9:2201:1::1/64 -""" -import re - -from copy import deepcopy - -from ansible.module_utils._text import to_text -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.ios import get_config, load_config -from ansible.module_utils.network.ios.ios import ios_argument_spec -from ansible.module_utils.network.common.config import NetworkConfig -from ansible.module_utils.network.common.utils import remove_default_spec -from ansible.module_utils.network.common.utils import is_netmask, is_masklen, to_netmask, to_masklen - - -def validate_ipv4(value, module): - if value: - address = value.split('/') - if len(address) != 2: - module.fail_json(msg='address format is /, got invalid format %s' % value) - - if not is_masklen(address[1]): - module.fail_json(msg='invalid value for mask: %s, mask should be in range 0-32' % address[1]) - - -def validate_ipv6(value, module): - if value: - address = value.split('/') - if len(address) != 2: - module.fail_json(msg='address format is /, got invalid format %s' % value) - else: - if not 0 <= int(address[1]) <= 128: - module.fail_json(msg='invalid value for mask: %s, mask should be in range 0-128' % address[1]) - - -def validate_param_values(module, obj, param=None): - if param is None: - param = module.params - for key in obj: - # validate the param value (if validator func exists) - validator = globals().get('validate_%s' % key) - if callable(validator): - validator(param.get(key), module) - - -def parse_config_argument(configobj, name, arg=None): - cfg = configobj['interface %s' % name] - cfg = '\n'.join(cfg.children) - - values = [] - matches = re.finditer(r'%s (.+)$' % arg, cfg, re.M) - for match in matches: - match_str = match.group(1).strip() - if arg == 'ipv6 address': - values.append(match_str) - else: - values = match_str - break - - return values or None - - -def search_obj_in_list(name, lst): - for o in lst: - if o['name'] == name: - return o - - return None - - -def map_obj_to_commands(updates, module): - commands = list() - want, have = updates - for w in want: - name = w['name'] - ipv4 = w['ipv4'] - ipv6 = w['ipv6'] - state = w['state'] - - interface = 'interface ' + name - commands.append(interface) - - obj_in_have = search_obj_in_list(name, have) - if state == 'absent' and obj_in_have: - if obj_in_have['ipv4']: - if ipv4: - address = ipv4.split('/') - if len(address) == 2: - ipv4 = '{0} {1}'.format(address[0], to_netmask(address[1])) - commands.append('no ip address {0}'.format(ipv4)) - else: - commands.append('no ip address') - if obj_in_have['ipv6']: - if ipv6: - commands.append('no ipv6 address {0}'.format(ipv6)) - else: - commands.append('no ipv6 address') - if 'dhcp' in obj_in_have['ipv6']: - commands.append('no ipv6 address dhcp') - - elif state == 'present': - if ipv4: - if obj_in_have is None or obj_in_have.get('ipv4') is None or ipv4 != obj_in_have['ipv4']: - address = ipv4.split('/') - if len(address) == 2: - ipv4 = '{0} {1}'.format(address[0], to_netmask(address[1])) - commands.append('ip address {0}'.format(ipv4)) - - if ipv6: - if obj_in_have is None or obj_in_have.get('ipv6') is None or ipv6.lower() not in [addr.lower() for addr in obj_in_have['ipv6']]: - commands.append('ipv6 address {0}'.format(ipv6)) - - if commands[-1] == interface: - commands.pop(-1) - - return commands - - -def map_config_to_obj(module): - config = get_config(module) - configobj = NetworkConfig(indent=1, contents=config) - - match = re.findall(r'^interface (\S+)', config, re.M) - if not match: - return list() - - instances = list() - - for item in set(match): - ipv4 = parse_config_argument(configobj, item, 'ip address') - if ipv4: - # eg. 192.168.2.10 255.255.255.0 -> 192.168.2.10/24 - address = ipv4.strip().split(' ') - if len(address) == 2 and is_netmask(address[1]): - ipv4 = '{0}/{1}'.format(address[0], to_text(to_masklen(address[1]))) - - obj = { - 'name': item, - 'ipv4': ipv4, - 'ipv6': parse_config_argument(configobj, item, 'ipv6 address'), - 'state': 'present' - } - instances.append(obj) - - return instances - - -def map_params_to_obj(module): - obj = [] - - aggregate = module.params.get('aggregate') - if aggregate: - for item in aggregate: - for key in item: - if item.get(key) is None: - item[key] = module.params[key] - - validate_param_values(module, item, item) - obj.append(item.copy()) - else: - obj.append({ - 'name': module.params['name'], - 'ipv4': module.params['ipv4'], - 'ipv6': module.params['ipv6'], - 'state': module.params['state'] - }) - - validate_param_values(module, obj) - - return obj - - -def main(): - """ main entry point for module execution - """ - element_spec = dict( - name=dict(), - ipv4=dict(), - ipv6=dict(), - state=dict(default='present', - choices=['present', 'absent']) - ) - - aggregate_spec = deepcopy(element_spec) - aggregate_spec['name'] = dict(required=True) - - # remove default in aggregate spec, to handle common arguments - remove_default_spec(aggregate_spec) - - argument_spec = dict( - aggregate=dict(type='list', elements='dict', options=aggregate_spec), - ) - - argument_spec.update(element_spec) - argument_spec.update(ios_argument_spec) - - required_one_of = [['name', 'aggregate']] - mutually_exclusive = [['name', 'aggregate']] - module = AnsibleModule(argument_spec=argument_spec, - required_one_of=required_one_of, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True) - - warnings = list() - - result = {'changed': False} - - want = map_params_to_obj(module) - have = map_config_to_obj(module) - - commands = map_obj_to_commands((want, have), module) - result['commands'] = commands - - if commands: - if not module.check_mode: - resp = load_config(module, commands) - warnings.extend((out for out in resp if out)) - - result['changed'] = True - - if warnings: - result['warnings'] = warnings - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/_ios_vlan.py b/lib/ansible/modules/network/ios/_ios_vlan.py deleted file mode 100644 index d2b3dcf043b..00000000000 --- a/lib/ansible/modules/network/ios/_ios_vlan.py +++ /dev/null @@ -1,350 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['deprecated'], - 'supported_by': 'network'} - -DOCUMENTATION = """ ---- -module: ios_vlan -version_added: "2.5" -author: "Trishna Guha (@trishnaguha)" -short_description: Manage VLANs on IOS network devices -description: - - This module provides declarative management of VLANs - on Cisco IOS network devices. -deprecated: - removed_in: '2.13' - alternative: ios_vlans - why: Newer and updated modules released with more functionality in Ansible 2.9 -notes: - - Tested against IOS 15.2 -options: - name: - description: - - Name of the VLAN. - vlan_id: - description: - - ID of the VLAN. Range 1-4094. - required: true - interfaces: - description: - - List of interfaces that should be associated to the VLAN. - required: true - associated_interfaces: - description: - - This is a intent option and checks the operational state of the for given vlan C(name) - for associated interfaces. If the value in the C(associated_interfaces) does not match with - the operational state of vlan interfaces on device it will result in failure. - version_added: "2.5" - delay: - description: - - Delay the play should wait to check for declarative intent params values. - default: 10 - aggregate: - description: List of VLANs definitions. - purge: - description: - - Purge VLANs not defined in the I(aggregate) parameter. - default: no - type: bool - state: - description: - - State of the VLAN configuration. - default: present - choices: ['present', 'absent', 'active', 'suspend'] -extends_documentation_fragment: ios -""" - -EXAMPLES = """ -- name: Create vlan - ios_vlan: - vlan_id: 100 - name: test-vlan - state: present - -- name: Add interfaces to VLAN - ios_vlan: - vlan_id: 100 - interfaces: - - GigabitEthernet0/0 - - GigabitEthernet0/1 - -- name: Check if interfaces is assigned to VLAN - ios_vlan: - vlan_id: 100 - associated_interfaces: - - GigabitEthernet0/0 - - GigabitEthernet0/1 - -- name: Delete vlan - ios_vlan: - vlan_id: 100 - state: absent - -- name: Add vlan using aggregate - ios_vlan: - aggregate: - - { vlan_id: 100, name: test-vlan, interfaces: [GigabitEthernet0/1, GigabitEthernet0/2], delay: 15, state: suspend } - - { vlan_id: 101, name: test-vlan, interfaces: GigabitEthernet0/3 } - -- name: Move interfaces to a different VLAN - ios_vlan: - vlan_id: 102 - interfaces: - - GigabitEthernet0/0 - - GigabitEthernet0/1 -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always - type: list - sample: - - vlan 100 - - name test-vlan -""" - -import re -import time - -from copy import deepcopy - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.utils import remove_default_spec -from ansible.module_utils.network.ios.ios import load_config, run_commands, normalize_interface -from ansible.module_utils.network.ios.ios import ios_argument_spec - - -def search_obj_in_list(vlan_id, lst): - for o in lst: - if o['vlan_id'] == vlan_id: - return o - - -def map_obj_to_commands(updates, module): - commands = list() - want, have = updates - purge = module.params['purge'] - - for w in want: - vlan_id = w['vlan_id'] - name = w['name'] - interfaces = w['interfaces'] - state = w['state'] - - obj_in_have = search_obj_in_list(vlan_id, have) - - if state == 'absent': - if obj_in_have: - commands.append('no vlan {0}'.format(vlan_id)) - - elif state == 'present': - if not obj_in_have: - commands.append('vlan {0}'.format(vlan_id)) - if name: - commands.append('name {0}'.format(name)) - - if interfaces: - for i in interfaces: - commands.append('interface {0}'.format(i)) - commands.append('switchport mode access') - commands.append('switchport access vlan {0}'.format(vlan_id)) - - else: - if name: - if name != obj_in_have['name']: - commands.append('vlan {0}'.format(vlan_id)) - commands.append('name {0}'.format(name)) - - if interfaces: - if not obj_in_have['interfaces']: - for i in interfaces: - commands.append('vlan {0}'.format(vlan_id)) - commands.append('interface {0}'.format(i)) - commands.append('switchport mode access') - commands.append('switchport access vlan {0}'.format(vlan_id)) - - elif set(interfaces) != set(obj_in_have['interfaces']): - missing_interfaces = list(set(interfaces) - set(obj_in_have['interfaces'])) - for i in missing_interfaces: - commands.append('vlan {0}'.format(vlan_id)) - commands.append('interface {0}'.format(i)) - commands.append('switchport mode access') - commands.append('switchport access vlan {0}'.format(vlan_id)) - - superfluous_interfaces = list(set(obj_in_have['interfaces']) - set(interfaces)) - for i in superfluous_interfaces: - commands.append('vlan {0}'.format(vlan_id)) - commands.append('interface {0}'.format(i)) - commands.append('switchport mode access') - commands.append('no switchport access vlan {0}'.format(vlan_id)) - else: - commands.append('vlan {0}'.format(vlan_id)) - if name: - commands.append('name {0}'.format(name)) - commands.append('state {0}'.format(state)) - - if purge: - for h in have: - obj_in_want = search_obj_in_list(h['vlan_id'], want) - if not obj_in_want and h['vlan_id'] != '1': - commands.append('no vlan {0}'.format(h['vlan_id'])) - - return commands - - -def map_params_to_obj(module): - obj = [] - aggregate = module.params.get('aggregate') - if aggregate: - for item in aggregate: - for key in item: - if item.get(key) is None: - item[key] = module.params[key] - - d = item.copy() - d['vlan_id'] = str(d['vlan_id']) - - obj.append(d) - else: - obj.append({ - 'vlan_id': str(module.params['vlan_id']), - 'name': module.params['name'], - 'interfaces': module.params['interfaces'], - 'associated_interfaces': module.params['associated_interfaces'], - 'state': module.params['state'] - }) - - return obj - - -def parse_to_logical_rows(out): - started_yielding = False - cur_row = [] - for l in out.splitlines()[2:]: - if not l: - """Skip empty lines.""" - continue - if '0' < l[0] <= '9': - """Line starting with a number.""" - if started_yielding: - yield cur_row - cur_row = [] # Reset it to hold a next chunk - started_yielding = True - cur_row.append(l) - - # Return the rest of it: - yield cur_row - - -def map_ports_str_to_list(ports_str): - return list(filter(bool, (normalize_interface(p.strip()) for p in ports_str.split(', ')))) - - -def parse_to_obj(logical_rows): - first_row = logical_rows[0] - rest_rows = logical_rows[1:] - obj = re.match(r'(?P\d+)\s+(?P[^\s]+)\s+(?P[^\s]+)\s*(?P.*)', first_row).groupdict() - if obj['state'] == 'suspended': - obj['state'] = 'suspend' - obj['interfaces'] = map_ports_str_to_list(obj['interfaces']) - obj['interfaces'].extend(prts_r for prts in rest_rows for prts_r in map_ports_str_to_list(prts)) - return obj - - -def parse_vlan_brief(vlan_out): - return [parse_to_obj(r) for r in parse_to_logical_rows(vlan_out)] - - -def map_config_to_obj(module): - return parse_vlan_brief(run_commands(module, ['show vlan brief'])[0]) - - -def check_declarative_intent_params(want, module, result): - - have = None - is_delay = False - - for w in want: - if w.get('associated_interfaces') is None: - continue - - if result['changed'] and not is_delay: - time.sleep(module.params['delay']) - is_delay = True - - if have is None: - have = map_config_to_obj(module) - - for i in w['associated_interfaces']: - obj_in_have = search_obj_in_list(w['vlan_id'], have) - if obj_in_have and 'interfaces' in obj_in_have and i not in obj_in_have['interfaces']: - module.fail_json(msg="Interface %s not configured on vlan %s" % (i, w['vlan_id'])) - - -def main(): - """ main entry point for module execution - """ - element_spec = dict( - vlan_id=dict(type='int'), - name=dict(), - interfaces=dict(type='list'), - associated_interfaces=dict(type='list'), - delay=dict(default=10, type='int'), - state=dict(default='present', - choices=['present', 'absent', 'active', 'suspend']) - ) - - aggregate_spec = deepcopy(element_spec) - aggregate_spec['vlan_id'] = dict(required=True) - - # remove default in aggregate spec, to handle common arguments - remove_default_spec(aggregate_spec) - - argument_spec = dict( - aggregate=dict(type='list', elements='dict', options=aggregate_spec), - purge=dict(default=False, type='bool') - ) - - argument_spec.update(element_spec) - argument_spec.update(ios_argument_spec) - - required_one_of = [['vlan_id', 'aggregate']] - mutually_exclusive = [['vlan_id', 'aggregate']] - - module = AnsibleModule(argument_spec=argument_spec, - required_one_of=required_one_of, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True) - warnings = list() - result = {'changed': False} - if warnings: - result['warnings'] = warnings - - want = map_params_to_obj(module) - have = map_config_to_obj(module) - commands = map_obj_to_commands((want, have), module) - result['commands'] = commands - - if commands: - if not module.check_mode: - load_config(module, commands) - result['changed'] = True - - check_declarative_intent_params(want, module, result) - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_acl_interfaces.py b/lib/ansible/modules/network/ios/ios_acl_interfaces.py deleted file mode 100644 index 7286ac45a8d..00000000000 --- a/lib/ansible/modules/network/ios/ios_acl_interfaces.py +++ /dev/null @@ -1,633 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The module file for ios_acl_interfaces -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - -DOCUMENTATION = """ ---- -module: ios_acl_interfaces -version_added: '2.10' -short_description: Configure and manage access-control (ACL) attributes of interfaces on IOS devices. -description: This module configures and manages the access-control (ACL) attributes of interfaces on IOS platforms. -author: Sumit Jaiswal (@justjais) -notes: - - Tested against Cisco IOSv Version 15.2 on VIRL - - This module works with connection C(network_cli). - See L(IOS Platform Options,../network/user_guide/platform_ios.html). -options: - config: - description: A dictionary of ACL interfaces options - type: list - elements: dict - suboptions: - name: - description: Full name of the interface excluding any logical unit number, i.e. GigabitEthernet0/1. - type: str - required: True - access_groups: - description: Specify access-group for IP access list (standard or extended). - type: list - elements: dict - suboptions: - afi: - description: Specifies the AFI for the ACLs to be configured on this interface. - type: str - required: True - choices: - - ipv4 - - ipv6 - acls: - description: Specifies the ACLs for the provided AFI. - type: list - elements: dict - suboptions: - name: - description: Specifies the name of the IPv4/IPv4 ACL for the interface. - type: str - required: True - direction: - description: - - Specifies the direction of packets that the ACL will be applied on. - - With one direction already assigned, other acl direction cannot be same. - type: str - required: True - choices: - - in - - out - running_config: - description: - - The module, by default, will connect to the remote device and retrieve the current - running-config to use as a base for comparing against the contents of source. - There are times when it is not desirable to have the task get the current running-config - for every task in a playbook. The I(running_config) argument allows the implementer to - pass in the configuration to use as the base config for comparison. This value of this - option should be the output received from device by executing command. - type: str - state: - description: - - The state the configuration should be left in - type: str - choices: - - merged - - replaced - - overridden - - deleted - - gathered - - parsed - - rendered - default: merged -""" - -EXAMPLES = """ ---- - -# Using Merged - -# Before state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# interface GigabitEthernet0/2 -# ip access-group 123 out - -- name: "Merge module attributes of given access-groups" - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv4 - acls: - - name: 110 - direction: in - - name: 123 - direction: out - - afi: ipv6 - acls: - - name: test_v6 - direction: out - - name: temp_v6 - direction: in - - name: GigabitEthernet0/2 - access_groups: - - afi: ipv4 - acls: - - name: 100 - direction: in - state: merged - -# Commands Fired: -# --------------- -# -# interface GigabitEthernet0/1 -# ip access-group 110 in -# ip access-group 123 out -# ipv6 traffic-filter test_v6 out -# ipv6 traffic-filter temp_v6 in -# interface GigabitEthernet0/2 -# ip access-group 100 in -# ip access-group 123 out - - -# After state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# ip access-group 110 in -# ip access-group 123 out -# ipv6 traffic-filter test_v6 out -# ipv6 traffic-filter temp_v6 in -# interface GigabitEthernet0/2 -# ip access-group 110 in -# ip access-group 123 out - -# Using Replaced - -# Before state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# ip access-group 110 in -# ip access-group 123 out -# ipv6 traffic-filter test_v6 out -# ipv6 traffic-filter temp_v6 in -# interface GigabitEthernet0/2 -# ip access-group 110 in -# ip access-group 123 out - -- name: "Replace module attributes of given access-groups" - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv4 - acls: - - name: 100 - direction: out - - name: 110 - direction: in - state: replaced - -# Commands Fired: -# --------------- -# -# interface GigabitEthernet0/1 -# no ip access-group 123 out -# no ipv6 traffic-filter temp_v6 in -# no ipv6 traffic-filter test_v6 out -# ip access-group 100 out - -# After state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# ip access-group 100 out -# ip access-group 110 in -# interface GigabitEthernet0/2 -# ip access-group 110 in -# ip access-group 123 out - -# Using Overridden - -# Before state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# ip access-group 110 in -# ip access-group 123 out -# ipv6 traffic-filter test_v6 out -# ipv6 traffic-filter temp_v6 in -# interface GigabitEthernet0/2 -# ip access-group 110 in -# ip access-group 123 out - -- name: "Overridden module attributes of given access-groups" - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv4 - acls: - - name: 100 - direction: out - - name: 110 - direction: in - state: overridden - -# Commands Fired: -# --------------- -# -# interface GigabitEthernet0/1 -# no ip access-group 123 out -# no ipv6 traffic-filter test_v6 out -# no ipv6 traffic-filter temp_v6 in -# ip access-group 100 out -# interface GigabitEthernet0/2 -# no ip access-group 110 in -# no ip access-group 123 out - -# After state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# ip access-group 100 out -# ip access-group 110 in -# interface GigabitEthernet0/2 - -# Using Deleted - -# Before state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# ip access-group 110 in -# ip access-group 123 out -# ipv6 traffic-filter test_v6 out -# ipv6 traffic-filter temp_v6 in -# interface GigabitEthernet0/2 -# ip access-group 110 in -# ip access-group 123 out - -- name: "Delete module attributes of given Interface" - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - state: deleted - -# Commands Fired: -# --------------- -# -# interface GigabitEthernet0/1 -# no ip access-group 110 in -# no ip access-group 123 out -# no ipv6 traffic-filter test_v6 out -# no ipv6 traffic-filter temp_v6 in - -# After state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# interface GigabitEthernet0/2 -# ip access-group 110 in -# ip access-group 123 out - -# Before state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# ip access-group 110 in -# ip access-group 123 out -# ipv6 traffic-filter test_v6 out -# ipv6 traffic-filter temp_v6 in -# interface GigabitEthernet0/2 -# ip access-group 110 in -# ip access-group 123 out - -- name: "Delete module attributes of given Interface based on AFI" - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv4 - state: deleted - -# Commands Fired: -# --------------- -# -# interface GigabitEthernet0/1 -# no ip access-group 110 in -# no ip access-group 123 out - -# After state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# ipv6 traffic-filter test_v6 out -# ipv6 traffic-filter temp_v6 in -# interface GigabitEthernet0/2 -# ip access-group 110 in -# ip access-group 123 out - -# Using DELETED without any config passed -#"(NOTE: This will delete all of configured resource module attributes from each configured interface)" - -# Before state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# ip access-group 110 in -# ip access-group 123 out -# ipv6 traffic-filter test_v6 out -# ipv6 traffic-filter temp_v6 in -# interface GigabitEthernet0/2 -# ip access-group 110 in -# ip access-group 123 out - -- name: "Delete module attributes of given access-groups from ALL Interfaces" - ios_acl_interfaces: - config: - state: deleted - -# Commands Fired: -# --------------- -# -# interface GigabitEthernet0/1 -# no ip access-group 110 in -# no ip access-group 123 out -# no ipv6 traffic-filter test_v6 out -# no ipv6 traffic-filter temp_v6 in -# interface GigabitEthernet0/2 -# no ip access-group 110 out -# no ip access-group 123 out - -# After state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# interface GigabitEthernet0/2 - -# Using Gathered - -# Before state: -# ------------- -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# ip access-group 110 in -# ip access-group 123 out -# ipv6 traffic-filter test_v6 out -# ipv6 traffic-filter temp_v6 in -# interface GigabitEthernet0/2 -# ip access-group 110 in -# ip access-group 123 out - -- name: Gather listed acl interfaces with provided configurations - ios_acl_interfaces: - config: - state: gathered - -# Module Execution Result: -# ------------------------ -# -# "gathered": [ -# { -# "name": "Loopback888" -# }, -# { -# "name": "GigabitEthernet0/0" -# }, -# { -# "access_groups": [ -# { -# "acls": [ -# { -# "direction": "in", -# "name": "110" -# }, -# { -# "direction": "out", -# "name": "123" -# } -# ], -# "afi": "ipv4" -# }, -# { -# "acls": [ -# { -# "direction": "in", -# "name": "temp_v6" -# }, -# { -# "direction": "out", -# "name": "test_v6" -# } -# ], -# "afi": "ipv6" -# } -# ], -# "name": "GigabitEthernet0/1" -# }, -# { -# "access_groups": [ -# { -# "acls": [ -# { -# "direction": "in", -# "name": "100" -# }, -# { -# "direction": "out", -# "name": "123" -# } -# ], -# "afi": "ipv4" -# } -# ], -# "name": "GigabitEthernet0/2" -# } -# ] - -# After state: -# ------------ -# -# vios#sh running-config | include interface|ip access-group|ipv6 traffic-filter -# interface Loopback888 -# interface GigabitEthernet0/0 -# interface GigabitEthernet0/1 -# ip access-group 110 in -# ip access-group 123 out -# ipv6 traffic-filter test_v6 out -# ipv6 traffic-filter temp_v6 in -# interface GigabitEthernet0/2 -# ip access-group 110 in -# ip access-group 123 out - -# Using Rendered - -- name: Render the commands for provided configuration - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv4 - acls: - - name: 110 - direction: in - - name: 123 - direction: out - - afi: ipv6 - acls: - - name: test_v6 - direction: out - - name: temp_v6 - direction: in - state: rendered - -# Module Execution Result: -# ------------------------ -# -# "rendered": [ -# "interface GigabitEthernet0/1", -# "ip access-group 110 in", -# "ip access-group 123 out", -# "ipv6 traffic-filter temp_v6 in", -# "ipv6 traffic-filter test_v6 out" -# ] - -# Using Parsed - -- name: Parse the commands for provided configuration - ios_acl_interfaces: - running_config: - "interface GigabitEthernet0/1 - ip access-group 110 in - ip access-group 123 out - ipv6 traffic-filter temp_v6 in - ipv6 traffic-filter test_v6 out" - state: parsed - -# Module Execution Result: -# ------------------------ -# -# "parsed": [ -# { -# "access_groups": [ -# { -# "acls": [ -# { -# "direction": "in", -# "name": "110" -# } -# ], -# "afi": "ipv4" -# }, -# { -# "acls": [ -# { -# "direction": "in", -# "name": "temp_v6" -# } -# ], -# "afi": "ipv6" -# } -# ], -# "name": "GigabitEthernet0/1" -# } -# ] - -""" - -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: list - sample: The configuration returned will always be in the same format of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: list - sample: The configuration returned will always be in the same format of the parameters above. -commands: - description: The set of commands pushed to the remote device - returned: always - type: list - sample: ['interface GigabitEthernet0/1', 'ip access-group 110 in', 'ipv6 traffic-filter test_v6 out'] -""" - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.acl_interfaces.acl_interfaces import Acl_InterfacesArgs -from ansible.module_utils.network.ios.config.acl_interfaces.acl_interfaces import Acl_Interfaces - - -def main(): - """ - Main entry point for module execution - :returns: the result form module invocation - """ - required_if = [('state', 'merged', ('config',)), - ('state', 'replaced', ('config',)), - ('state', 'overridden', ('config',)), - ('state', 'rendered', ('config',)), - ('state', 'parsed', ('running_config',))] - - mutually_exclusive = [('config', 'running_config')] - - module = AnsibleModule(argument_spec=Acl_InterfacesArgs.argument_spec, - required_if=required_if, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True) - - result = Acl_Interfaces(module).execute_module() - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_acls.py b/lib/ansible/modules/network/ios/ios_acls.py deleted file mode 100644 index a05214d8e11..00000000000 --- a/lib/ansible/modules/network/ios/ios_acls.py +++ /dev/null @@ -1,1417 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The module file for ios_acls -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_acls -version_added: '2.10' -short_description: Manages named or numbered ACLs on IOS devices. -description: This module configures and manages the named or numbered ACLs on IOS platforms. -author: Sumit Jaiswal (@justjais) -notes: -- Tested against Cisco IOSv Version 15.2 on VIRL -- This module works with connection C(network_cli). - See L(IOS Platform Options,../network/user_guide/platform_ios.html). -options: - config: - description: A dictionary of ACL options. - type: list - elements: dict - suboptions: - afi: - description: - - The Address Family Indicator (AFI) for the Access Control Lists (ACL). - required: true - type: str - choices: - - ipv4 - - ipv6 - acls: - description: - - A list of Access Control Lists (ACL). - type: list - elements: dict - suboptions: - name: - description: The name or the number of the ACL. - required: true - type: str - acl_type: - description: - - ACL type - - Note, it's mandatory and required for Named ACL, but for - Numbered ACL it's not mandatory. - type: str - choices: - - extended - - standard - aces: - description: The entries within the ACL. - elements: dict - type: list - suboptions: - grant: - description: Specify the action. - type: str - choices: - - permit - - deny - sequence: - description: - - Sequence Number for the Access Control Entry(ACE). - - Refer to vendor documentation for valid values. - type: int - protocol: - description: - - Specify the protocol to match. - - Refer to vendor documentation for valid values. - type: str - protocol_options: - description: protocol type. - type: dict - suboptions: - protocol_number: - description: An IP protocol number - type: int - ahp: - description: Authentication Header Protocol. - type: bool - eigrp: - description: Cisco's EIGRP routing protocol. - type: bool - esp: - description: Encapsulation Security Payload. - type: bool - gre: - description: Cisco's GRE tunneling. - type: bool - hbh: - description: Hop by Hop options header. Valid for IPV6 - type: bool - icmp: - description: Internet Control Message Protocol. - type: dict - suboptions: - administratively_prohibited: - description: Administratively prohibited - type: bool - alternate_address: - description: Alternate address - type: bool - conversion_error: - description: Datagram conversion - type: bool - dod_host_prohibited: - description: Host prohibited - type: bool - dod_net_prohibited: - description: Net prohibited - type: bool - echo: - description: Echo (ping) - type: bool - echo_reply: - description: Echo reply - type: bool - general_parameter_problem: - description: Parameter problem - type: bool - host_isolated: - description: Host isolated - type: bool - host_precedence_unreachable: - description: Host unreachable for precedence - type: bool - host_redirect: - description: Host redirect - type: bool - host_tos_redirect: - description: Host redirect for TOS - type: bool - host_tos_unreachable: - description: Host unreachable for TOS - type: bool - host_unknown: - description: Host unknown - type: bool - host_unreachable: - description: Host unreachable - type: bool - information_reply: - description: Information replies - type: bool - information_request: - description: Information requests - type: bool - mask_reply: - description: Mask replies - type: bool - mask_request: - description: mask_request - type: bool - mobile_redirect: - description: Mobile host redirect - type: bool - net_redirect: - description: Network redirect - type: bool - net_tos_redirect: - description: Net redirect for TOS - type: bool - net_tos_unreachable: - description: Network unreachable for TOS - type: bool - net_unreachable: - description: Net unreachable - type: bool - network_unknown: - description: Network unknown - type: bool - no_room_for_option: - description: Parameter required but no room - type: bool - option_missing: - description: Parameter required but not present - type: bool - packet_too_big: - description: Fragmentation needed and DF set - type: bool - parameter_problem: - description: All parameter problems - type: bool - port_unreachable: - description: Port unreachable - type: bool - precedence_unreachable: - description: Precedence cutoff - type: bool - protocol_unreachable: - description: Protocol unreachable - type: bool - reassembly_timeout: - description: Reassembly timeout - type: bool - redirect: - description: All redirects - type: bool - router_advertisement: - description: Router discovery advertisements - type: bool - router_solicitation: - description: Router discovery solicitations - type: bool - source_quench: - description: Source quenches - type: bool - source_route_failed: - description: Source route failed - type: bool - time_exceeded: - description: All time exceededs - type: bool - timestamp_reply: - description: Timestamp replies - type: bool - timestamp_request: - description: Timestamp requests - type: bool - traceroute: - description: Traceroute - type: bool - ttl_exceeded: - description: TTL exceeded - type: bool - unreachable: - description: All unreachables - type: bool - igmp: - description: Internet Gateway Message Protocol. - type: dict - suboptions: - dvmrp: - description: Distance Vector Multicast Routing Protocol(2) - type: bool - host_query: - description: IGMP Membership Query(0) - type: bool - mtrace_resp: - description: Multicast Traceroute Response(7) - type: bool - mtrace_route: - description: Multicast Traceroute(8) - type: bool - pim: - description: Protocol Independent Multicast(3) - type: bool - trace: - description: Multicast trace(4) - type: bool - v1host_report: - description: IGMPv1 Membership Report(1) - type: bool - v2host_report: - description: IGMPv2 Membership Report(5) - type: bool - v2leave_group: - description: IGMPv2 Leave Group(6) - type: bool - v3host_report: - description: IGMPv3 Membership Report(9) - type: bool - ip: - description: Any Internet Protocol. - type: bool - ipv6: - description: Any IPv6. - type: bool - ipinip: - description: IP in IP tunneling. - type: bool - nos: - description: KA9Q NOS compatible IP over IP tunneling. - type: bool - ospf: - description: OSPF routing protocol. - type: bool - pcp: - description: Payload Compression Protocol. - type: bool - pim: - description: Protocol Independent Multicast. - type: bool - sctp: - description: Stream Control Transmission Protocol. - type: bool - udp: - description: User Datagram Protocol. - type: bool - tcp: - description: Match TCP packet flags - type: dict - suboptions: - ack: - description: Match on the ACK bit - type: bool - established: - description: Match established connections - type: bool - fin: - description: Match on the FIN bit - type: bool - psh: - description: Match on the PSH bit - type: bool - rst: - description: Match on the RST bit - type: bool - syn: - description: Match on the SYN bit - type: bool - urg: - description: Match on the URG bit - type: bool - source: - description: Specify the packet source. - type: dict - suboptions: - address: - description: Source network address. - type: str - wildcard_bits: - description: Destination wildcard bits, valid with IPV4 address. - type: str - any: - description: Match any source address. - type: bool - host: - description: A single source host - type: str - port_protocol: - description: - - Specify the destination port along with protocol. - - Note, Valid with TCP/UDP protocol_options - type: dict - suboptions: - eq: - description: Match only packets on a given port number. - type: str - gt: - description: Match only packets with a greater port number. - type: str - lt: - description: Match only packets with a lower port number. - type: str - neq: - description: Match only packets not on a given port number. - type: str - range: - description: Port group. - type: dict - suboptions: - start: - description: Specify the start of the port range. - type: int - end: - description: Specify the end of the port range. - type: int - destination: - description: Specify the packet destination. - type: dict - suboptions: - address: - description: Host address to match, or any single host address. - type: str - wildcard_bits: - description: Destination wildcard bits, valid with IPV4 address. - type: str - any: - description: Match any source address. - type: bool - host: - description: A single destination host - type: str - port_protocol: - description: - - Specify the destination port along with protocol. - - Note, Valid with TCP/UDP protocol_options - type: dict - suboptions: - eq: - description: Match only packets on a given port number. - type: str - gt: - description: Match only packets with a greater port number. - type: str - lt: - description: Match only packets with a lower port number. - type: str - neq: - description: Match only packets not on a given port number. - type: str - range: - description: Port group. - type: dict - suboptions: - start: - description: Specify the start of the port range. - type: int - end: - description: Specify the end of the port range. - type: int - dscp: - description: Match packets with given dscp value. - type: str - fragments: - description: Check non-initial fragments. - type: str - log: - description: Log matches against this entry. - type: str - log_input: - description: Log matches against this entry, including input interface. - type: str - option: - description: - - Match packets with given IP Options value. - - Valid only for named acls. - type: dict - suboptions: - add_ext: - description: Match packets with Address Extension Option (147). - type: bool - any_options: - description: Match packets with ANY Option. - type: bool - com_security: - description: Match packets with Commercial Security Option (134). - type: bool - dps: - description: Match packets with Dynamic Packet State Option (151). - type: bool - encode: - description: Match packets with Encode Option (15). - type: bool - eool: - description: Match packets with End of Options (0). - type: bool - ext_ip: - description: Match packets with Extended IP Option (145). - type: bool - ext_security: - description: Match packets with Extended Security Option (133). - type: bool - finn: - description: Match packets with Experimental Flow Control Option (205). - type: bool - imitd: - description: Match packets with IMI Traffic Desriptor Option (144). - type: bool - lsr: - description: Match packets with Loose Source Route Option (131). - type: bool - mtup: - description: Match packets with MTU Probe Option (11). - type: bool - mtur: - description: Match packets with MTU Reply Option (12). - type: bool - no_op: - description: Match packets with No Operation Option (1). - type: bool - nsapa: - description: Match packets with NSAP Addresses Option (150). - type: bool - record_route: - description: Match packets with Record Route Option (7). - type: bool - router_alert: - description: Match packets with Router Alert Option (148). - type: bool - sdb: - description: Match packets with Selective Directed Broadcast Option (149). - type: bool - security: - description: Match packets with Basic Security Option (130). - type: bool - ssr: - description: Match packets with Strict Source Routing Option (137). - type: bool - stream_id: - description: Match packets with Stream ID Option (136). - type: bool - timestamp: - description: Match packets with Time Stamp Option (68). - type: bool - traceroute: - description: Match packets with Trace Route Option (82). - type: bool - ump: - description: Match packets with Upstream Multicast Packet Option (152). - type: bool - visa: - description: Match packets with Experimental Access Control Option (142). - type: bool - zsu: - description: Match packets with Experimental Measurement Option (10). - type: bool - precedence: - description: Match packets with given precedence value. - type: int - time_range: - description: Specify a time-range. - type: str - tos: - description: - - Match packets with given TOS value. - - Note, DSCP and TOS are mutually exclusive - type: dict - suboptions: - service_value: - description: Type of service value - type: int - max_reliability: - description: Match packets with max reliable TOS (2). - type: bool - max_throughput: - description: Match packets with max throughput TOS (4). - type: bool - min_delay : - description: Match packets with min delay TOS (8). - type: bool - min_monetary_cost: - description: Match packets with min monetary cost TOS (1). - type: bool - normal: - description: Match packets with normal TOS (0). - type: bool - ttl: - description: Match packets with given TTL value. - type: dict - suboptions: - eq: - description: Match only packets on a given TTL number. - type: int - gt: - description: Match only packets with a greater TTL number. - type: int - lt: - description: Match only packets with a lower TTL number. - type: int - neq: - description: Match only packets not on a given TTL number. - type: int - range: - description: Match only packets in the range of TTLs. - type: dict - suboptions: - start: - description: Specify the start of the port range. - type: int - end: - description: Specify the end of the port range. - type: int - running_config: - description: - - The module, by default, will connect to the remote device and - retrieve the current running-config to use as a base for comparing - against the contents of source. There are times when it is not - desirable to have the task get the current running-config for - every task in a playbook. The I(running_config) argument allows the - implementer to pass in the configuration to use as the base - config for comparison. - type: str - state: - choices: - - merged - - replaced - - overridden - - deleted - - gathered - - rendered - - parsed - default: merged - description: - - The state of the configuration after module completion - type: str -""" - -EXAMPLES = """ ---- - -# Using merged - -# Before state: -# ------------- -# -# vios#sh access-lists -# Extended IP access list 110 -# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10 - -- name: Merge provided configuration with device configuration - ios_acl: - config: - - afi: ipv4 - acls: - - name: std_acl - acl_type: standard - aces: - - grant: deny - source: - address: 192.168.1.200 - - grant: deny - source: - address: 192.168.2.0 - wildcard_bits: 0.0.0.255 - - name: 110 - aces: - - grant: deny - sequence: 10 - protocol_options: - icmp: - traceroute: true - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - dscp: ef - ttl: - eq: 10 - - grant: deny - protocol_options: - tcp: - ack: true - source: - host: 198.51.100.0 - destination: - host: 198.51.110.0 - port_protocol: - eq: telnet - - name: test - acl_type: extended - aces: - - grant: deny - protocol_options: - tcp: - fin: true - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - option: - traceroute: true - ttl: - eq: 10 - - name: 123 - aces: - - grant: deny - protocol_options: - tcp: - ack: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - destination: - address: 198.51.101.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - tos: - service_value: 12 - - grant: deny - protocol_options: - tcp: - ack: true - source: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.4.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - dscp: ef - ttl: - lt: 20 - - afi: ipv6 - acls: - - name: R1_TRAFFIC - aces: - - grant: deny - protocol_options: - tcp: - ack: true - source: - any: true - port_protocol: - eq: www - destination: - any: true - port_protocol: - eq: telnet - dscp: af11 - state: merged - -# Commands fired: -# --------------- -# -# - ip access-list standard std_acl -# - deny 192.168.1.200 -# - deny 192.168.2.0 0.0.0.255 -# - ip access-list extended 110 -# - no 10 -# - 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10 -# - deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack -# - ip access-list extended test -# - deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 -# - ip access-list extended 123 -# - deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 -# - deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 -# - ipv6 access-list R1_TRAFFIC -# - deny tcp any eq www any eq telnet ack dscp af11 - -# After state: -# ------------ -# -# vios#sh access-lists -# Standard IP access list std_acl -# 10 deny 192.168.1.200 -# 20 deny 192.168.2.0, wildcard bits 0.0.0.255 -# Extended IP access list 110 -# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10 -# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack -# Extended IP access list 123 -# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 -# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 -# Extended IP access list test -# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 -# IPv6 access list R1_TRAFFIC -# deny tcp any eq www any eq telnet ack dscp af11 sequence 10 - - -# Using replaced - -# Before state: -# ------------- -# -# vios#sh access-lists -# Standard IP access list std_acl -# 10 deny 192.168.1.200 -# 20 deny 192.168.2.0, wildcard bits 0.0.0.255 -# Extended IP access list 110 -# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10 -# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack -# Extended IP access list 123 -# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 -# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 -# Extended IP access list test -# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 -# IPv6 access list R1_TRAFFIC -# deny tcp any eq www any eq telnet ack dscp af11 sequence 10 - - -- name: Replaces device configuration of listed acls with provided configuration - ios_acl: - config: - - afi: ipv4 - acls: - - name: 110 - aces: - - grant: deny - protocol_options: - tcp: - syn: true - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - dscp: ef - ttl: - eq: 10 - - name: 150 - aces: - - grant: deny - sequence: 20 - protocol_options: - tcp: - syn: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - destination: - address: 198.51.110.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - dscp: ef - ttl: - eq: 10 - state: replaced - -# Commands fired: -# --------------- -# -# - no ip access-list extended 110 -# - ip access-list extended 110 -# - deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10 -# - ip access-list extended 150 -# - 20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10 - -# After state: -# ------------- -# -# vios#sh access-lists -# Standard IP access list std_acl -# 10 deny 192.168.1.200 -# 20 deny 192.168.2.0, wildcard bits 0.0.0.255 -# Extended IP access list 110 -# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10 -# Extended IP access list 123 -# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 -# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 -# Extended IP access list 150 -# 20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10 -# Extended IP access list test -# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 -# IPv6 access list R1_TRAFFIC -# deny tcp any eq www any eq telnet ack dscp af11 sequence 10 - -# Using overridden - -# Before state: -# ------------- -# -# vios#sh access-lists -# Standard IP access list std_acl -# 10 deny 192.168.1.200 -# 20 deny 192.168.2.0, wildcard bits 0.0.0.255 -# Extended IP access list 110 -# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10 -# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack -# Extended IP access list 123 -# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 -# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 -# Extended IP access list test -# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 -# IPv6 access list R1_TRAFFIC -# deny tcp any eq www any eq telnet ack dscp af11 sequence 10 - -- name: Override device configuration of all acls with provided configuration - ios_acl: - config: - - afi: ipv4 - acls: - - name: 110 - aces: - - grant: deny - sequence: 20 - protocol_options: - tcp: - ack: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - destination: - address: 198.51.110.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - dscp: ef - ttl: - eq: 10 - - name: 150 - aces: - - grant: deny - sequence: 10 - protocol_options: - tcp: - syn: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - destination: - address: 198.51.110.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - dscp: ef - ttl: - eq: 10 - state: overridden - -# Commands fired: -# --------------- -# -# - no ip access-list standard std_acl -# - no ip access-list extended 110 -# - no ip access-list extended 123 -# - no ip access-list extended 150 -# - no ip access-list extended test -# - no ipv6 access-list R1_TRAFFIC -# - ip access-list extended 150 -# - 10 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10 -# - ip access-list extended 110 -# - 20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq www ack dscp ef ttl eq 10 - -# After state: -# ------------- -# -# vios#sh access-lists -# Extended IP access list 110 -# 20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq www ack dscp ef ttl eq 10 -# Extended IP access list 150 -# 10 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10 - -# Using Deleted - -# Before state: -# ------------- -# -# vios#sh access-lists -# Standard IP access list std_acl -# 10 deny 192.168.1.200 -# 20 deny 192.168.2.0, wildcard bits 0.0.0.255 -# Extended IP access list 110 -# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10 -# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack -# Extended IP access list 123 -# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 -# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 -# Extended IP access list test -# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 -# IPv6 access list R1_TRAFFIC -# deny tcp any eq www any eq telnet ack dscp af11 sequence 10 - -- name: "Delete module attributes of given acls (Note: This won't delete the interface itself)" - ios_acl: - config: - - afi: ipv4 - acls: - - name: test - acl_type: extended - - name: 110 - - name: 123 - aces: - - sequence: 10 - - afi: ipv6 - acls: - - name: R1_TRAFFIC - state: deleted - -# Commands fired: -# --------------- -# -# - no ip access-list extended test -# - no ip access-list extended 110 -# - ip access-list extended 123 -# - no 10 -# - no ipv6 access-list R1_TRAFFIC - -# After state: -# ------------- -# -# vios#sh access-lists -# Standard IP access list std_acl -# 10 deny 192.168.1.200 -# 20 deny 192.168.2.0, wildcard bits 0.0.0.255 -# Extended IP access list 123 -# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 - -# Before state: -# ------------- -# -# vios#sh access-lists -# Standard IP access list std_acl -# 10 deny 192.168.1.200 -# 20 deny 192.168.2.0, wildcard bits 0.0.0.255 -# Extended IP access list 110 -# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10 -# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack -# Extended IP access list 123 -# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 -# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 -# Extended IP access list test -# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 -# IPv6 access list R1_TRAFFIC -# deny tcp any eq www any eq telnet ack dscp af11 sequence 10 - -- name: "Delete module attributes of given ACL based on AFI (Note: This won't delete the interface itself)" - ios_acl: - config: - - afi: ipv4 - state: deleted - -# Commands fired: -# --------------- -# -# - no ip access-list standard std_acl -# - no ip access-list extended test -# - no ip access-list extended 110 -# - no ip access-list extended 123 - -# After state: -# ------------- -# -# vios#sh access-lists -# IPv6 access list R1_TRAFFIC -# deny tcp any eq www any eq telnet ack dscp af11 sequence 10 - -# Using Deleted without any config passed -#"(NOTE: This will delete all of configured resource module attributes from each configured interface)" - -# Before state: -# ------------- -# -# vios#sh access-lists -# Standard IP access list std_acl -# 10 deny 192.168.1.200 -# 20 deny 192.168.2.0, wildcard bits 0.0.0.255 -# Extended IP access list 110 -# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10 -# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack -# Extended IP access list 123 -# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 -# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 -# Extended IP access list test -# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 -# IPv6 access list R1_TRAFFIC -# deny tcp any eq www any eq telnet ack dscp af11 sequence 10 - -- name: "Delete module attributes of all acls (Note: This won't delete the interface itself)" - ios_acl: - state: deleted - -# Commands fired: -# --------------- -# -# - no ip access-list extended test -# - no ip access-list extended 110 -# - no ip access-list extended 123 -# - no ip access-list extended test -# - no ipv6 access-list R1_TRAFFIC - -# After state: -# ------------- -# -# vios#sh access-lists - -# Using Gathered - -# Before state: -# ------------- -# -# vios#sh access-lists -# Standard IP access list std_acl -# 10 deny 192.168.1.200 -# 20 deny 192.168.2.0, wildcard bits 0.0.0.255 -# Extended IP access list 110 -# 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10 -# 20 deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack -# Extended IP access list 123 -# 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 -# 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 -# Extended IP access list test -# 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 -# IPv6 access list R1_TRAFFIC -# deny tcp any eq www any eq telnet ack dscp af11 sequence 10 - -- name: Gather listed acls interfaces with provided configurations - ios_acl_interfaces: - config: - state: gathered - -# Module Execution Result: -# ------------------------ -# -# "gathered": [ -# { -# "acls": [ -# { -# "aces": [ -# { -# "destination": { -# "address": "192.0.3.0", -# "wildcard_bits": "0.0.0.255" -# }, -# "dscp": "ef", -# "grant": "deny", -# "protocol_options": { -# "icmp": { -# "echo": true -# } -# }, -# "sequence": 10, -# "source": { -# "address": "192.0.2.0", -# "wildcard_bits": "0.0.0.255" -# }, -# "ttl": { -# "eq": 10 -# } -# } -# ], -# "acl_type": "extended", -# "name": "110" -# }, -# { -# "aces": [ -# { -# "destination": { -# "address": "198.51.101.0", -# "port_protocol": { -# "eq": "telnet" -# }, -# "wildcard_bits": "0.0.0.255" -# }, -# "grant": "deny", -# "protocol_options": { -# "tcp": { -# "ack": true -# } -# }, -# "sequence": 10, -# "source": { -# "address": "198.51.100.0", -# "wildcard_bits": "0.0.0.255" -# }, -# "tos": { -# "service_value": 12 -# } -# }, -# { -# "destination": { -# "address": "192.0.4.0", -# "port_protocol": { -# "eq": "www" -# }, -# "wildcard_bits": "0.0.0.255" -# }, -# "dscp": "ef", -# "grant": "deny", -# "protocol_options": { -# "tcp": { -# "ack": true -# } -# }, -# "sequence": 20, -# "source": { -# "address": "192.0.3.0", -# "wildcard_bits": "0.0.0.255" -# }, -# "ttl": { -# "lt": 20 -# } -# } -# ], -# "acl_type": "extended", -# "name": "123" -# }, -# { -# "aces": [ -# { -# "destination": { -# "address": "192.0.3.0", -# "port_protocol": { -# "eq": "www" -# }, -# "wildcard_bits": "0.0.0.255" -# }, -# "grant": "deny", -# "option": { -# "traceroute": true -# }, -# "protocol_options": { -# "tcp": { -# "fin": true -# } -# }, -# "sequence": 10, -# "source": { -# "address": "192.0.2.0", -# "wildcard_bits": "0.0.0.255" -# }, -# "ttl": { -# "eq": 10 -# } -# } -# ], -# "acl_type": "extended", -# "name": "test_acl" -# } -# ], -# "afi": "ipv4" -# }, -# { -# "acls": [ -# { -# "aces": [ -# { -# "destination": { -# "any": true, -# "port_protocol": { -# "eq": "telnet" -# } -# }, -# "dscp": "af11", -# "grant": "deny", -# "protocol_options": { -# "tcp": { -# "ack": true -# } -# }, -# "sequence": 10, -# "source": { -# "any": true, -# "port_protocol": { -# "eq": "www" -# } -# } -# } -# ], -# "name": "R1_TRAFFIC" -# } -# ], -# "afi": "ipv6" -# } -# ] - -# Using Rendered - -- name: Rendered the provided configuration with the exisiting running configuration - ios_acl: - config: - - afi: ipv4 - acls: - - name: 110 - aces: - - grant: deny - sequence: 10 - protocol_options: - tcp: - syn: true - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - dscp: ef - ttl: - eq: 10 - - name: 150 - aces: - - grant: deny - protocol_options: - tcp: - syn: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - destination: - address: 198.51.110.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - dscp: ef - ttl: - eq: 10 - state: rendered - -# Module Execution Result: -# ------------------------ -# -# "rendered": [ -# "ip access-list extended 110", -# "10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10", -# "ip access-list extended 150", -# "deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10" -# ] - -# Using Parsed - -- name: Parse the commands for provided configuration - ios_acl: - running_config: - "ipv6 access-list R1_TRAFFIC - deny tcp any eq www any eq telnet ack dscp af11" - state: parsed - -# Module Execution Result: -# ------------------------ -# -# "parsed": [ -# { -# "acls": [ -# { -# "aces": [ -# { -# "destination": { -# "any": true, -# "port_protocol": { -# "eq": "telnet" -# } -# }, -# "dscp": "af11", -# "grant": "deny", -# "protocol_options": { -# "tcp": { -# "ack": true -# } -# }, -# "source": { -# "any": true, -# "port_protocol": { -# "eq": "www" -# } -# } -# } -# ], -# "name": "R1_TRAFFIC" -# } -# ], -# "afi": "ipv6" -# } -# ] - -""" - -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: list - sample: The configuration returned will always be in the same format of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: list - sample: The configuration returned will always be in the same format of the parameters above. -commands: - description: The set of commands pushed to the remote device - returned: always - type: list - sample: ['ip access-list extended 110', 'deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10'] -""" - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.acls.acls import AclsArgs -from ansible.module_utils.network.ios.config.acls.acls import Acls - - -def main(): - """ - Main entry point for module execution - - :returns: the result form module invocation - """ - required_if = [('state', 'merged', ('config',)), - ('state', 'replaced', ('config',)), - ('state', 'overridden', ('config',)), - ('state', 'rendered', ('config',)), - ('state', 'parsed', ('running_config',))] - - mutually_exclusive = [('config', 'running_config')] - - module = AnsibleModule(argument_spec=AclsArgs.argument_spec, - required_if=required_if, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True) - - result = Acls(module).execute_module() - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_banner.py b/lib/ansible/modules/network/ios/ios_banner.py deleted file mode 100644 index c28838407c7..00000000000 --- a/lib/ansible/modules/network/ios/ios_banner.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/python -# -# 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 . -# - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_banner -version_added: "2.3" -author: "Ricardo Carrillo Cruz (@rcarrillocruz)" -short_description: Manage multiline banners on Cisco IOS devices -description: - - This will configure both login and motd banners on remote devices - running Cisco IOS. It allows playbooks to add or remote - banner text from the active running configuration. -extends_documentation_fragment: ios -notes: - - Tested against IOS 15.6 -options: - banner: - description: - - Specifies which banner should be configured on the remote device. - In Ansible 2.4 and earlier only I(login) and I(motd) were supported. - required: true - choices: ['login', 'motd', 'exec', 'incoming', 'slip-ppp'] - text: - description: - - The banner text that should be - present in the remote device running configuration. This argument - accepts a multiline string, with no empty lines. Requires I(state=present). - state: - description: - - Specifies whether or not the configuration is - present in the current devices active running configuration. - default: present - choices: ['present', 'absent'] -""" - -EXAMPLES = """ -- name: configure the login banner - ios_banner: - banner: login - text: | - this is my login banner - that contains a multiline - string - state: present - -- name: remove the motd banner - ios_banner: - banner: motd - state: absent - -- name: Configure banner from file - ios_banner: - banner: motd - text: "{{ lookup('file', './config_partial/raw_banner.cfg') }}" - state: present - -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always - type: list - sample: - - banner login - - this is my login banner - - that contains a multiline - - string -""" -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.ios import get_config, load_config -from ansible.module_utils.network.ios.ios import ios_argument_spec -from re import search, M - - -def map_obj_to_commands(updates, module): - commands = list() - want, have = updates - state = module.params['state'] - - if state == 'absent' and 'text' in have.keys() and have['text']: - commands.append('no banner %s' % module.params['banner']) - - elif state == 'present': - if want['text'] and (want['text'] != have.get('text')): - banner_cmd = 'banner %s' % module.params['banner'] - banner_cmd += ' @\n' - banner_cmd += want['text'].strip('\n') - banner_cmd += '\n@' - commands.append(banner_cmd) - - return commands - - -def map_config_to_obj(module): - """ - This function gets the banner config without stripping any whitespaces, - and then fetches the required banner from it. - :param module: - :return: banner config dict object. - """ - out = get_config(module, flags='| begin banner %s' % module.params['banner']) - if out: - regex = 'banner ' + module.params['banner'] + ' ^C\n' - if search('banner ' + module.params['banner'], out, M): - output = str((out.split(regex))[1].split("^C\n")[0]) - else: - output = None - else: - output = None - obj = {'banner': module.params['banner'], 'state': 'absent'} - if output: - obj['text'] = output - obj['state'] = 'present' - return obj - - -def map_params_to_obj(module): - text = module.params['text'] - return { - 'banner': module.params['banner'], - 'text': text, - 'state': module.params['state'] - } - - -def main(): - """ main entry point for module execution - """ - argument_spec = dict( - banner=dict(required=True, choices=['login', 'motd', 'exec', 'incoming', 'slip-ppp']), - text=dict(), - state=dict(default='present', choices=['present', 'absent']) - ) - - argument_spec.update(ios_argument_spec) - - required_if = [('state', 'present', ('text',))] - - module = AnsibleModule(argument_spec=argument_spec, - required_if=required_if, - supports_check_mode=True) - - warnings = list() - - result = {'changed': False} - if warnings: - result['warnings'] = warnings - want = map_params_to_obj(module) - have = map_config_to_obj(module) - - commands = map_obj_to_commands((want, have), module) - result['commands'] = commands - - if commands: - if not module.check_mode: - load_config(module, commands) - - result['changed'] = True - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_bgp.py b/lib/ansible/modules/network/ios/ios_bgp.py deleted file mode 100644 index 88fe29a12cb..00000000000 --- a/lib/ansible/modules/network/ios/ios_bgp.py +++ /dev/null @@ -1,438 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# (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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_bgp -version_added: "2.8" -author: "Nilashish Chakraborty (@NilashishC)" -short_description: Configure global BGP protocol settings on Cisco IOS. -description: - - This module provides configuration management of global BGP parameters - on devices running Cisco IOS -notes: - - Tested against Cisco IOS Version 15.6(3)M2 -options: - config: - description: - - Specifies the BGP related configuration. - suboptions: - bgp_as: - description: - - Specifies the BGP Autonomous System (AS) number to configure on the device. - type: int - required: true - router_id: - description: - - Configures the BGP routing process router-id value. - default: null - log_neighbor_changes: - description: - - Enable/disable logging neighbor up/down and reset reason. - type: bool - neighbors: - description: - - Specifies BGP neighbor related configurations. - suboptions: - neighbor: - description: - - Neighbor router address. - required: True - remote_as: - description: - - Remote AS of the BGP neighbor to configure. - type: int - required: True - update_source: - description: - - Source of the routing updates. - password: - description: - - Password to authenticate the BGP peer connection. - enabled: - description: - - Administratively shutdown or enable a neighbor. - type: bool - description: - description: - - Neighbor specific description. - ebgp_multihop: - description: - - Specifies the maximum hop count for EBGP neighbors not on directly connected networks. - - The range is from 1 to 255. - type: int - peer_group: - description: - - Name of the peer group that the neighbor is a member of. - timers: - description: - - Specifies BGP neighbor timer related configurations. - suboptions: - keepalive: - description: - - Frequency (in seconds) with which the device sends keepalive messages to its peer. - - The range is from 0 to 65535. - type: int - required: True - holdtime: - description: - - Interval (in seconds) after not receiving a keepalive message that IOS declares a peer dead. - - The range is from 0 to 65535. - type: int - required: True - min_neighbor_holdtime: - description: - - Interval (in seconds) specifying the minimum acceptable hold-time from a BGP neighbor. - - The minimum acceptable hold-time must be less than, or equal to, the interval specified in the holdtime argument. - - The range is from 0 to 65535. - type: int - local_as: - description: - - The local AS number for the neighbor. - type: int - networks: - description: - - Specify Networks to announce via BGP. - - For operation replace, this option is mutually exclusive with networks option under address_family. - - For operation replace, if the device already has an address family activated, this option is not allowed. - suboptions: - prefix: - description: - - Network ID to announce via BGP. - required: True - masklen: - description: - - Subnet mask length for the Network to announce(e.g, 8, 16, 24, etc.). - route_map: - description: - - Route map to modify the attributes. - address_family: - description: - - Specifies BGP address family related configurations. - suboptions: - afi: - description: - - Type of address family to configure. - choices: - - ipv4 - - ipv6 - required: True - safi: - description: - - Specifies the type of cast for the address family. - choices: - - flowspec - - unicast - - multicast - - labeled-unicast - default: unicast - synchronization: - description: - - Enable/disable IGP synchronization. - type: bool - auto_summary: - description: - - Enable/disable automatic network number summarization. - type: bool - redistribute: - description: - - Specifies the redistribute information from another routing protocol. - suboptions: - protocol: - description: - - Specifies the protocol for configuring redistribute information. - choices: ['ospf', 'ospfv3', 'eigrp', 'isis', 'static', 'connected', 'odr', 'lisp', 'mobile', 'rip'] - required: True - id: - description: - - Identifier for the routing protocol for configuring redistribute information. - - Valid for protocols 'ospf', 'ospfv3' and 'eigrp'. - metric: - description: - - Specifies the metric for redistributed routes. - route_map: - description: - - Specifies the route map reference. - networks: - description: - - Specify Networks to announce via BGP. - - For operation replace, this option is mutually exclusive with root level networks option. - suboptions: - prefix: - description: - - Network ID to announce via BGP. - required: True - masklen: - description: - - Subnet mask length for the Network to announce(e.g, 8, 16, 24, etc.). - route_map: - description: - - Route map to modify the attributes. - neighbors: - description: - - Specifies BGP neighbor related configurations in Address Family configuration mode. - suboptions: - neighbor: - description: - - Neighbor router address. - required: True - advertisement_interval: - description: - - Minimum interval between sending BGP routing updates for this neighbor. - type: int - route_reflector_client: - description: - - Specify a neighbor as a route reflector client. - type: bool - route_server_client: - description: - - Specify a neighbor as a route server client. - type: bool - activate: - description: - - Enable the Address Family for this Neighbor. - type: bool - remove_private_as: - description: - - Remove the private AS number from outbound updates. - type: bool - next_hop_self: - description: - - Enable/disable the next hop calculation for this neighbor. - type: bool - next_hop_unchanged: - description: - - Propagate next hop unchanged for iBGP paths to this neighbor. - type: bool - maximum_prefix: - description: - - Maximum number of prefixes to accept from this peer. - - The range is from 1 to 2147483647. - type: int - prefix_list_in: - description: - - Name of ip prefix-list to apply to incoming prefixes. - prefix_list_out: - description: - - Name of ip prefix-list to apply to outgoing prefixes. - operation: - description: - - Specifies the operation to be performed on the BGP process configured on the device. - - In case of merge, the input configuration will be merged with the existing BGP configuration on the device. - - In case of replace, if there is a diff between the existing configuration and the input configuration, the - existing configuration will be replaced by the input configuration for every option that has the diff. - - In case of override, all the existing BGP configuration will be removed from the device and replaced with - the input configuration. - - In case of delete the existing BGP configuration will be removed from the device. - default: merge - choices: ['merge', 'replace', 'override', 'delete'] -""" - -EXAMPLES = """ -- name: configure global bgp as 64496 - ios_bgp: - config: - bgp_as: 64496 - router_id: 192.0.2.1 - log_neighbor_changes: True - neighbors: - - neighbor: 203.0.113.5 - remote_as: 64511 - timers: - keepalive: 300 - holdtime: 360 - min_neighbor_holdtime: 360 - - neighbor: 198.51.100.2 - remote_as: 64498 - networks: - - prefix: 198.51.100.0 - route_map: RMAP_1 - - prefix: 192.0.2.0 - masklen: 23 - address_family: - - afi: ipv4 - safi: unicast - redistribute: - - protocol: ospf - id: 223 - metric: 10 - operation: merge - -- name: Configure BGP neighbors - ios_bgp: - config: - bgp_as: 64496 - neighbors: - - neighbor: 192.0.2.10 - remote_as: 64496 - password: ansible - description: IBGP_NBR_1 - ebgp_multihop: 100 - timers: - keepalive: 300 - holdtime: 360 - min_neighbor_holdtime: 360 - - neighbor: 192.0.2.15 - remote_as: 64496 - description: IBGP_NBR_2 - ebgp_multihop: 150 - operation: merge - -- name: Configure root-level networks for BGP - ios_bgp: - config: - bgp_as: 64496 - networks: - - prefix: 203.0.113.0 - masklen: 27 - route_map: RMAP_1 - - prefix: 203.0.113.32 - masklen: 27 - route_map: RMAP_2 - operation: merge - -- name: Configure BGP neighbors under address family mode - ios_bgp: - config: - bgp_as: 64496 - address_family: - - afi: ipv4 - safi: unicast - neighbors: - - neighbor: 203.0.113.10 - activate: yes - maximum_prefix: 250 - advertisement_interval: 120 - - neighbor: 192.0.2.15 - activate: yes - route_reflector_client: True - operation: merge - -- name: remove bgp as 64496 from config - ios_bgp: - config: - bgp_as: 64496 - operation: delete -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always - type: list - sample: - - router bgp 64496 - - bgp router-id 192.0.2.1 - - bgp log-neighbor-changes - - neighbor 203.0.113.5 remote-as 64511 - - neighbor 203.0.113.5 timers 300 360 360 - - neighbor 198.51.100.2 remote-as 64498 - - network 198.51.100.0 route-map RMAP_1 - - network 192.0.2.0 mask 255.255.254.0 - - address-family ipv4 - - redistribute ospf 223 metric 70 - - exit-address-family -""" -from ansible.module_utils._text import to_text -from ansible.module_utils.network.ios.providers.module import NetworkModule -from ansible.module_utils.network.ios.providers.cli.config.bgp.process import REDISTRIBUTE_PROTOCOLS - - -def main(): - """ main entry point for module execution - """ - network_spec = { - 'prefix': dict(required=True), - 'masklen': dict(type='int'), - 'route_map': dict(), - } - - redistribute_spec = { - 'protocol': dict(choices=REDISTRIBUTE_PROTOCOLS, required=True), - 'id': dict(), - 'metric': dict(type='int'), - 'route_map': dict(), - } - - timer_spec = { - 'keepalive': dict(type='int', required=True), - 'holdtime': dict(type='int', required=True), - 'min_neighbor_holdtime': dict(type='int'), - } - - neighbor_spec = { - 'neighbor': dict(required=True), - 'remote_as': dict(type='int', required=True), - 'local_as': dict(type='int'), - 'update_source': dict(), - 'password': dict(no_log=True), - 'enabled': dict(type='bool'), - 'description': dict(), - 'ebgp_multihop': dict(type='int'), - 'timers': dict(type='dict', options=timer_spec), - 'peer_group': dict(), - } - - af_neighbor_spec = { - 'neighbor': dict(required=True), - 'activate': dict(type='bool'), - 'advertisement_interval': dict(type='int'), - 'remove_private_as': dict(type='bool'), - 'next_hop_self': dict(type='bool'), - 'route_reflector_client': dict(type='bool'), - 'route_server_client': dict(type='bool'), - 'maximum_prefix': dict(type='int'), - 'prefix_list_in': dict(), - 'prefix_list_out': dict() - } - - address_family_spec = { - 'afi': dict(choices=['ipv4', 'ipv6'], required=True), - 'safi': dict(choices=['flowspec', 'labeled-unicast', 'multicast', 'unicast'], default='unicast'), - 'auto_summary': dict(type='bool'), - 'synchronization': dict(type='bool'), - 'networks': dict(type='list', elements='dict', options=network_spec), - 'redistribute': dict(type='list', elements='dict', options=redistribute_spec), - 'neighbors': dict(type='list', elements='dict', options=af_neighbor_spec), - } - - config_spec = { - 'bgp_as': dict(type='int', required=True), - 'router_id': dict(), - 'log_neighbor_changes': dict(type='bool'), - 'neighbors': dict(type='list', elements='dict', options=neighbor_spec), - 'address_family': dict(type='list', elements='dict', options=address_family_spec), - 'networks': dict(type='list', elements='dict', options=network_spec) - } - - argument_spec = { - 'config': dict(type='dict', options=config_spec), - 'operation': dict(default='merge', choices=['merge', 'replace', 'override', 'delete']) - } - - module = NetworkModule(argument_spec=argument_spec, - supports_check_mode=True) - - try: - result = module.edit_config(config_filter='| section ^router bgp') - except Exception as exc: - module.fail_json(msg=to_text(exc)) - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_command.py b/lib/ansible/modules/network/ios/ios_command.py deleted file mode 100644 index 59ea254b2dc..00000000000 --- a/lib/ansible/modules/network/ios/ios_command.py +++ /dev/null @@ -1,230 +0,0 @@ -#!/usr/bin/python -# -# 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 . -# - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_command -version_added: "2.1" -author: "Peter Sprygada (@privateip)" -short_description: Run commands on remote devices running Cisco IOS -description: - - Sends arbitrary commands to an ios node and returns the results - read from the device. This module includes an - argument that will cause the module to wait for a specific condition - before returning or timing out if the condition is not met. - - This module does not support running commands in configuration mode. - Please use M(ios_config) to configure IOS devices. -extends_documentation_fragment: ios -notes: - - Tested against IOS 15.6 -options: - commands: - description: - - List of commands to send to the remote ios device over the - configured provider. The resulting output from the command - is returned. If the I(wait_for) argument is provided, the - module is not returned until the condition is satisfied or - the number of retries has expired. If a command sent to the - device requires answering a prompt, it is possible to pass - a dict containing I(command), I(answer) and I(prompt). - Common answers are 'y' or "\\r" (carriage return, must be - double quotes). See examples. - required: true - wait_for: - description: - - List of conditions to evaluate against the output of the - command. The task will wait for each condition to be true - before moving forward. If the conditional is not true - within the configured number of retries, the task fails. - See examples. - aliases: ['waitfor'] - version_added: "2.2" - match: - description: - - The I(match) argument is used in conjunction with the - I(wait_for) argument to specify the match policy. Valid - values are C(all) or C(any). If the value is set to C(all) - then all conditionals in the wait_for must be satisfied. If - the value is set to C(any) then only one of the values must be - satisfied. - default: all - choices: ['any', 'all'] - version_added: "2.2" - retries: - description: - - Specifies the number of retries a command should by tried - before it is considered failed. The command is run on the - target device every retry and evaluated against the - I(wait_for) conditions. - default: 10 - interval: - description: - - Configures the interval in seconds to wait between retries - of the command. If the command does not pass the specified - conditions, the interval indicates how long to wait before - trying the command again. - default: 1 -""" - -EXAMPLES = r""" -tasks: - - name: run show version on remote devices - ios_command: - commands: show version - - - name: run show version and check to see if output contains IOS - ios_command: - commands: show version - wait_for: result[0] contains IOS - - - name: run multiple commands on remote nodes - ios_command: - commands: - - show version - - show interfaces - - - name: run multiple commands and evaluate the output - ios_command: - commands: - - show version - - show interfaces - wait_for: - - result[0] contains IOS - - result[1] contains Loopback0 - - - name: run commands that require answering a prompt - ios_command: - commands: - - command: 'clear counters GigabitEthernet0/1' - prompt: 'Clear "show interface" counters on this interface \[confirm\]' - answer: 'y' - - command: 'clear counters GigabitEthernet0/2' - prompt: '[confirm]' - answer: "\r" -""" - -RETURN = """ -stdout: - description: The set of responses from the commands - returned: always apart from low level errors (such as action plugin) - type: list - sample: ['...', '...'] -stdout_lines: - description: The value of stdout split into a list - returned: always apart from low level errors (such as action plugin) - type: list - sample: [['...', '...'], ['...'], ['...']] -failed_conditions: - description: The list of conditionals that have failed - returned: failed - type: list - sample: ['...', '...'] -""" -import time - -from ansible.module_utils._text import to_text -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.parsing import Conditional -from ansible.module_utils.network.common.utils import transform_commands, to_lines -from ansible.module_utils.network.ios.ios import run_commands -from ansible.module_utils.network.ios.ios import ios_argument_spec - - -def parse_commands(module, warnings): - commands = transform_commands(module) - - if module.check_mode: - for item in list(commands): - if not item['command'].startswith('show'): - warnings.append( - 'Only show commands are supported when using check mode, not ' - 'executing %s' % item['command'] - ) - commands.remove(item) - - return commands - - -def main(): - """main entry point for module execution - """ - argument_spec = dict( - commands=dict(type='list', required=True), - - wait_for=dict(type='list', aliases=['waitfor']), - match=dict(default='all', choices=['all', 'any']), - - retries=dict(default=10, type='int'), - interval=dict(default=1, type='int') - ) - - argument_spec.update(ios_argument_spec) - - module = AnsibleModule(argument_spec=argument_spec, - supports_check_mode=True) - - warnings = list() - result = {'changed': False, 'warnings': warnings} - commands = parse_commands(module, warnings) - wait_for = module.params['wait_for'] or list() - - try: - conditionals = [Conditional(c) for c in wait_for] - except AttributeError as exc: - module.fail_json(msg=to_text(exc)) - - retries = module.params['retries'] - interval = module.params['interval'] - match = module.params['match'] - - while retries > 0: - responses = run_commands(module, commands) - - for item in list(conditionals): - if item(responses): - if match == 'any': - conditionals = list() - break - conditionals.remove(item) - - if not conditionals: - break - - time.sleep(interval) - retries -= 1 - - if conditionals: - failed_conditions = [item.raw for item in conditionals] - msg = 'One or more conditional statements have not been satisfied' - module.fail_json(msg=msg, failed_conditions=failed_conditions) - - result.update({ - 'stdout': responses, - 'stdout_lines': list(to_lines(responses)), - }) - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_config.py b/lib/ansible/modules/network/ios/ios_config.py deleted file mode 100644 index b359c9cc787..00000000000 --- a/lib/ansible/modules/network/ios/ios_config.py +++ /dev/null @@ -1,567 +0,0 @@ -#!/usr/bin/python -# -# 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 . -# - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_config -version_added: "2.1" -author: "Peter Sprygada (@privateip)" -short_description: Manage Cisco IOS configuration sections -description: - - Cisco IOS configurations use a simple block indent file syntax - for segmenting configuration into sections. This module provides - an implementation for working with IOS configuration sections in - a deterministic way. -extends_documentation_fragment: ios -notes: - - Tested against IOS 15.6 - - Abbreviated commands are NOT idempotent, see - L(Network FAQ,../network/user_guide/faq.html#why-do-the-config-modules-always-return-changed-true-with-abbreviated-commands). -options: - lines: - description: - - The ordered set of commands that should be configured in the - section. The commands must be the exact same commands as found - in the device running-config. Be sure to note the configuration - command syntax as some commands are automatically modified by the - device config parser. - aliases: ['commands'] - parents: - description: - - The ordered set of parents that uniquely identify the section or hierarchy - the commands should be checked against. If the parents argument - is omitted, the commands are checked against the set of top - level or global commands. - src: - description: - - Specifies the source path to the file that contains the configuration - or configuration template to load. The path to the source file can - either be the full path on the Ansible control host or a relative - path from the playbook or role root directory. This argument is mutually - exclusive with I(lines), I(parents). - version_added: "2.2" - before: - description: - - The ordered set of commands to push on to the command stack if - a change needs to be made. This allows the playbook designer - the opportunity to perform configuration commands prior to pushing - any changes without affecting how the set of commands are matched - against the system. - after: - description: - - The ordered set of commands to append to the end of the command - stack if a change needs to be made. Just like with I(before) this - allows the playbook designer to append a set of commands to be - executed after the command set. - match: - description: - - Instructs the module on the way to perform the matching of - the set of commands against the current device config. If - match is set to I(line), commands are matched line by line. If - match is set to I(strict), command lines are matched with respect - to position. If match is set to I(exact), command lines - must be an equal match. Finally, if match is set to I(none), the - module will not attempt to compare the source configuration with - the running configuration on the remote device. - choices: ['line', 'strict', 'exact', 'none'] - default: line - replace: - description: - - Instructs the module on the way to perform the configuration - on the device. If the replace argument is set to I(line) then - the modified lines are pushed to the device in configuration - mode. If the replace argument is set to I(block) then the entire - command block is pushed to the device in configuration mode if any - line is not correct. - default: line - choices: ['line', 'block'] - multiline_delimiter: - description: - - This argument is used when pushing a multiline configuration - element to the IOS device. It specifies the character to use - as the delimiting character. This only applies to the - configuration action. - default: "@" - version_added: "2.3" - backup: - description: - - This argument will cause the module to create a full backup of - the current C(running-config) from the remote device before any - changes are made. If the C(backup_options) value is not given, - the backup file is written to the C(backup) folder in the playbook - root directory or role root directory, if playbook is part of an - ansible role. If the directory does not exist, it is created. - type: bool - default: 'no' - version_added: "2.2" - running_config: - description: - - The module, by default, will connect to the remote device and - retrieve the current running-config to use as a base for comparing - against the contents of source. There are times when it is not - desirable to have the task get the current running-config for - every task in a playbook. The I(running_config) argument allows the - implementer to pass in the configuration to use as the base - config for comparison. - aliases: ['config'] - version_added: "2.4" - defaults: - description: - - This argument specifies whether or not to collect all defaults - when getting the remote device running config. When enabled, - the module will get the current config by issuing the command - C(show running-config all). - type: bool - default: 'no' - version_added: "2.2" - save_when: - description: - - When changes are made to the device running-configuration, the - changes are not copied to non-volatile storage by default. Using - this argument will change that before. If the argument is set to - I(always), then the running-config will always be copied to the - startup-config and the I(modified) flag will always be set to - True. If the argument is set to I(modified), then the running-config - will only be copied to the startup-config if it has changed since - the last save to startup-config. If the argument is set to - I(never), the running-config will never be copied to the - startup-config. If the argument is set to I(changed), then the running-config - will only be copied to the startup-config if the task has made a change. - I(changed) was added in Ansible 2.5. - default: never - choices: ['always', 'never', 'modified', 'changed'] - version_added: "2.4" - diff_against: - description: - - When using the C(ansible-playbook --diff) command line argument - the module can generate diffs against different sources. - - When this option is configure as I(startup), the module will return - the diff of the running-config against the startup-config. - - When this option is configured as I(intended), the module will - return the diff of the running-config against the configuration - provided in the C(intended_config) argument. - - When this option is configured as I(running), the module will - return the before and after diff of the running-config with respect - to any changes made to the device configuration. - choices: ['running', 'startup', 'intended'] - version_added: "2.4" - diff_ignore_lines: - description: - - Use this argument to specify one or more lines that should be - ignored during the diff. This is used for lines in the configuration - that are automatically updated by the system. This argument takes - a list of regular expressions or exact line matches. - version_added: "2.4" - intended_config: - description: - - The C(intended_config) provides the master configuration that - the node should conform to and is used to check the final - running-config against. This argument will not modify any settings - on the remote device and is strictly used to check the compliance - of the current device's configuration against. When specifying this - argument, the task should also modify the C(diff_against) value and - set it to I(intended). - version_added: "2.4" - backup_options: - description: - - This is a dict object containing configurable options related to backup file path. - The value of this option is read only when C(backup) is set to I(yes), if C(backup) is set - to I(no) this option will be silently ignored. - suboptions: - filename: - description: - - The filename to be used to store the backup configuration. If the filename - is not given it will be generated based on the hostname, current time and date - in format defined by _config.@ - dir_path: - description: - - This option provides the path ending with directory name in which the backup - configuration file will be stored. If the directory does not exist it will be first - created and the filename is either the value of C(filename) or default filename - as described in C(filename) options description. If the path value is not given - in that case a I(backup) directory will be created in the current working directory - and backup configuration will be copied in C(filename) within I(backup) directory. - type: path - type: dict - version_added: "2.8" -""" - -EXAMPLES = """ -- name: configure top level configuration - ios_config: - lines: hostname {{ inventory_hostname }} - -- name: configure interface settings - ios_config: - lines: - - description test interface - - ip address 172.31.1.1 255.255.255.0 - parents: interface Ethernet1 - -- name: configure ip helpers on multiple interfaces - ios_config: - lines: - - ip helper-address 172.26.1.10 - - ip helper-address 172.26.3.8 - parents: "{{ item }}" - with_items: - - interface Ethernet1 - - interface Ethernet2 - - interface GigabitEthernet1 - -- name: configure policer in Scavenger class - ios_config: - lines: - - conform-action transmit - - exceed-action drop - parents: - - policy-map Foo - - class Scavenger - - police cir 64000 - -- name: load new acl into device - ios_config: - lines: - - 10 permit ip host 192.0.2.1 any log - - 20 permit ip host 192.0.2.2 any log - - 30 permit ip host 192.0.2.3 any log - - 40 permit ip host 192.0.2.4 any log - - 50 permit ip host 192.0.2.5 any log - parents: ip access-list extended test - before: no ip access-list extended test - match: exact - -- name: check the running-config against master config - ios_config: - diff_against: intended - intended_config: "{{ lookup('file', 'master.cfg') }}" - -- name: check the startup-config against the running-config - ios_config: - diff_against: startup - diff_ignore_lines: - - ntp clock .* - -- name: save running to startup when modified - ios_config: - save_when: modified - -- name: for idempotency, use full-form commands - ios_config: - lines: - # - shut - - shutdown - # parents: int gig1/0/11 - parents: interface GigabitEthernet1/0/11 - -# Set boot image based on comparison to a group_var (version) and the version -# that is returned from the `ios_facts` module -- name: SETTING BOOT IMAGE - ios_config: - lines: - - no boot system - - boot system flash bootflash:{{new_image}} - host: "{{ inventory_hostname }}" - when: ansible_net_version != version - -- name: render a Jinja2 template onto an IOS device - ios_config: - backup: yes - src: ios_template.j2 - -- name: configurable backup path - ios_config: - src: ios_template.j2 - backup: yes - backup_options: - filename: backup.cfg - dir_path: /home/user -""" - -RETURN = """ -updates: - description: The set of commands that will be pushed to the remote device - returned: always - type: list - sample: ['hostname foo', 'router ospf 1', 'router-id 192.0.2.1'] -commands: - description: The set of commands that will be pushed to the remote device - returned: always - type: list - sample: ['hostname foo', 'router ospf 1', 'router-id 192.0.2.1'] -backup_path: - description: The full path to the backup file - returned: when backup is yes - type: str - sample: /playbooks/ansible/backup/ios_config.2016-07-16@22:28:34 -filename: - description: The name of the backup file - returned: when backup is yes and filename is not specified in backup options - type: str - sample: ios_config.2016-07-16@22:28:34 -shortname: - description: The full path to the backup file excluding the timestamp - returned: when backup is yes and filename is not specified in backup options - type: str - sample: /playbooks/ansible/backup/ios_config -date: - description: The date extracted from the backup file name - returned: when backup is yes - type: str - sample: "2016-07-16" -time: - description: The time extracted from the backup file name - returned: when backup is yes - type: str - sample: "22:28:34" -""" -import json - -from ansible.module_utils._text import to_text -from ansible.module_utils.connection import ConnectionError -from ansible.module_utils.network.ios.ios import run_commands, get_config -from ansible.module_utils.network.ios.ios import get_defaults_flag, get_connection -from ansible.module_utils.network.ios.ios import ios_argument_spec -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.config import NetworkConfig, dumps - - -def check_args(module, warnings): - if module.params['multiline_delimiter']: - if len(module.params['multiline_delimiter']) != 1: - module.fail_json(msg='multiline_delimiter value can only be a ' - 'single character') - - -def edit_config_or_macro(connection, commands): - # only catch the macro configuration command, - # not negated 'no' variation. - if commands[0].startswith("macro name"): - connection.edit_macro(candidate=commands) - else: - connection.edit_config(candidate=commands) - - -def get_candidate_config(module): - candidate = '' - if module.params['src']: - candidate = module.params['src'] - - elif module.params['lines']: - candidate_obj = NetworkConfig(indent=1) - parents = module.params['parents'] or list() - candidate_obj.add(module.params['lines'], parents=parents) - candidate = dumps(candidate_obj, 'raw') - - return candidate - - -def get_running_config(module, current_config=None, flags=None): - running = module.params['running_config'] - if not running: - if not module.params['defaults'] and current_config: - running = current_config - else: - running = get_config(module, flags=flags) - - return running - - -def save_config(module, result): - result['changed'] = True - if not module.check_mode: - run_commands(module, 'copy running-config startup-config\r') - else: - module.warn('Skipping command `copy running-config startup-config` ' - 'due to check_mode. Configuration not copied to ' - 'non-volatile storage') - - -def main(): - """ main entry point for module execution - """ - backup_spec = dict( - filename=dict(), - dir_path=dict(type='path') - ) - argument_spec = dict( - src=dict(type='path'), - - lines=dict(aliases=['commands'], type='list'), - parents=dict(type='list'), - - before=dict(type='list'), - after=dict(type='list'), - - match=dict(default='line', choices=['line', 'strict', 'exact', 'none']), - replace=dict(default='line', choices=['line', 'block']), - multiline_delimiter=dict(default='@'), - - running_config=dict(aliases=['config']), - intended_config=dict(), - - defaults=dict(type='bool', default=False), - backup=dict(type='bool', default=False), - backup_options=dict(type='dict', options=backup_spec), - save_when=dict(choices=['always', 'never', 'modified', 'changed'], default='never'), - - diff_against=dict(choices=['startup', 'intended', 'running']), - diff_ignore_lines=dict(type='list'), - ) - - argument_spec.update(ios_argument_spec) - - mutually_exclusive = [('lines', 'src'), - ('parents', 'src')] - - required_if = [('match', 'strict', ['lines']), - ('match', 'exact', ['lines']), - ('replace', 'block', ['lines']), - ('diff_against', 'intended', ['intended_config'])] - - module = AnsibleModule(argument_spec=argument_spec, - mutually_exclusive=mutually_exclusive, - required_if=required_if, - supports_check_mode=True) - - result = {'changed': False} - - warnings = list() - check_args(module, warnings) - result['warnings'] = warnings - - diff_ignore_lines = module.params['diff_ignore_lines'] - config = None - contents = None - flags = get_defaults_flag(module) if module.params['defaults'] else [] - connection = get_connection(module) - - if module.params['backup'] or (module._diff and module.params['diff_against'] == 'running'): - contents = get_config(module, flags=flags) - config = NetworkConfig(indent=1, contents=contents) - if module.params['backup']: - result['__backup__'] = contents - - if any((module.params['lines'], module.params['src'])): - match = module.params['match'] - replace = module.params['replace'] - path = module.params['parents'] - - candidate = get_candidate_config(module) - running = get_running_config(module, contents, flags=flags) - try: - response = connection.get_diff(candidate=candidate, running=running, diff_match=match, diff_ignore_lines=diff_ignore_lines, path=path, - diff_replace=replace) - except ConnectionError as exc: - module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) - - config_diff = response['config_diff'] - banner_diff = response['banner_diff'] - - if config_diff or banner_diff: - commands = config_diff.split('\n') - - if module.params['before']: - commands[:0] = module.params['before'] - - if module.params['after']: - commands.extend(module.params['after']) - - result['commands'] = commands - result['updates'] = commands - result['banners'] = banner_diff - - # send the configuration commands to the device and merge - # them with the current running config - if not module.check_mode: - if commands: - edit_config_or_macro(connection, commands) - if banner_diff: - connection.edit_banner(candidate=json.dumps(banner_diff), multiline_delimiter=module.params['multiline_delimiter']) - - result['changed'] = True - - running_config = module.params['running_config'] - startup_config = None - - if module.params['save_when'] == 'always': - save_config(module, result) - elif module.params['save_when'] == 'modified': - output = run_commands(module, ['show running-config', 'show startup-config']) - - running_config = NetworkConfig(indent=1, contents=output[0], ignore_lines=diff_ignore_lines) - startup_config = NetworkConfig(indent=1, contents=output[1], ignore_lines=diff_ignore_lines) - - if running_config.sha1 != startup_config.sha1: - save_config(module, result) - elif module.params['save_when'] == 'changed' and result['changed']: - save_config(module, result) - - if module._diff: - if not running_config: - output = run_commands(module, 'show running-config') - contents = output[0] - else: - contents = running_config - - # recreate the object in order to process diff_ignore_lines - running_config = NetworkConfig(indent=1, contents=contents, ignore_lines=diff_ignore_lines) - - if module.params['diff_against'] == 'running': - if module.check_mode: - module.warn("unable to perform diff against running-config due to check mode") - contents = None - else: - contents = config.config_text - - elif module.params['diff_against'] == 'startup': - if not startup_config: - output = run_commands(module, 'show startup-config') - contents = output[0] - else: - contents = startup_config.config_text - - elif module.params['diff_against'] == 'intended': - contents = module.params['intended_config'] - - if contents is not None: - base_config = NetworkConfig(indent=1, contents=contents, ignore_lines=diff_ignore_lines) - - if running_config.sha1 != base_config.sha1: - if module.params['diff_against'] == 'intended': - before = running_config - after = base_config - elif module.params['diff_against'] in ('startup', 'running'): - before = base_config - after = running_config - - result.update({ - 'changed': True, - 'diff': {'before': str(before), 'after': str(after)} - }) - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_facts.py b/lib/ansible/modules/network/ios/ios_facts.py deleted file mode 100644 index e2f147e6694..00000000000 --- a/lib/ansible/modules/network/ios/ios_facts.py +++ /dev/null @@ -1,239 +0,0 @@ -#!/usr/bin/python -# -# 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 . -# -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_facts -version_added: "2.2" -author: - - "Peter Sprygada (@privateip)" - - "Sumit Jaiswal (@justjais)" -short_description: Collect facts from remote devices running Cisco IOS -description: - - Collects a base set of device facts from a remote device that - is running IOS. This module prepends all of the - base network fact keys with C(ansible_net_). The facts - module will always collect a base set of facts from the device - and can enable or disable collection of additional facts. -extends_documentation_fragment: ios -notes: - - Tested against IOS 15.6 -options: - gather_subset: - description: - - When supplied, this argument restricts the facts collected - to a given subset. - - Possible values for this argument include - C(all), C(min), C(hardware), C(config), and C(interfaces). - - Specify a list of values to include a larger subset. - - Use a value with an initial C(!) to collect all facts except that subset. - required: false - default: '!config' - gather_network_resources: - description: - - When supplied, this argument will restrict the facts collected - to a given subset. Possible values for this argument include - all and the resources like interfaces, vlans etc. - Can specify a list of values to include a larger subset. - Values can also be used with an initial C(M(!)) to specify that - a specific subset should not be collected. - Valid subsets are 'all', 'interfaces', 'l2_interfaces', 'vlans', - 'lag_interfaces', 'lacp', 'lacp_interfaces', 'lldp_global', - 'lldp_interfaces', 'l3_interfaces', 'acl_interfaces', 'static_routes', 'acls'. - version_added: "2.9" -""" - -EXAMPLES = """ -- name: Gather all legacy facts - ios_facts: - gather_subset: all - -- name: Gather only the config and default facts - ios_facts: - gather_subset: - - config - -- name: Do not gather hardware facts - ios_facts: - gather_subset: - - "!hardware" - -- name: Gather legacy and resource facts - ios_facts: - gather_subset: all - gather_network_resources: all - -- name: Gather only the interfaces resource facts and no legacy facts - ios_facts: - gather_subset: - - '!all' - - '!min' - gather_network_resources: - - interfaces - -- name: Gather interfaces resource and minimal legacy facts - ios_facts: - gather_subset: min - gather_network_resources: interfaces - -- name: Gather L2 interfaces resource and minimal legacy facts - ios_facts: - gather_subset: min - gather_network_resources: l2_interfaces - -- name: Gather L3 interfaces resource and minimal legacy facts - ios_facts: - gather_subset: min - gather_network_resources: l3_interfaces - -""" - -RETURN = """ -ansible_net_gather_subset: - description: The list of fact subsets collected from the device - returned: always - type: list - -ansible_net_gather_network_resources: - description: The list of fact for network resource subsets collected from the device - returned: when the resource is configured - type: list - -# default -ansible_net_model: - description: The model name returned from the device - returned: always - type: str -ansible_net_serialnum: - description: The serial number of the remote device - returned: always - type: str -ansible_net_version: - description: The operating system version running on the remote device - returned: always - type: str -ansible_net_iostype: - description: The operating system type (IOS or IOS-XE) running on the remote device - returned: always - type: str -ansible_net_hostname: - description: The configured hostname of the device - returned: always - type: str -ansible_net_image: - description: The image file the device is running - returned: always - type: str -ansible_net_stacked_models: - description: The model names of each device in the stack - returned: when multiple devices are configured in a stack - type: list -ansible_net_stacked_serialnums: - description: The serial numbers of each device in the stack - returned: when multiple devices are configured in a stack - type: list -ansible_net_api: - description: The name of the transport - returned: always - type: str -ansible_net_python_version: - description: The Python version Ansible controller is using - returned: always - type: str - -# hardware -ansible_net_filesystems: - description: All file system names available on the device - returned: when hardware is configured - type: list -ansible_net_filesystems_info: - description: A hash of all file systems containing info about each file system (e.g. free and total space) - returned: when hardware is configured - type: dict -ansible_net_memfree_mb: - description: The available free memory on the remote device in Mb - returned: when hardware is configured - type: int -ansible_net_memtotal_mb: - description: The total memory on the remote device in Mb - returned: when hardware is configured - type: int - -# config -ansible_net_config: - description: The current active config from the device - returned: when config is configured - type: str - -# interfaces -ansible_net_all_ipv4_addresses: - description: All IPv4 addresses configured on the device - returned: when interfaces is configured - type: list -ansible_net_all_ipv6_addresses: - description: All IPv6 addresses configured on the device - returned: when interfaces is configured - type: list -ansible_net_interfaces: - description: A hash of all interfaces running on the system - returned: when interfaces is configured - type: dict -ansible_net_neighbors: - description: - - The list of CDP and LLDP neighbors from the remote device. If both, - CDP and LLDP neighbor data is present on one port, CDP is preferred. - returned: when interfaces is configured - type: dict -""" - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.facts.facts import FactsArgs -from ansible.module_utils.network.ios.facts.facts import Facts -from ansible.module_utils.network.ios.ios import ios_argument_spec - - -def main(): - """ - Main entry point for module execution - - :returns: ansible_facts - """ - argument_spec = FactsArgs.argument_spec - argument_spec.update(ios_argument_spec) - - module = AnsibleModule(argument_spec=argument_spec, - supports_check_mode=True) - - warnings = [] - if module.params["gather_subset"] == "!config": - warnings.append('default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards') - - result = Facts(module).get_facts() - - ansible_facts, additional_warnings = result - warnings.extend(additional_warnings) - - module.exit_json(ansible_facts=ansible_facts, warnings=warnings) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_interfaces.py b/lib/ansible/modules/network/ios/ios_interfaces.py deleted file mode 100644 index 4988f029be3..00000000000 --- a/lib/ansible/modules/network/ios/ios_interfaces.py +++ /dev/null @@ -1,405 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The module file for ios_interfaces -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_interfaces -version_added: 2.9 -short_description: Manages interface attributes of Cisco IOS network devices -description: This module manages the interface attributes of Cisco IOS network devices. -author: Sumit Jaiswal (@justjais) -notes: -- Tested against Cisco IOSv Version 15.2 on VIRL -- This module works with connection C(network_cli). - See L(IOS Platform Options,../network/user_guide/platform_ios.html). -options: - config: - description: A dictionary of interface options - type: list - suboptions: - name: - description: - - Full name of interface, e.g. GigabitEthernet0/2, loopback999. - type: str - required: True - description: - description: - - Interface description. - type: str - enabled: - description: - - Administrative state of the interface. - - Set the value to C(true) to administratively enable the interface or C(false) to disable it. - type: bool - default: True - speed: - description: - - Interface link speed. Applicable for Ethernet interfaces only. - type: str - mtu: - description: - - MTU for a specific interface. Applicable for Ethernet interfaces only. - - Refer to vendor documentation for valid values. - type: int - duplex: - description: - - Interface link status. Applicable for Ethernet interfaces only, either in half duplex, - full duplex or in automatic state which negotiates the duplex automatically. - type: str - choices: ['full', 'half', 'auto'] - state: - choices: - - merged - - replaced - - overridden - - deleted - default: merged - description: - - The state of the configuration after module completion - type: str -""" - -EXAMPLES = """ ---- - -# Using merged - -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description This is test -# no ip address -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# no ip address -# duplex auto -# speed auto - -- name: Merge provided configuration with device configuration - ios_interfaces: - config: - - name: GigabitEthernet0/2 - description: 'Configured and Merged by Ansible Network' - enabled: True - - name: GigabitEthernet0/3 - description: 'Configured and Merged by Ansible Network' - mtu: 2800 - enabled: False - speed: 100 - duplex: full - state: merged - -# After state: -# ------------ -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description Configured and Merged by Ansible Network -# no ip address -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# description Configured and Merged by Ansible Network -# mtu 2800 -# no ip address -# shutdown -# duplex full -# speed 100 - -# Using replaced - -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description Configured by Ansible Network -# no ip address -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# mtu 2000 -# no ip address -# shutdown -# duplex full -# speed 100 - -- name: Replaces device configuration of listed interfaces with provided configuration - ios_interfaces: - config: - - name: GigabitEthernet0/3 - description: 'Configured and Replaced by Ansible Network' - enabled: False - duplex: auto - mtu: 2500 - speed: 1000 - state: replaced - -# After state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description Configured by Ansible Network -# no ip address -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# description Configured and Replaced by Ansible Network -# mtu 2500 -# no ip address -# shutdown -# duplex full -# speed 1000 - -# Using overridden - -# Before state: -# ------------- -# -# vios#show running-config | section ^interface# -# interface GigabitEthernet0/1 -# description Configured by Ansible -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description This is test -# no ip address -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# description Configured by Ansible -# mtu 2800 -# no ip address -# shutdown -# duplex full -# speed 100 - -- name: Override device configuration of all interfaces with provided configuration - ios_interfaces: - config: - - name: GigabitEthernet0/2 - description: 'Configured and Overridden by Ansible Network' - speed: 1000 - - name: GigabitEthernet0/3 - description: 'Configured and Overridden by Ansible Network' - enabled: False - duplex: full - mtu: 2000 - state: overridden - -# After state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description Configured and Overridden by Ansible Network -# no ip address -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# description Configured and Overridden by Ansible Network -# mtu 2000 -# no ip address -# shutdown -# duplex full -# speed 100 - -# Using Deleted - -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description Configured by Ansible Network -# no ip address -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# mtu 2500 -# no ip address -# shutdown -# duplex full -# speed 1000 - -- name: "Delete module attributes of given interfaces (Note: This won't delete the interface itself)" - ios_interfaces: - config: - - name: GigabitEthernet0/2 - state: deleted - -# After state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# mtu 2500 -# no ip address -# shutdown -# duplex full -# speed 1000 - -# Using Deleted without any config passed -#"(NOTE: This will delete all of configured resource module attributes from each configured interface)" - -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description Configured by Ansible Network -# no ip address -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# mtu 2500 -# no ip address -# shutdown -# duplex full -# speed 1000 - -- name: "Delete module attributes of all interfaces (Note: This won't delete the interface itself)" - ios_interfaces: - state: deleted - -# After state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/3 -# no ip address -# duplex auto -# speed auto - -""" - -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: list - sample: The configuration returned will always be in the same format of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: list - sample: The configuration returned will always be in the same format of the parameters above. -commands: - description: The set of commands pushed to the remote device - returned: always - type: list - sample: ['interface GigabitEthernet 0/1', 'description This is test', 'speed 100'] -""" - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.interfaces.interfaces import InterfacesArgs -from ansible.module_utils.network.ios.config.interfaces.interfaces import Interfaces - - -def main(): - """ - Main entry point for module execution - - :returns: the result form module invocation - """ - required_if = [('state', 'merged', ('config',)), - ('state', 'replaced', ('config',)), - ('state', 'overridden', ('config',))] - - module = AnsibleModule(argument_spec=InterfacesArgs.argument_spec, - required_if=required_if, - supports_check_mode=True) - - result = Interfaces(module).execute_module() - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_l2_interfaces.py b/lib/ansible/modules/network/ios/ios_l2_interfaces.py deleted file mode 100644 index 19eadb8426c..00000000000 --- a/lib/ansible/modules/network/ios/ios_l2_interfaces.py +++ /dev/null @@ -1,390 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The module file for ios_l2_interfaces -""" - - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - -DOCUMENTATION = """ ---- -module: ios_l2_interfaces -version_added: 2.9 -short_description: Manage Layer-2 interface on Cisco IOS devices. -description: This module provides declarative management of Layer-2 interface on Cisco IOS devices. -author: Sumit Jaiswal (@justjais) -notes: - - Tested against Cisco IOSv Version 15.2 on VIRL - - This module works with connection C(network_cli). - See L(IOS Platform Options,../network/user_guide/platform_ios.html). -options: - config: - description: A dictionary of Layer-2 interface options - type: list - elements: dict - suboptions: - name: - description: - - Full name of the interface excluding any logical unit number, i.e. GigabitEthernet0/1. - type: str - required: True - access: - description: - - Switchport mode access command to configure the interface as a layer 2 access. - type: dict - suboptions: - vlan: - description: - - Configure given VLAN in access port. It's used as the access VLAN ID. - type: int - voice: - description: - - Switchport mode voice command to configure the interface with a voice vlan. - type: dict - suboptions: - vlan: - description: - - Configure given voice VLAN on access port. It's used as the voice VLAN ID. - type: int - trunk: - description: - - Switchport mode trunk command to configure the interface as a Layer 2 trunk. - Note The encapsulation is always set to dot1q. - type: dict - suboptions: - allowed_vlans: - description: - - List of allowed VLANs in a given trunk port. These are the only VLANs that will be - configured on the trunk. - type: list - native_vlan: - description: - - Native VLAN to be configured in trunk port. It's used as the trunk native VLAN ID. - type: int - encapsulation: - description: - - Trunking encapsulation when interface is in trunking mode. - choices: ['dot1q','isl','negotiate'] - type: str - pruning_vlans: - description: - - Pruning VLAN to be configured in trunk port. It's used as the trunk pruning VLAN ID. - type: list - mode: - description: - - Mode in which interface needs to be configured. - - An interface whose trunk encapsulation is "Auto" can not be configured to "trunk" mode. - version_added: '2.10' - type: str - choices: ['access', 'trunk'] - state: - choices: - - merged - - replaced - - overridden - - deleted - default: merged - description: - - The state of the configuration after module completion - type: str -""" - -EXAMPLES = """ ---- - -# Using merged - -# Before state: -# ------------- -# -# viosl2#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# negotiation auto -# interface GigabitEthernet0/2 -# description This is test -# switchport access vlan 20 -# media-type rj45 -# negotiation auto - -- name: Merge provided configuration with device configuration - ios_l2_interfaces: - config: - - name: GigabitEthernet0/1 - mode: access - access: - vlan: 10 - voice: - vlan: 40 - - name: GigabitEthernet0/2 - mode: trunk - trunk: - allowed_vlans: 10-20,40 - native_vlan: 20 - pruning_vlans: 10,20 - encapsulation: dot1q - state: merged - -# After state: -# ------------ -# -# viosl2#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# switchport access vlan 10 -# switchport access vlan 40 -# switchport mode access -# negotiation auto -# interface GigabitEthernet0/2 -# description This is test -# switchport trunk allowed vlan 10-20,40 -# switchport trunk encapsulation dot1q -# switchport trunk native vlan 20 -# switchport trunk pruning vlan 10,20 -# switchport mode trunk -# media-type rj45 -# negotiation auto - -# Using replaced - -# Before state: -# ------------- -# -# viosl2#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# switchport access vlan 20 -# negotiation auto -# interface GigabitEthernet0/2 -# description This is test -# switchport access vlan 20 -# media-type rj45 -# negotiation auto - -- name: Replaces device configuration of listed l2 interfaces with provided configuration - ios_l2_interfaces: - config: - - name: GigabitEthernet0/2 - trunk: - - allowed_vlans: 20-25,40 - native_vlan: 20 - pruning_vlans: 10 - encapsulation: isl - state: replaced - -# After state: -# ------------- -# -# viosl2#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# switchport access vlan 20 -# negotiation auto -# interface GigabitEthernet0/2 -# description This is test -# switchport trunk allowed vlan 20-25,40 -# switchport trunk encapsulation isl -# switchport trunk native vlan 20 -# switchport trunk pruning vlan 10 -# media-type rj45 -# negotiation auto - -# Using overridden - -# Before state: -# ------------- -# -# viosl2#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# switchport trunk encapsulation dot1q -# switchport trunk native vlan 20 -# negotiation auto -# interface GigabitEthernet0/2 -# description This is test -# switchport access vlan 20 -# switchport trunk encapsulation dot1q -# switchport trunk native vlan 20 -# media-type rj45 -# negotiation auto - -- name: Override device configuration of all l2 interfaces with provided configuration - ios_l2_interfaces: - config: - - name: GigabitEthernet0/2 - access: - vlan: 20 - voice: - vlan: 40 - state: overridden - -# After state: -# ------------- -# -# viosl2#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# negotiation auto -# interface GigabitEthernet0/2 -# description This is test -# switchport access vlan 20 -# switchport voice vlan 40 -# media-type rj45 -# negotiation auto - -# Using Deleted - -# Before state: -# ------------- -# -# viosl2#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# switchport access vlan 20 -# negotiation auto -# interface GigabitEthernet0/2 -# description This is test -# switchport access vlan 20 -# switchport trunk allowed vlan 20-40,60,80 -# switchport trunk encapsulation dot1q -# switchport trunk native vlan 10 -# switchport trunk pruning vlan 10 -# media-type rj45 -# negotiation auto - -- name: Delete IOS L2 interfaces as in given arguments - ios_l2_interfaces: - config: - - name: GigabitEthernet0/1 - state: deleted - -# After state: -# ------------- -# -# viosl2#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# negotiation auto -# interface GigabitEthernet0/2 -# description This is test -# switchport access vlan 20 -# switchport trunk allowed vlan 20-40,60,80 -# switchport trunk encapsulation dot1q -# switchport trunk native vlan 10 -# switchport trunk pruning vlan 10 -# media-type rj45 -# negotiation auto - - -# Using Deleted without any config passed -#"(NOTE: This will delete all of configured resource module attributes from each configured interface)" - -# Before state: -# ------------- -# -# viosl2#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# switchport access vlan 20 -# negotiation auto -# interface GigabitEthernet0/2 -# description This is test -# switchport access vlan 20 -# switchport trunk allowed vlan 20-40,60,80 -# switchport trunk encapsulation dot1q -# switchport trunk native vlan 10 -# switchport trunk pruning vlan 10 -# media-type rj45 -# negotiation auto - -- name: Delete IOS L2 interfaces as in given arguments - ios_l2_interfaces: - state: deleted - -# After state: -# ------------- -# -# viosl2#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# negotiation auto -# interface GigabitEthernet0/2 -# description This is test -# media-type rj45 -# negotiation auto - -""" - -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: list - sample: The configuration returned will always be in the same format of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: list - sample: The configuration returned will always be in the same format of the parameters above. -commands: - description: The set of commands pushed to the remote device - returned: always - type: list - sample: ['interface GigabitEthernet0/1', 'switchport access vlan 20'] -""" - - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.l2_interfaces.l2_interfaces import L2_InterfacesArgs -from ansible.module_utils.network.ios.config.l2_interfaces.l2_interfaces import L2_Interfaces - - -def main(): - """ - Main entry point for module execution - - :returns: the result form module invocation - """ - required_if = [('state', 'merged', ('config',)), - ('state', 'replaced', ('config',)), - ('state', 'overridden', ('config',))] - - module = AnsibleModule(argument_spec=L2_InterfacesArgs.argument_spec, - required_if=required_if, - supports_check_mode=True) - - result = L2_Interfaces(module).execute_module() - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_l3_interfaces.py b/lib/ansible/modules/network/ios/ios_l3_interfaces.py deleted file mode 100644 index 9fd054ef754..00000000000 --- a/lib/ansible/modules/network/ios/ios_l3_interfaces.py +++ /dev/null @@ -1,442 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat Inc. -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################## -# WARNING -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -# -############################################## - -""" -The module file for ios_l3_interfaces -""" - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_l3_interfaces -version_added: 2.9 -short_description: Manage Layer-3 interface on Cisco IOS devices. -description: -- This module provides declarative management of Layer-3 interface - on Cisco IOS devices. -author: Sumit Jaiswal (@justjais) -options: - config: - description: A dictionary of Layer-3 interface options - type: list - elements: dict - suboptions: - name: - description: - - Full name of the interface excluding any logical unit number, - i.e. GigabitEthernet0/1. - type: str - required: True - ipv4: - description: - - IPv4 address to be set for the Layer-3 interface mentioned in - I(name) option. The address format is /, - the mask is number in range 0-32 eg. 192.168.0.1/24. - type: list - elements: dict - suboptions: - address: - description: - - Configures the IPv4 address for Interface. - type: str - secondary: - description: - - Configures the IP address as a secondary address. - type: bool - dhcp_client: - description: - - Configures and specifies client-id to use over DHCP ip. - Note, This option shall work only when dhcp is configured - as IP. - - GigabitEthernet interface number - type: int - dhcp_hostname: - description: - - Configures and specifies value for hostname option over - DHCP ip. Note, This option shall work only when dhcp is - configured as IP. - type: str - ipv6: - description: - - IPv6 address to be set for the Layer-3 interface mentioned in - I(name) option. - - The address format is /, the mask is number - in range 0-128 eg. fd5d:12c9:2201:1::1/64 - type: list - elements: dict - suboptions: - address: - description: - - Configures the IPv6 address for Interface. - type: str - state: - choices: - - merged - - replaced - - overridden - - deleted - default: merged - description: - - The state of the configuration after module completion - type: str -""" - -EXAMPLES = """ ---- -# Using merged -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# ip address 10.1.1.1 255.255.255.0 -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description This is test -# no ip address -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# no ip address -# interface GigabitEthernet0/3.100 -# encapsulation dot1Q 20 - -- name: Merge provided configuration with device configuration - ios_l3_interfaces: - config: - - name: GigabitEthernet0/1 - ipv4: - - address: 192.168.0.1/24 - secondary: True - - name: GigabitEthernet0/2 - ipv4: - - address: 192.168.0.2/24 - - name: GigabitEthernet0/3 - ipv6: - - address: fd5d:12c9:2201:1::1/64 - - name: GigabitEthernet0/3.100 - ipv4: - - address: 192.168.0.3/24 - state: merged - -# After state: -# ------------ -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# ip address 10.1.1.1 255.255.255.0 -# ip address 192.168.0.1 255.255.255.0 secondary -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description This is test -# ip address 192.168.0.2 255.255.255.0 -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# ipv6 address FD5D:12C9:2201:1::1/64 -# interface GigabitEthernet0/3.100 -# encapsulation dot1Q 20 -# ip address 192.168.0.3 255.255.255.0 - -# Using replaced -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# ip address 10.1.1.1 255.255.255.0 -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description This is test -# no ip address -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# ip address 192.168.2.0 255.255.255.0 -# interface GigabitEthernet0/3.100 -# encapsulation dot1Q 20 -# ip address 192.168.0.2 255.255.255.0 - -- name: Replaces device configuration of listed interfaces with provided configuration - ios_l3_interfaces: - config: - - name: GigabitEthernet0/2 - ipv4: - - address: 192.168.2.0/24 - - name: GigabitEthernet0/3 - ipv4: - - address: dhcp - dhcp_client: 2 - dhcp_hostname: test.com - - name: GigabitEthernet0/3.100 - ipv4: - - address: 192.168.0.3/24 - secondary: True - state: replaced - -# After state: -# ------------ -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# ip address 10.1.1.1 255.255.255.0 -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description This is test -# ip address 192.168.2.1 255.255.255.0 -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# ip address dhcp client-id GigabitEthernet0/2 hostname test.com -# interface GigabitEthernet0/3.100 -# encapsulation dot1Q 20 -# ip address 192.168.0.2 255.255.255.0 -# ip address 192.168.0.3 255.255.255.0 secondary - -# Using overridden -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# ip address 10.1.1.1 255.255.255.0 -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description This is test -# ip address 192.168.2.1 255.255.255.0 -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# ipv6 address FD5D:12C9:2201:1::1/64 -# interface GigabitEthernet0/3.100 -# encapsulation dot1Q 20 -# ip address 192.168.0.2 255.255.255.0 - -- name: Override device configuration of all interfaces with provided configuration - ios_l3_interfaces: - config: - - name: GigabitEthernet0/2 - ipv4: - - address: 192.168.0.1/24 - - name: GigabitEthernet0/3.100 - ipv6: - - address: autoconfig - state: overridden - -# After state: -# ------------ -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# description Configured by Ansible -# no ip address -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description This is test -# ip address 192.168.0.1 255.255.255.0 -# duplex auto -# speed 1000 -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# interface GigabitEthernet0/3.100 -# encapsulation dot1Q 20 -# ipv6 address autoconfig - -# Using Deleted -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# ip address 192.0.2.10 255.255.255.0 -# shutdown -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description Configured by Ansible Network -# ip address 192.168.1.0 255.255.255.0 -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# ip address 192.168.0.1 255.255.255.0 -# shutdown -# duplex full -# speed 10 -# ipv6 address FD5D:12C9:2201:1::1/64 -# interface GigabitEthernet0/3.100 -# encapsulation dot1Q 20 -# ip address 192.168.0.2 255.255.255.0 - -- name: "Delete attributes of given interfaces (NOTE: This won't delete the interface itself)" - ios_l3_interfaces: - config: - - name: GigabitEthernet0/2 - - name: GigabitEthernet0/3.100 - state: deleted - -# After state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# no ip address -# shutdown -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description Configured by Ansible Network -# no ip address -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# ip address 192.168.0.1 255.255.255.0 -# shutdown -# duplex full -# speed 10 -# ipv6 address FD5D:12C9:2201:1::1/64 -# interface GigabitEthernet0/3.100 -# encapsulation dot1Q 20 - -# Using Deleted without any config passed -#"(NOTE: This will delete all of configured L3 resource module attributes from each configured interface)" - -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# ip address 192.0.2.10 255.255.255.0 -# shutdown -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description Configured by Ansible Network -# ip address 192.168.1.0 255.255.255.0 -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# ip address 192.168.0.1 255.255.255.0 -# shutdown -# duplex full -# speed 10 -# ipv6 address FD5D:12C9:2201:1::1/64 -# interface GigabitEthernet0/3.100 -# encapsulation dot1Q 20 -# ip address 192.168.0.2 255.255.255.0 - -- name: "Delete L3 attributes of ALL interfaces together (NOTE: This won't delete the interface itself)" - ios_l3_interfaces: - state: deleted - -# After state: -# ------------- -# -# vios#show running-config | section ^interface -# interface GigabitEthernet0/1 -# no ip address -# shutdown -# duplex auto -# speed auto -# interface GigabitEthernet0/2 -# description Configured by Ansible Network -# no ip address -# interface GigabitEthernet0/3 -# description Configured by Ansible Network -# shutdown -# duplex full -# speed 10 -# interface GigabitEthernet0/3.100 -# encapsulation dot1Q 20 - -""" - -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: list - sample: The configuration returned will always be in the same format of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: list - sample: The configuration returned will always be in the same format of the parameters above. -commands: - description: The set of commands pushed to the remote device - returned: always - type: list - sample: ['interface GigabitEthernet0/1', 'ip address 192.168.0.2 255.255.255.0'] -""" - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.l3_interfaces.l3_interfaces import L3_InterfacesArgs -from ansible.module_utils.network.ios.config.l3_interfaces.l3_interfaces import L3_Interfaces - - -def main(): - """ - Main entry point for module execution - :returns: the result form module invocation - """ - required_if = [('state', 'merged', ('config',)), - ('state', 'replaced', ('config',)), - ('state', 'overridden', ('config',))] - - module = AnsibleModule(argument_spec=L3_InterfacesArgs.argument_spec, - required_if=required_if, - supports_check_mode=True) - - result = L3_Interfaces(module).execute_module() - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_lacp.py b/lib/ansible/modules/network/ios/ios_lacp.py deleted file mode 100644 index 1ebe3b3cef6..00000000000 --- a/lib/ansible/modules/network/ios/ios_lacp.py +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The module file for ios_lacp -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network' -} - -DOCUMENTATION = """ ---- -module: ios_lacp -version_added: 2.9 -short_description: Manage Global Link Aggregation Control Protocol (LACP) on Cisco IOS devices. -description: This module provides declarative management of Global LACP on Cisco IOS network devices. -author: Sumit Jaiswal (@justjais) -notes: - - Tested against Cisco IOSv Version 15.2 on VIRL - - This module works with connection C(network_cli), - See L(IOS Platform Options,../network/user_guide/platform_ios.html). -options: - config: - description: The provided configurations. - type: dict - suboptions: - system: - description: This option sets the default system parameters for LACP. - type: dict - suboptions: - priority: - description: - - LACP priority for the system. - - Refer to vendor documentation for valid values. - type: int - required: True - state: - description: - - The state of the configuration after module completion - type: str - choices: - - merged - - replaced - - deleted - default: merged -""" - -EXAMPLES = """ - -# Using merged -# -# Before state: -# ------------- -# -# vios#show lacp sys-id -# 32768, 5e00.0000.8000 - -- name: Merge provided configuration with device configuration - ios_lacp: - config: - system: - priority: 123 - state: merged - -# After state: -# ------------ -# -# vios#show lacp sys-id -# 123, 5e00.0000.8000 - -# Using replaced -# -# Before state: -# ------------- -# -# vios#show lacp sys-id -# 500, 5e00.0000.8000 - -- name: Replaces Global LACP configuration - ios_lacp: - config: - system: - priority: 123 - state: replaced - -# After state: -# ------------ -# -# vios#show lacp sys-id -# 123, 5e00.0000.8000 - -# Using Deleted -# -# Before state: -# ------------- -# -# vios#show lacp sys-id -# 500, 5e00.0000.8000 - -- name: Delete Global LACP attribute - ios_lacp: - state: deleted - -# After state: -# ------------- -# -# vios#show lacp sys-id -# 32768, 5e00.0000.8000 - -""" - -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: list - sample: > - The configuration returned will always be in the same format - of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: list - sample: > - The configuration returned will always be in the same format - of the parameters above. -commands: - description: The set of commands pushed to the remote device. - returned: always - type: list - sample: ['lacp system-priority 10'] -""" - - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.lacp.lacp import LacpArgs -from ansible.module_utils.network.ios.config.lacp.lacp import Lacp - - -def main(): - """ - Main entry point for module execution - - :returns: the result form module invocation - """ - required_if = [('state', 'merged', ('config',)), - ('state', 'replaced', ('config',))] - - module = AnsibleModule(argument_spec=LacpArgs.argument_spec, - required_if=required_if, - supports_check_mode=True) - - result = Lacp(module).execute_module() - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_lacp_interfaces.py b/lib/ansible/modules/network/ios/ios_lacp_interfaces.py deleted file mode 100644 index d9e52e39cfb..00000000000 --- a/lib/ansible/modules/network/ios/ios_lacp_interfaces.py +++ /dev/null @@ -1,363 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The module file for ios_lacp_interfaces -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network' -} - - -DOCUMENTATION = """ ---- -module: ios_lacp_interfaces -version_added: 2.9 -short_description: Manage Link Aggregation Control Protocol (LACP) on Cisco IOS devices interface. -description: This module provides declarative management of LACP on Cisco IOS network devices lacp_interfaces. -author: Sumit Jaiswal (@justjais) -notes: - - Tested against Cisco IOSv Version 15.2 on VIRL. - - This module works with connection C(network_cli), - See L(IOS Platform Options,../network/user_guide/platform_ios.html). -options: - config: - description: A dictionary of LACP lacp_interfaces option - type: list - elements: dict - suboptions: - name: - description: - - Name of the Interface for configuring LACP. - type: str - required: True - port_priority: - description: - - LACP priority on this interface. - - Refer to vendor documentation for valid port values. - type: int - fast_switchover: - description: - - LACP fast switchover supported on this port channel. - type: bool - max_bundle: - description: - - LACP maximum number of ports to bundle in this port channel. - - Refer to vendor documentation for valid port values. - type: int - state: - description: - - The state of the configuration after module completion - type: str - choices: - - merged - - replaced - - overridden - - deleted - default: merged -""" - -EXAMPLES = """ - -# Using merged -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# interface GigabitEthernet0/2 -# shutdown -# interface GigabitEthernet0/3 -# shutdown - -- name: Merge provided configuration with device configuration - ios_lacp_interfaces: - config: - - name: GigabitEthernet0/1 - port_priority: 10 - - name: GigabitEthernet0/2 - port_priority: 20 - - name: GigabitEthernet0/3 - port_priority: 30 - - name: Port-channel10 - fast_switchover: True - max_bundle: 5 - state: merged - -# After state: -# ------------ -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# lacp fast-switchover -# lacp max-bundle 5 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# lacp port-priority 10 -# interface GigabitEthernet0/2 -# shutdown -# lacp port-priority 20 -# interface GigabitEthernet0/3 -# shutdown -# lacp port-priority 30 - -# Using overridden -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# lacp fast-switchover -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# lacp port-priority 10 -# interface GigabitEthernet0/2 -# shutdown -# lacp port-priority 20 -# interface GigabitEthernet0/3 -# shutdown -# lacp port-priority 30 - -- name: Override device configuration of all lacp_interfaces with provided configuration - ios_lacp_interfaces: - config: - - name: GigabitEthernet0/1 - port_priority: 20 - - name: Port-channel10 - max_bundle: 2 - state: overridden - -# After state: -# ------------ -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# lacp max-bundle 2 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# lacp port-priority 20 -# interface GigabitEthernet0/2 -# shutdown -# interface GigabitEthernet0/3 -# shutdown - -# Using replaced -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# lacp max-bundle 5 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# lacp port-priority 10 -# interface GigabitEthernet0/2 -# shutdown -# lacp port-priority 20 -# interface GigabitEthernet0/3 -# shutdown -# lacp port-priority 30 - -- name: Replaces device configuration of listed lacp_interfaces with provided configuration - ios_lacp_interfaces: - config: - - name: GigabitEthernet0/3 - port_priority: 40 - - name: Port-channel10 - fast_switchover: True - max_bundle: 2 - state: replaced - -# After state: -# ------------ -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# lacp fast-switchover -# lacp max-bundle 2 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# lacp port-priority 10 -# interface GigabitEthernet0/2 -# shutdown -# lacp port-priority 20 -# interface GigabitEthernet0/3 -# shutdown -# lacp port-priority 40 - -# Using Deleted -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# flowcontrol receive on -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# lacp port-priority 10 -# interface GigabitEthernet0/2 -# shutdown -# lacp port-priority 20 -# interface GigabitEthernet0/3 -# shutdown -# lacp port-priority 30 - -- name: "Delete LACP attributes of given interfaces (Note: This won't delete the interface itself)" - ios_lacp_interfaces: - config: - - name: GigabitEthernet0/1 - state: deleted - -# After state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# interface GigabitEthernet0/2 -# shutdown -# lacp port-priority 20 -# interface GigabitEthernet0/3 -# shutdown -# lacp port-priority 30 - -# Using Deleted without any config passed -# "(NOTE: This will delete all of configured LLDP module attributes)" -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# lacp fast-switchover -# interface Port-channel20 -# lacp max-bundle 2 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# lacp port-priority 10 -# interface GigabitEthernet0/2 -# shutdown -# lacp port-priority 20 -# interface GigabitEthernet0/3 -# shutdown -# lacp port-priority 30 - -- name: "Delete LACP attributes for all configured interfaces (Note: This won't delete the interface itself)" - ios_lacp_interfaces: - state: deleted - -# After state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# interface GigabitEthernet0/2 -# shutdown -# interface GigabitEthernet0/3 -# shutdown - -""" - -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: list - sample: > - The configuration returned will always be in the same format - of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: list - sample: > - The configuration returned will always be in the same format - of the parameters above. -commands: - description: The set of commands pushed to the remote device. - returned: always - type: list - sample: ['interface GigabitEthernet 0/1', 'lacp port-priority 30'] -""" - - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.lacp_interfaces.lacp_interfaces import Lacp_InterfacesArgs -from ansible.module_utils.network.ios.config.lacp_interfaces.lacp_interfaces import Lacp_Interfaces - - -def main(): - """ - Main entry point for module execution - - :returns: the result form module invocation - """ - required_if = [('state', 'merged', ('config',)), - ('state', 'replaced', ('config',)), - ('state', 'overridden', ('config',))] - - module = AnsibleModule(argument_spec=Lacp_InterfacesArgs.argument_spec, - required_if=required_if, - supports_check_mode=True) - - result = Lacp_Interfaces(module).execute_module() - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_lag_interfaces.py b/lib/ansible/modules/network/ios/ios_lag_interfaces.py deleted file mode 100644 index b5351c6dd8e..00000000000 --- a/lib/ansible/modules/network/ios/ios_lag_interfaces.py +++ /dev/null @@ -1,390 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat Inc. -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################## -# WARNING -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -# -############################################## - -""" -The module file for ios_l3_interfaces -""" - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_lag_interfaces -version_added: 2.9 -short_description: Manage Link Aggregation on Cisco IOS devices. -description: This module manages properties of Link Aggregation Group on Cisco IOS devices. -author: Sumit Jaiswal (@justjais) -notes: - - Tested against Cisco IOSv Version 15.2 on VIRL - - This module works with connection C(network_cli). - See L(IOS Platform Options,../network/user_guide/platform_ios.html). -options: - config: - description: A list of link aggregation group configurations. - type: list - elements: dict - suboptions: - name: - description: - - ID of Ethernet Channel of interfaces. - - Refer to vendor documentation for valid port values. - type: str - required: True - members: - description: - - Interface options for the link aggregation group. - type: list - suboptions: - member: - description: - - Interface member of the link aggregation group. - type: str - mode: - description: - - Etherchannel Mode of the interface for link aggregation. - type: str - choices: - - 'auto' - - 'on' - - 'desirable' - - 'active' - - 'passive' - link: - description: - - Assign a link identifier used for load-balancing. - - Refer to vendor documentation for valid values. - - NOTE, parameter only supported on Cisco IOS XE platform. - type: int - state: - description: - - The state of the configuration after module completion - type: str - choices: - - merged - - replaced - - overridden - - deleted - default: merged -""" - -EXAMPLES = """ ---- -# Using merged -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface GigabitEthernet0/1 -# shutdown -# interface GigabitEthernet0/2 -# shutdown -# interface GigabitEthernet0/3 -# shutdown -# interface GigabitEthernet0/4 -# shutdown - -- name: Merge provided configuration with device configuration - ios_lag_interfaces: - config: - - name: 10 - members: - - member: GigabitEthernet0/1 - mode: auto - - member: GigabitEthernet0/2 - mode: auto - - name: 20 - members: - - member: GigabitEthernet0/3 - mode: on - - name: 30 - members: - - member: GigabitEthernet0/4 - mode: active - state: merged - -# After state: -# ------------ -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# channel-group 10 mode auto -# interface GigabitEthernet0/2 -# shutdown -# channel-group 10 mode auto -# interface GigabitEthernet0/3 -# shutdown -# channel-group 20 mode on -# interface GigabitEthernet0/4 -# shutdown -# channel-group 30 mode active - -# Using overridden -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# channel-group 10 mode auto -# interface GigabitEthernet0/2 -# shutdown -# channel-group 10 mode auto -# interface GigabitEthernet0/3 -# shutdown -# channel-group 20 mode on -# interface GigabitEthernet0/4 -# shutdown -# channel-group 30 mode active - -- name: Override device configuration of all interfaces with provided configuration - ios_lag_interfaces: - config: - - name: 20 - members: - - member: GigabitEthernet0/2 - mode: auto - - member: GigabitEthernet0/3 - mode: auto - state: overridden - -# After state: -# ------------ -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# interface GigabitEthernet0/2 -# shutdown -# channel-group 20 mode auto -# interface GigabitEthernet0/3 -# shutdown -# channel-group 20 mode auto -# interface GigabitEthernet0/4 -# shutdown - -# Using replaced -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# channel-group 10 mode auto -# interface GigabitEthernet0/2 -# shutdown -# channel-group 10 mode auto -# interface GigabitEthernet0/3 -# shutdown -# channel-group 20 mode on -# interface GigabitEthernet0/4 -# shutdown -# channel-group 30 mode active - -- name: Replaces device configuration of listed interfaces with provided configuration - ios_lag_interfaces: - config: - - name: 40 - members: - - member: GigabitEthernet0/3 - mode: auto - state: replaced - -# After state: -# ------------ -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface Port-channel20 -# interface Port-channel30 -# interface Port-channel40 -# interface GigabitEthernet0/1 -# shutdown -# channel-group 10 mode auto -# interface GigabitEthernet0/2 -# shutdown -# channel-group 10 mode auto -# interface GigabitEthernet0/3 -# shutdown -# channel-group 40 mode on -# interface GigabitEthernet0/4 -# shutdown -# channel-group 30 mode active - -# Using Deleted -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# channel-group 10 mode auto -# interface GigabitEthernet0/2 -# shutdown -# channel-group 10 mode auto -# interface GigabitEthernet0/3 -# shutdown -# channel-group 20 mode on -# interface GigabitEthernet0/4 -# shutdown -# channel-group 30 mode active - -- name: "Delete LAG attributes of given interfaces (Note: This won't delete the interface itself)" - ios_lag_interfaces: - config: - - name: 10 - - name: 20 - state: deleted - -# After state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# interface GigabitEthernet0/2 -# shutdown -# interface GigabitEthernet0/3 -# shutdown -# interface GigabitEthernet0/4 -# shutdown -# channel-group 30 mode active - -# Using Deleted without any config passed -#"(NOTE: This will delete all of configured LLDP module attributes)" - -# -# Before state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# channel-group 10 mode auto -# interface GigabitEthernet0/2 -# shutdown -# channel-group 10 mode auto -# interface GigabitEthernet0/3 -# shutdown -# channel-group 20 mode on -# interface GigabitEthernet0/4 -# shutdown -# channel-group 30 mode active - -- name: "Delete all configured LAG attributes for interfaces (Note: This won't delete the interface itself)" - ios_lag_interfaces: - state: deleted - -# After state: -# ------------- -# -# vios#show running-config | section ^interface -# interface Port-channel10 -# interface Port-channel20 -# interface Port-channel30 -# interface GigabitEthernet0/1 -# shutdown -# interface GigabitEthernet0/2 -# shutdown -# interface GigabitEthernet0/3 -# shutdown -# interface GigabitEthernet0/4 -# shutdown -""" - -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: list - sample: The configuration returned will always be in the same format of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: list - sample: The configuration returned will always be in the same format of the parameters above. -commands: - description: The set of commands pushed to the remote device - returned: always - type: list - sample: ['interface GigabitEthernet0/1', 'channel-group 1 mode active'] -""" - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.lag_interfaces.lag_interfaces import Lag_interfacesArgs -from ansible.module_utils.network.ios.config.lag_interfaces.lag_interfaces import Lag_interfaces - - -def main(): - """ - Main entry point for module execution - :returns: the result form module invocation - """ - required_if = [('state', 'merged', ('config',)), - ('state', 'replaced', ('config',)), - ('state', 'overridden', ('config',))] - - module = AnsibleModule(argument_spec=Lag_interfacesArgs.argument_spec, - required_if=required_if, - supports_check_mode=True) - - result = Lag_interfaces(module).execute_module() - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_linkagg.py b/lib/ansible/modules/network/ios/ios_linkagg.py deleted file mode 100644 index 61620e6b574..00000000000 --- a/lib/ansible/modules/network/ios/ios_linkagg.py +++ /dev/null @@ -1,318 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - -DOCUMENTATION = """ ---- -module: ios_linkagg -version_added: "2.5" -author: "Trishna Guha (@trishnaguha)" -short_description: Manage link aggregation groups on Cisco IOS network devices -description: - - This module provides declarative management of link aggregation groups - on Cisco IOS network devices. -notes: - - Tested against IOS 15.2 -options: - group: - description: - - Channel-group number for the port-channel - Link aggregation group. Range 1-255. - mode: - description: - - Mode of the link aggregation group. - choices: ['active', 'on', 'passive', 'auto', 'desirable'] - members: - description: - - List of members of the link aggregation group. - aggregate: - description: List of link aggregation definitions. - state: - description: - - State of the link aggregation group. - default: present - choices: ['present', 'absent'] - purge: - description: - - Purge links not defined in the I(aggregate) parameter. - default: no - type: bool -extends_documentation_fragment: ios -""" - -EXAMPLES = """ -- name: create link aggregation group - ios_linkagg: - group: 10 - state: present - -- name: delete link aggregation group - ios_linkagg: - group: 10 - state: absent - -- name: set link aggregation group to members - ios_linkagg: - group: 200 - mode: active - members: - - GigabitEthernet0/0 - - GigabitEthernet0/1 - -- name: remove link aggregation group from GigabitEthernet0/0 - ios_linkagg: - group: 200 - mode: active - members: - - GigabitEthernet0/1 - -- name: Create aggregate of linkagg definitions - ios_linkagg: - aggregate: - - { group: 3, mode: on, members: [GigabitEthernet0/1] } - - { group: 100, mode: passive, members: [GigabitEthernet0/2] } -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always, except for the platforms that use Netconf transport to manage the device. - type: list - sample: - - interface port-channel 30 - - interface GigabitEthernet0/3 - - channel-group 30 mode on - - no interface port-channel 30 -""" - -import re -from copy import deepcopy - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.config import CustomNetworkConfig -from ansible.module_utils.network.common.utils import remove_default_spec -from ansible.module_utils.network.ios.ios import get_config, load_config -from ansible.module_utils.network.ios.ios import ios_argument_spec - - -def search_obj_in_list(group, lst): - for o in lst: - if o['group'] == group: - return o - - -def map_obj_to_commands(updates, module): - commands = list() - want, have = updates - purge = module.params['purge'] - - for w in want: - group = w['group'] - mode = w['mode'] - members = w.get('members') or [] - state = w['state'] - del w['state'] - - obj_in_have = search_obj_in_list(group, have) - - if state == 'absent': - if obj_in_have: - commands.append('no interface port-channel {0}'.format(group)) - - elif state == 'present': - cmd = ['interface port-channel {0}'.format(group), - 'end'] - if not obj_in_have: - if not group: - module.fail_json(msg='group is a required option') - commands.extend(cmd) - - if members: - for m in members: - commands.append('interface {0}'.format(m)) - commands.append('channel-group {0} mode {1}'.format(group, mode)) - - else: - if members: - if 'members' not in obj_in_have.keys(): - for m in members: - commands.extend(cmd) - commands.append('interface {0}'.format(m)) - commands.append('channel-group {0} mode {1}'.format(group, mode)) - - elif set(members) != set(obj_in_have['members']): - missing_members = list(set(members) - set(obj_in_have['members'])) - for m in missing_members: - commands.extend(cmd) - commands.append('interface {0}'.format(m)) - commands.append('channel-group {0} mode {1}'.format(group, mode)) - - superfluous_members = list(set(obj_in_have['members']) - set(members)) - for m in superfluous_members: - commands.extend(cmd) - commands.append('interface {0}'.format(m)) - commands.append('no channel-group {0} mode {1}'.format(group, mode)) - - if purge: - for h in have: - obj_in_want = search_obj_in_list(h['group'], want) - if not obj_in_want: - commands.append('no interface port-channel {0}'.format(h['group'])) - - return commands - - -def map_params_to_obj(module): - obj = [] - - aggregate = module.params.get('aggregate') - if aggregate: - for item in aggregate: - for key in item: - if item.get(key) is None: - item[key] = module.params[key] - - d = item.copy() - d['group'] = str(d['group']) - - obj.append(d) - else: - obj.append({ - 'group': str(module.params['group']), - 'mode': module.params['mode'], - 'members': module.params['members'], - 'state': module.params['state'] - }) - - return obj - - -def parse_mode(module, config, group, member): - mode = None - netcfg = CustomNetworkConfig(indent=1, contents=config) - parents = ['interface {0}'.format(member)] - body = netcfg.get_section(parents) - - match_int = re.findall(r'interface {0}\n'.format(member), body, re.M) - if match_int: - match = re.search(r'channel-group {0} mode (\S+)'.format(group), body, re.M) - if match: - mode = match.group(1) - - return mode - - -def parse_members(module, config, group): - members = [] - - for line in config.strip().split('!'): - l = line.strip() - if l.startswith('interface'): - match_group = re.findall(r'channel-group {0} mode'.format(group), l, re.M) - if match_group: - match = re.search(r'interface (\S+)', l, re.M) - if match: - members.append(match.group(1)) - - return members - - -def get_channel(module, config, group): - match = re.findall(r'^interface (\S+)', config, re.M) - - if not match: - return {} - - channel = {} - for item in set(match): - member = item - channel['mode'] = parse_mode(module, config, group, member) - channel['members'] = parse_members(module, config, group) - - return channel - - -def map_config_to_obj(module): - objs = list() - config = get_config(module) - - for line in config.split('\n'): - l = line.strip() - match = re.search(r'interface Port-channel(\S+)', l, re.M) - if match: - obj = {} - group = match.group(1) - obj['group'] = group - obj.update(get_channel(module, config, group)) - objs.append(obj) - - return objs - - -def main(): - """ main entry point for module execution - """ - element_spec = dict( - group=dict(type='int'), - mode=dict(choices=['active', 'on', 'passive', 'auto', 'desirable']), - members=dict(type='list'), - state=dict(default='present', - choices=['present', 'absent']) - ) - - aggregate_spec = deepcopy(element_spec) - aggregate_spec['group'] = dict(required=True) - - required_one_of = [['group', 'aggregate']] - required_together = [['members', 'mode']] - mutually_exclusive = [['group', 'aggregate']] - - # remove default in aggregate spec, to handle common arguments - remove_default_spec(aggregate_spec) - - argument_spec = dict( - aggregate=dict(type='list', elements='dict', options=aggregate_spec, - required_together=required_together), - purge=dict(default=False, type='bool') - ) - - argument_spec.update(element_spec) - argument_spec.update(ios_argument_spec) - - module = AnsibleModule(argument_spec=argument_spec, - required_one_of=required_one_of, - required_together=required_together, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True) - - warnings = list() - result = {'changed': False} - if warnings: - result['warnings'] = warnings - - want = map_params_to_obj(module) - have = map_config_to_obj(module) - - commands = map_obj_to_commands((want, have), module) - result['commands'] = commands - - if commands: - if not module.check_mode: - load_config(module, commands) - result['changed'] = True - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_lldp.py b/lib/ansible/modules/network/ios/ios_lldp.py deleted file mode 100644 index 7ba7bf385ae..00000000000 --- a/lib/ansible/modules/network/ios/ios_lldp.py +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_lldp -version_added: "2.5" -author: "Ganesh Nalawade (@ganeshrn)" -short_description: Manage LLDP configuration on Cisco IOS network devices. -description: - - This module provides declarative management of LLDP service - on Cisco IOS network devices. -notes: - - Tested against IOS 15.2 -options: - state: - description: - - State of the LLDP configuration. If value is I(present) lldp will be enabled - else if it is I(absent) it will be disabled. - default: present - choices: ['present', 'absent'] -extends_documentation_fragment: ios -""" - -EXAMPLES = """ -- name: Enable LLDP service - ios_lldp: - state: present - -- name: Disable LLDP service - ios_lldp: - state: absent -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always, except for the platforms that use Netconf transport to manage the device. - type: list - sample: - - lldp run -""" -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.ios import load_config, run_commands -from ansible.module_utils.network.ios.ios import ios_argument_spec - - -def has_lldp(module): - output = run_commands(module, ['show lldp']) - - is_lldp_enable = False - if len(output) > 0 and "LLDP is not enabled" not in output[0]: - is_lldp_enable = True - - return is_lldp_enable - - -def main(): - """ main entry point for module execution - """ - argument_spec = dict( - state=dict(default='present', - choices=['present', 'absent', - 'enabled', 'disabled']) - ) - - argument_spec.update(ios_argument_spec) - - module = AnsibleModule(argument_spec=argument_spec, - supports_check_mode=True) - - warnings = list() - - result = {'changed': False} - - if warnings: - result['warnings'] = warnings - - HAS_LLDP = has_lldp(module) - - commands = [] - - if module.params['state'] == 'absent' and HAS_LLDP: - commands.append('no lldp run') - elif module.params['state'] == 'present' and not HAS_LLDP: - commands.append('lldp run') - - result['commands'] = commands - - if commands: - if not module.check_mode: - load_config(module, commands) - - result['changed'] = True - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_lldp_global.py b/lib/ansible/modules/network/ios/ios_lldp_global.py deleted file mode 100644 index 49c146f8d29..00000000000 --- a/lib/ansible/modules/network/ios/ios_lldp_global.py +++ /dev/null @@ -1,256 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The module file for ios_lldp_global -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_lldp_global -version_added: 2.9 -short_description: Configure and manage Link Layer Discovery Protocol(LLDP) attributes on IOS platforms. -description: This module configures and manages the Link Layer Discovery Protocol(LLDP) attributes on IOS platforms. -author: Sumit Jaiswal (@justjais) -notes: - - Tested against Cisco IOSv Version 15.2 on VIRL - - This module works with connection C(network_cli), - See L(IOS Platform Options,../network/user_guide/platform_ios.html). -options: - config: - description: A dictionary of LLDP options - type: dict - suboptions: - holdtime: - description: - - LLDP holdtime (in sec) to be sent in packets. - - Refer to vendor documentation for valid values. - type: int - reinit: - description: - - Specify the delay (in secs) for LLDP to initialize. - - Refer to vendor documentation for valid values. - - NOTE, if LLDP reinit is configured with a starting - value, idempotency won't be maintained as the Cisco - device doesn't record the starting reinit configured - value. As such, Ansible cannot verify if the respective - starting reinit value is already configured or not from - the device side. If you try to apply starting reinit - value in every play run, Ansible will show changed as True. - For any other reinit value, idempotency will be maintained - since any other reinit value is recorded in the Cisco device. - type: int - enabled: - description: - - Enable LLDP - type: bool - timer: - description: - - Specify the rate at which LLDP packets are sent (in sec). - - Refer to vendor documentation for valid values. - type: int - tlv_select: - description: - - Selection of LLDP TLVs i.e. type-length-value to send - - NOTE, if tlv-select is configured idempotency won't be maintained - as Cisco device doesn't record configured tlv-select options. As - such, Ansible cannot verify if the respective tlv-select options is - already configured or not from the device side. If you try to apply - tlv-select option in every play run, Ansible will show changed as True. - type: dict - suboptions: - four_wire_power_management: - description: - - Cisco 4-wire Power via MDI TLV - type: bool - mac_phy_cfg: - description: - - IEEE 802.3 MAC/Phy Configuration/status TLV - type: bool - management_address: - description: - - Management Address TLV - type: bool - port_description: - description: - - Port Description TLV - type: bool - port_vlan: - description: - - Port VLAN ID TLV - type: bool - power_management: - description: - - IEEE 802.3 DTE Power via MDI TLV - type: bool - system_capabilities: - description: - - System Capabilities TLV - type: bool - system_description: - description: - - System Description TLV - type: bool - system_name: - description: - - System Name TLV - type: bool - state: - description: - - The state of the configuration after module completion - type: str - choices: - - merged - - replaced - - deleted - default: merged -""" - -EXAMPLES = """ ---- - -# Using merged - -# Before state: -# ------------- -# vios#sh running-config | section ^lldp -# vios1# - - -- name: Merge provided configuration with device configuration - ios_lldp_global: - config: - holdtime: 10 - enabled: True - reinit: 3 - timer: 10 - state: merged - -# After state: -# ------------ -# vios#sh running-config | section ^lldp -# lldp timer 10 -# lldp holdtime 10 -# lldp reinit 3 -# lldp run - - -# Using replaced - -# Before state: -# ------------- -# vios#sh running-config | section ^lldp -# lldp timer 10 -# lldp holdtime 10 -# lldp reinit 3 -# lldp run - - -- name: Replaces LLDP device configuration with provided configuration - ios_lldp_global: - config: - holdtime: 20 - reinit: 5 - state: replaced - -# After state: -# ------------- -# vios#sh running-config | section ^lldp -# lldp holdtime 20 -# lldp reinit 5 - - -# Using Deleted without any config passed -#"(NOTE: This will delete all of configured LLDP module attributes)" - -# Before state: -# ------------- -# vios#sh running-config | section ^lldp -# lldp timer 10 -# lldp holdtime 10 -# lldp reinit 3 -# lldp run - - -- name: "Delete LLDP attributes (Note: This won't delete the interface itself)" - ios_lldp_global: - state: deleted - -# After state: -# ------------- -# vios#sh running-config | section ^lldp -# vios1# - -""" - -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: dict - sample: The configuration returned will always be in the same format of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: dict - sample: The configuration returned will always be in the same format of the parameters above. -commands: - description: The set of commands pushed to the remote device - returned: always - type: list - sample: ['lldp holdtime 10', 'lldp run', 'lldp timer 10'] -""" - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.lldp_global.lldp_global import Lldp_globalArgs -from ansible.module_utils.network.ios.config.lldp_global.lldp_global import Lldp_global - - -def main(): - """ - Main entry point for module execution - - :returns: the result form module invocation - """ - required_if = [('state', 'merged', ('config',)), - ('state', 'replaced', ('config',))] - - module = AnsibleModule(argument_spec=Lldp_globalArgs.argument_spec, - required_if=required_if, - supports_check_mode=True) - - result = Lldp_global(module).execute_module() - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_lldp_interfaces.py b/lib/ansible/modules/network/ios/ios_lldp_interfaces.py deleted file mode 100644 index c1bbc274e43..00000000000 --- a/lib/ansible/modules/network/ios/ios_lldp_interfaces.py +++ /dev/null @@ -1,501 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The module file for ios_lldp_interfaces -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network' -} - - -DOCUMENTATION = """ ---- -module: ios_lldp_interfaces -version_added: 2.9 -short_description: Manage link layer discovery protocol (LLDP) attributes of interfaces on Cisco IOS devices. -description: This module manages link layer discovery protocol (LLDP) attributes of interfaces on Cisco IOS devices. -author: Sumit Jaiswal (@justjais) -notes: - - Tested against Cisco IOSv Version 15.2 on VIRL - - This module works with connection C(network_cli), - See L(IOS Platform Options,../network/user_guide/platform_ios.html). -options: - config: - description: A dictionary of LLDP options - type: list - elements: dict - suboptions: - name: - description: - - Full name of the interface excluding any logical unit number, i.e. GigabitEthernet0/1. - type: str - required: True - receive: - description: - - Enable LLDP reception on interface. - type: bool - transmit: - description: - - Enable LLDP transmission on interface. - type: bool - med_tlv_select: - description: - - Selection of LLDP MED TLVs to send - - NOTE, if med-tlv-select is configured idempotency won't be maintained - as Cisco device doesn't record configured med-tlv-select options. As - such, Ansible cannot verify if the respective med-tlv-select options is - already configured or not from the device side. If you try to apply - med-tlv-select option in every play run, Ansible will show changed as - True. - type: dict - suboptions: - inventory_management: - description: - - LLDP MED Inventory Management TLV - type: bool - tlv_select: - description: - - Selection of LLDP type-length-value i.e. TLVs to send - - NOTE, if tlv-select is configured idempotency won't be maintained - as Cisco device doesn't record configured tlv-select options. As - such, Ansible cannot verify if the respective tlv-select options is - already configured or not from the device side. If you try to apply - tlv-select option in every play run, Ansible will show changed as True. - type: dict - suboptions: - power_management: - description: - - IEEE 802.3 DTE Power via MDI TLV - type: bool - state: - description: - - The state of the configuration after module completion - type: str - choices: - - merged - - replaced - - overridden - - deleted - default: merged -""" - -EXAMPLES = """ - -# Using merged -# -# Before state: -# ------------- -# -# vios#sh lldp interface -# GigabitEthernet0/0: -# Tx: enabled -# Rx: disabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/1: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/2: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: INIT -# -# GigabitEthernet0/3: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# - -- name: Merge provided configuration with device configuration - ios_lldp_interfaces: - config: - - name: GigabitEthernet0/1 - receive: True - transmit: True - - name: GigabitEthernet0/2 - receive: True - - name: GigabitEthernet0/3 - transmit: True - state: merged - -# After state: -# ------------ -# -# vios#sh lldp interface -# GigabitEthernet0/0: -# Tx: enabled -# Rx: disabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/1: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/2: -# Tx: disabled -# Rx: enabled -# Tx state: IDLE -# Rx state: INIT -# -# GigabitEthernet0/3: -# Tx: enabled -# Rx: disabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# - -# Using overridden -# -# Before state: -# ------------- -# -# vios#sh lldp interface -# GigabitEthernet0/0: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/1: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/2: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: INIT -# -# GigabitEthernet0/3: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# - -- name: Override device configuration of all lldp_interfaces with provided configuration - ios_lldp_interfaces: - config: - - name: GigabitEthernet0/2 - receive: True - transmit: True - state: overridden - -# After state: -# ------------ -# -# vios#sh lldp interface -# GigabitEthernet0/0: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/1: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/2: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: INIT -# -# GigabitEthernet0/3: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME - -# Using replaced -# -# Before state: -# ------------- -# -# vios#sh lldp interface -# GigabitEthernet0/0: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/1: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/2: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: INIT -# -# GigabitEthernet0/3: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# - -- name: Replaces device configuration of listed lldp_interfaces with provided configuration - ios_lldp_interfaces: - config: - - name: GigabitEthernet0/2 - receive: True - transmit: True - - name: GigabitEthernet0/3 - receive: True - state: replaced - -# After state: -# ------------ -# -# vios#sh lldp interface -# GigabitEthernet0/0: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/1: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/2: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: INIT -# -# GigabitEthernet0/3: -# Tx: disabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# - -# Using Deleted -# -# Before state: -# ------------- -# -# vios#sh lldp interface -# GigabitEthernet0/0: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/1: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/2: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: INIT -# -# GigabitEthernet0/3: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# - -- name: "Delete LLDP attributes of given interfaces (Note: This won't delete the interface itself)" - ios_lldp_interfaces: - config: - - name: GigabitEthernet0/1 - state: deleted - -# After state: -# ------------- -# -# vios#sh lldp interface -# GigabitEthernet0/0: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/1: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/2: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: INIT -# -# GigabitEthernet0/3: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# - -# Using Deleted without any config passed -# "(NOTE: This will delete all of configured LLDP module attributes)" -# -# Before state: -# ------------- -# -# vios#sh lldp interface -# GigabitEthernet0/0: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/1: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/2: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: INIT -# -# GigabitEthernet0/3: -# Tx: enabled -# Rx: enabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# - -- name: "Delete LLDP attributes for all configured interfaces (Note: This won't delete the interface itself)" - ios_lldp_interfaces: - state: deleted - -# After state: -# ------------- -# -# vios#sh lldp interface -# GigabitEthernet0/0: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/1: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# -# GigabitEthernet0/2: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: INIT -# -# GigabitEthernet0/3: -# Tx: disabled -# Rx: disabled -# Tx state: IDLE -# Rx state: WAIT FOR FRAME -# - -""" - -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: list - sample: > - The configuration returned will always be in the same format - of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: list - sample: > - The configuration returned will always be in the same format - of the parameters above. -commands: - description: The set of commands pushed to the remote device. - returned: always - type: list - sample: ['interface GigabitEthernet 0/1', 'lldp transmit', 'lldp receive'] -""" - - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.lldp_interfaces.lldp_interfaces import Lldp_InterfacesArgs -from ansible.module_utils.network.ios.config.lldp_interfaces.lldp_interfaces import Lldp_Interfaces - - -def main(): - """ - Main entry point for module execution - - :returns: the result form module invocation - """ - required_if = [('state', 'merged', ('config',)), - ('state', 'replaced', ('config',)), - ('state', 'overridden', ('config',))] - - module = AnsibleModule(argument_spec=Lldp_InterfacesArgs.argument_spec, - required_if=required_if, - supports_check_mode=True) - - result = Lldp_Interfaces(module).execute_module() - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_logging.py b/lib/ansible/modules/network/ios/ios_logging.py deleted file mode 100644 index b91f3ff2b90..00000000000 --- a/lib/ansible/modules/network/ios/ios_logging.py +++ /dev/null @@ -1,429 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, Ansible by Red Hat, inc -# -# This file is part of Ansible by Red Hat -# -# 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 . -# - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - -DOCUMENTATION = """ ---- -module: ios_logging -version_added: "2.4" -author: "Trishna Guha (@trishnaguha)" -short_description: Manage logging on network devices -description: - - This module provides declarative management of logging - on Cisco Ios devices. -notes: - - Tested against IOS 15.6 -options: - dest: - description: - - Destination of the logs. - choices: ['on', 'host', 'console', 'monitor', 'buffered', 'trap'] - name: - description: - - The hostname or IP address of the destination. - - Required when I(dest=host). - size: - description: - - Size of buffer. The acceptable value is in range from 4096 to - 4294967295 bytes. - default: 4096 - facility: - description: - - Set logging facility. - level: - description: - - Set logging severity levels. - default: debugging - choices: ['emergencies', 'alerts', 'critical', 'errors', 'warnings', 'notifications', 'informational', 'debugging'] - aggregate: - description: List of logging definitions. - state: - description: - - State of the logging configuration. - default: present - choices: ['present', 'absent'] -extends_documentation_fragment: ios -""" - -EXAMPLES = """ -- name: configure host logging - ios_logging: - dest: host - name: 172.16.0.1 - state: present - -- name: remove host logging configuration - ios_logging: - dest: host - name: 172.16.0.1 - state: absent - -- name: configure console logging level and facility - ios_logging: - dest: console - facility: local7 - level: debugging - state: present - -- name: enable logging to all - ios_logging: - dest : on - -- name: configure buffer size - ios_logging: - dest: buffered - size: 5000 - -- name: Configure logging using aggregate - ios_logging: - aggregate: - - { dest: console, level: notifications } - - { dest: buffered, size: 9000 } - -- name: remove logging using aggregate - ios_logging: - aggregate: - - { dest: console, level: notifications } - - { dest: buffered, size: 9000 } - state: absent -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always - type: list - sample: - - logging facility local7 - - logging host 172.16.0.1 -""" - -import re - -from copy import deepcopy -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.utils import remove_default_spec, validate_ip_address -from ansible.module_utils.network.ios.ios import get_config, load_config -from ansible.module_utils.network.ios.ios import get_capabilities -from ansible.module_utils.network.ios.ios import ios_argument_spec - - -def validate_size(value, module): - if value: - if not int(4096) <= int(value) <= int(4294967295): - module.fail_json(msg='size must be between 4096 and 4294967295') - else: - return value - - -def map_obj_to_commands(updates, module, os_version): - dest_group = ('console', 'monitor', 'buffered', 'on', 'trap') - commands = list() - want, have = updates - for w in want: - dest = w['dest'] - name = w['name'] - size = w['size'] - facility = w['facility'] - level = w['level'] - state = w['state'] - del w['state'] - - if facility: - w['dest'] = 'facility' - - if state == 'absent' and w in have: - if dest: - if dest == 'host': - if '12.' in os_version: - commands.append('no logging {0}'.format(name)) - else: - commands.append('no logging host {0}'.format(name)) - - elif dest in dest_group: - commands.append('no logging {0}'.format(dest)) - - else: - module.fail_json(msg='dest must be among console, monitor, buffered, host, on, trap') - - if facility: - commands.append('no logging facility {0}'.format(facility)) - - if state == 'present' and w not in have: - if facility: - present = False - - for entry in have: - if entry['dest'] == 'facility' and entry['facility'] == facility: - present = True - - if not present: - commands.append('logging facility {0}'.format(facility)) - - if dest == 'host': - if '12.' in os_version: - commands.append('logging {0}'.format(name)) - else: - commands.append('logging host {0}'.format(name)) - - elif dest == 'on': - commands.append('logging on') - - elif dest == 'buffered' and size: - present = False - - for entry in have: - if entry['dest'] == 'buffered' and entry['size'] == size and entry['level'] == level: - present = True - - if not present: - if level and level != 'debugging': - commands.append('logging buffered {0} {1}'.format(size, level)) - else: - commands.append('logging buffered {0}'.format(size)) - - else: - if dest: - dest_cmd = 'logging {0}'.format(dest) - if level: - dest_cmd += ' {0}'.format(level) - commands.append(dest_cmd) - return commands - - -def parse_facility(line, dest): - facility = None - if dest == 'facility': - match = re.search(r'logging facility (\S+)', line, re.M) - if match: - facility = match.group(1) - - return facility - - -def parse_size(line, dest): - size = None - - if dest == 'buffered': - match = re.search(r'logging buffered(?: (\d+))?(?: [a-z]+)?', line, re.M) - if match: - if match.group(1) is not None: - size = match.group(1) - else: - size = "4096" - - return size - - -def parse_name(line, dest): - if dest == 'host': - match = re.search(r'logging host (\S+)', line, re.M) - if match: - name = match.group(1) - else: - name = None - - return name - - -def parse_level(line, dest): - level_group = ('emergencies', 'alerts', 'critical', 'errors', 'warnings', - 'notifications', 'informational', 'debugging') - - if dest == 'host': - level = 'debugging' - - else: - if dest == 'buffered': - match = re.search(r'logging buffered(?: \d+)?(?: ([a-z]+))?', line, re.M) - else: - match = re.search(r'logging {0} (\S+)'.format(dest), line, re.M) - - if match and match.group(1) in level_group: - level = match.group(1) - else: - level = 'debugging' - - return level - - -def map_config_to_obj(module): - obj = [] - dest_group = ('console', 'host', 'monitor', 'buffered', 'on', 'facility', 'trap') - - data = get_config(module, flags=['| include logging']) - - for line in data.split('\n'): - match = re.search(r'^logging (\S+)', line, re.M) - if match: - if match.group(1) in dest_group: - dest = match.group(1) - - obj.append({ - 'dest': dest, - 'name': parse_name(line, dest), - 'size': parse_size(line, dest), - 'facility': parse_facility(line, dest), - 'level': parse_level(line, dest) - }) - elif validate_ip_address(match.group(1)): - dest = 'host' - obj.append({ - 'dest': dest, - 'name': match.group(1), - 'size': parse_size(line, dest), - 'facility': parse_facility(line, dest), - 'level': parse_level(line, dest) - }) - else: - ip_match = re.search(r'\d+\.\d+\.\d+\.\d+', match.group(1), re.M) - if ip_match: - dest = 'host' - obj.append({ - 'dest': dest, - 'name': match.group(1), - 'size': parse_size(line, dest), - 'facility': parse_facility(line, dest), - 'level': parse_level(line, dest) - }) - return obj - - -def map_params_to_obj(module, required_if=None): - obj = [] - aggregate = module.params.get('aggregate') - - if aggregate: - for item in aggregate: - for key in item: - if item.get(key) is None: - item[key] = module.params[key] - - module._check_required_if(required_if, item) - - d = item.copy() - if d['dest'] != 'host': - d['name'] = None - - if d['dest'] == 'buffered': - if 'size' in d: - d['size'] = str(validate_size(d['size'], module)) - elif 'size' not in d: - d['size'] = str(4096) - else: - pass - - if d['dest'] != 'buffered': - d['size'] = None - - obj.append(d) - - else: - if module.params['dest'] != 'host': - module.params['name'] = None - - if module.params['dest'] == 'buffered': - if not module.params['size']: - module.params['size'] = str(4096) - else: - module.params['size'] = None - - if module.params['size'] is None: - obj.append({ - 'dest': module.params['dest'], - 'name': module.params['name'], - 'size': module.params['size'], - 'facility': module.params['facility'], - 'level': module.params['level'], - 'state': module.params['state'] - }) - - else: - obj.append({ - 'dest': module.params['dest'], - 'name': module.params['name'], - 'size': str(validate_size(module.params['size'], module)), - 'facility': module.params['facility'], - 'level': module.params['level'], - 'state': module.params['state'] - }) - return obj - - -def main(): - """ main entry point for module execution - """ - element_spec = dict( - dest=dict(type='str', choices=['on', 'host', 'console', 'monitor', 'buffered', 'trap']), - name=dict(type='str'), - size=dict(type='int'), - facility=dict(type='str'), - level=dict(type='str', default='debugging', choices=['emergencies', 'alerts', 'critical', 'errors', 'warnings', - 'notifications', 'informational', 'debugging']), - state=dict(default='present', choices=['present', 'absent']), - ) - - aggregate_spec = deepcopy(element_spec) - - # remove default in aggregate spec, to handle common arguments - remove_default_spec(aggregate_spec) - - argument_spec = dict( - aggregate=dict(type='list', elements='dict', options=aggregate_spec), - ) - - argument_spec.update(element_spec) - argument_spec.update(ios_argument_spec) - - required_if = [('dest', 'host', ['name'])] - - module = AnsibleModule(argument_spec=argument_spec, - required_if=required_if, - supports_check_mode=True) - - device_info = get_capabilities(module) - os_version = device_info['device_info']['network_os_version'] - - warnings = list() - - result = {'changed': False} - if warnings: - result['warnings'] = warnings - - want = map_params_to_obj(module, required_if=required_if) - have = map_config_to_obj(module) - - commands = map_obj_to_commands((want, have), module, os_version) - result['commands'] = commands - - if commands: - if not module.check_mode: - load_config(module, commands) - result['changed'] = True - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_ntp.py b/lib/ansible/modules/network/ios/ios_ntp.py deleted file mode 100644 index 682140c3755..00000000000 --- a/lib/ansible/modules/network/ios/ios_ntp.py +++ /dev/null @@ -1,308 +0,0 @@ -#!/usr/bin/python -# Copyright: Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = ''' ---- -module: ios_ntp -extends_documentation_fragment: ios -version_added: "2.8" -short_description: Manages core NTP configuration. -description: - - Manages core NTP configuration. -author: - - Federico Olivieri (@Federico87) -options: - server: - description: - - Network address of NTP server. - source_int: - description: - - Source interface for NTP packets. - acl: - description: - - ACL for peer/server access restricition. - logging: - description: - - Enable NTP logs. Data type boolean. - type: bool - default: False - auth: - description: - - Enable NTP authentication. Data type boolean. - type: bool - default: False - auth_key: - description: - - md5 NTP authentication key of tye 7. - key_id: - description: - - auth_key id. Data type string - state: - description: - - Manage the state of the resource. - default: present - choices: ['present', 'absent'] -''' - -EXAMPLES = ''' -# Set new NTP server and source interface -- ios_ntp: - server: 10.0.255.10 - source_int: Loopback0 - logging: false - state: present - -# Remove NTP ACL and logging -- ios_ntp: - acl: NTP_ACL - logging: true - state: absent - -# Set NTP authentication -- ios_ntp: - key_id: 10 - auth_key: 15435A030726242723273C21181319000A - auth: true - state: present - -# Set new NTP configuration -- ios_ntp: - server: 10.0.255.10 - source_int: Loopback0 - acl: NTP_ACL - logging: true - key_id: 10 - auth_key: 15435A030726242723273C21181319000A - auth: true - state: present -''' - -RETURN = ''' -commands: - description: command sent to the device - returned: always - type: list - sample: ["no ntp server 10.0.255.10", "no ntp source Loopback0"] -''' -import re - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.ios import get_config, load_config -from ansible.module_utils.network.ios.ios import ios_argument_spec - - -def parse_server(line, dest): - if dest == 'server': - match = re.search(r'(ntp server )(\d+\.\d+\.\d+\.\d+)', line, re.M) - if match: - server = match.group(2) - return server - - -def parse_source_int(line, dest): - if dest == 'source': - match = re.search(r'(ntp source )(\S+)', line, re.M) - if match: - source = match.group(2) - return source - - -def parse_acl(line, dest): - if dest == 'access-group': - match = re.search(r'ntp access-group (?:peer|serve)(?:\s+)(\S+)', line, re.M) - if match: - acl = match.group(1) - return acl - - -def parse_logging(line, dest): - if dest == 'logging': - logging = dest - return logging - - -def parse_auth_key(line, dest): - if dest == 'authentication-key': - match = re.search(r'(ntp authentication-key \d+ md5 )(\w+)', line, re.M) - if match: - auth_key = match.group(2) - return auth_key - - -def parse_key_id(line, dest): - if dest == 'trusted-key': - match = re.search(r'(ntp trusted-key )(\d+)', line, re.M) - if match: - auth_key = match.group(2) - return auth_key - - -def parse_auth(dest): - if dest == 'authenticate': - return dest - - -def map_config_to_obj(module): - - obj_dict = {} - obj = [] - server_list = [] - - config = get_config(module, flags=['| include ntp']) - - for line in config.splitlines(): - match = re.search(r'ntp (\S+)', line, re.M) - if match: - dest = match.group(1) - - server = parse_server(line, dest) - source_int = parse_source_int(line, dest) - acl = parse_acl(line, dest) - logging = parse_logging(line, dest) - auth = parse_auth(dest) - auth_key = parse_auth_key(line, dest) - key_id = parse_key_id(line, dest) - - if server: - server_list.append(server) - if source_int: - obj_dict['source_int'] = source_int - if acl: - obj_dict['acl'] = acl - if logging: - obj_dict['logging'] = True - if auth: - obj_dict['auth'] = True - if auth_key: - obj_dict['auth_key'] = auth_key - if key_id: - obj_dict['key_id'] = key_id - - obj_dict['server'] = server_list - obj.append(obj_dict) - - return obj - - -def map_params_to_obj(module): - obj = [] - obj.append({ - 'state': module.params['state'], - 'server': module.params['server'], - 'source_int': module.params['source_int'], - 'logging': module.params['logging'], - 'acl': module.params['acl'], - 'auth': module.params['auth'], - 'auth_key': module.params['auth_key'], - 'key_id': module.params['key_id'] - }) - - return obj - - -def map_obj_to_commands(want, have, module): - - commands = list() - - server_have = have[0].get('server', None) - source_int_have = have[0].get('source_int', None) - acl_have = have[0].get('acl', None) - logging_have = have[0].get('logging', None) - auth_have = have[0].get('auth', None) - auth_key_have = have[0].get('auth_key', None) - key_id_have = have[0].get('key_id', None) - - for w in want: - server = w['server'] - source_int = w['source_int'] - acl = w['acl'] - logging = w['logging'] - state = w['state'] - auth = w['auth'] - auth_key = w['auth_key'] - key_id = w['key_id'] - - if state == 'absent': - if server_have and server in server_have: - commands.append('no ntp server {0}'.format(server)) - if source_int and source_int_have: - commands.append('no ntp source {0}'.format(source_int)) - if acl and acl_have: - commands.append('no ntp access-group peer {0}'.format(acl)) - if logging is True and logging_have: - commands.append('no ntp logging') - if auth is True and auth_have: - commands.append('no ntp authenticate') - if key_id and key_id_have: - commands.append('no ntp trusted-key {0}'.format(key_id)) - if auth_key and auth_key_have: - if key_id and key_id_have: - commands.append('no ntp authentication-key {0} md5 {1} 7'.format(key_id, auth_key)) - - elif state == 'present': - if server is not None and server not in server_have: - commands.append('ntp server {0}'.format(server)) - if source_int is not None and source_int != source_int_have: - commands.append('ntp source {0}'.format(source_int)) - if acl is not None and acl != acl_have: - commands.append('ntp access-group peer {0}'.format(acl)) - if logging is not None and logging != logging_have and logging is not False: - commands.append('ntp logging') - if auth is not None and auth != auth_have and auth is not False: - commands.append('ntp authenticate') - if key_id is not None and key_id != key_id_have: - commands.append('ntp trusted-key {0}'.format(key_id)) - if auth_key is not None and auth_key != auth_key_have: - if key_id is not None: - commands.append('ntp authentication-key {0} md5 {1} 7'.format(key_id, auth_key)) - - return commands - - -def main(): - - argument_spec = dict( - server=dict(), - source_int=dict(), - acl=dict(), - logging=dict(type='bool', default=False), - auth=dict(type='bool', default=False), - auth_key=dict(), - key_id=dict(), - state=dict(choices=['absent', 'present'], default='present') - ) - - argument_spec.update(ios_argument_spec) - - module = AnsibleModule( - argument_spec=argument_spec, - supports_check_mode=True - ) - - result = {'changed': False} - - warnings = list() - if warnings: - result['warnings'] = warnings - - want = map_params_to_obj(module) - have = map_config_to_obj(module) - - commands = map_obj_to_commands(want, have, module) - result['commands'] = commands - - if commands: - if not module.check_mode: - load_config(module, commands) - result['changed'] = True - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_ping.py b/lib/ansible/modules/network/ios/ios_ping.py deleted file mode 100644 index 6b7fca9261c..00000000000 --- a/lib/ansible/modules/network/ios/ios_ping.py +++ /dev/null @@ -1,210 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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 - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: ios_ping -short_description: Tests reachability using ping from Cisco IOS network devices -description: -- Tests reachability using ping from switch to a remote destination. -- For a general purpose network module, see the M(net_ping) module. -- For Windows targets, use the M(win_ping) module instead. -- For targets running Python, use the M(ping) module instead. -author: -- Jacob McGill (@jmcgill298) -version_added: '2.4' -extends_documentation_fragment: ios -options: - count: - description: - - Number of packets to send. - default: 5 - dest: - description: - - The IP Address or hostname (resolvable by switch) of the remote node. - required: true - source: - description: - - The source IP Address. - state: - description: - - Determines if the expected result is success or fail. - choices: [ absent, present ] - default: present - vrf: - description: - - The VRF to use for forwarding. - default: default -notes: - - For a general purpose network module, see the M(net_ping) module. - - For Windows targets, use the M(win_ping) module instead. - - For targets running Python, use the M(ping) module instead. -''' - -EXAMPLES = r''' -- name: Test reachability to 10.10.10.10 using default vrf - ios_ping: - dest: 10.10.10.10 - -- name: Test reachability to 10.20.20.20 using prod vrf - ios_ping: - dest: 10.20.20.20 - vrf: prod - -- name: Test unreachability to 10.30.30.30 using default vrf - ios_ping: - dest: 10.30.30.30 - state: absent - -- name: Test reachability to 10.40.40.40 using prod vrf and setting count and source - ios_ping: - dest: 10.40.40.40 - source: loopback0 - vrf: prod - count: 20 -''' - -RETURN = ''' -commands: - description: Show the command sent. - returned: always - type: list - sample: ["ping vrf prod 10.40.40.40 count 20 source loopback0"] -packet_loss: - description: Percentage of packets lost. - returned: always - type: str - sample: "0%" -packets_rx: - description: Packets successfully received. - returned: always - type: int - sample: 20 -packets_tx: - description: Packets successfully transmitted. - returned: always - type: int - sample: 20 -rtt: - description: Show RTT stats. - returned: always - type: dict - sample: {"avg": 2, "max": 8, "min": 1} -''' - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.ios import run_commands -from ansible.module_utils.network.ios.ios import ios_argument_spec -import re - - -def main(): - """ main entry point for module execution - """ - argument_spec = dict( - count=dict(type="int"), - dest=dict(type="str", required=True), - source=dict(type="str"), - state=dict(type="str", choices=["absent", "present"], default="present"), - vrf=dict(type="str") - ) - - argument_spec.update(ios_argument_spec) - - module = AnsibleModule(argument_spec=argument_spec) - - count = module.params["count"] - dest = module.params["dest"] - source = module.params["source"] - vrf = module.params["vrf"] - - warnings = list() - - results = {} - if warnings: - results["warnings"] = warnings - - results["commands"] = [build_ping(dest, count, source, vrf)] - - ping_results = run_commands(module, commands=results["commands"]) - ping_results_list = ping_results[0].split("\n") - - stats = "" - for line in ping_results_list: - if line.startswith('Success'): - stats = line - - success, rx, tx, rtt = parse_ping(stats) - loss = abs(100 - int(success)) - results["packet_loss"] = str(loss) + "%" - results["packets_rx"] = int(rx) - results["packets_tx"] = int(tx) - - # Convert rtt values to int - for k, v in rtt.items(): - if rtt[k] is not None: - rtt[k] = int(v) - - results["rtt"] = rtt - - validate_results(module, loss, results) - - module.exit_json(**results) - - -def build_ping(dest, count=None, source=None, vrf=None): - """ - Function to build the command to send to the terminal for the switch - to execute. All args come from the module's unique params. - """ - if vrf is not None: - cmd = "ping vrf {0} {1}".format(vrf, dest) - else: - cmd = "ping {0}".format(dest) - - if count is not None: - cmd += " repeat {0}".format(str(count)) - - if source is not None: - cmd += " source {0}".format(source) - - return cmd - - -def parse_ping(ping_stats): - """ - Function used to parse the statistical information from the ping response. - Example: "Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/8 ms" - Returns the percent of packet loss, received packets, transmitted packets, and RTT dict. - """ - rate_re = re.compile(r"^\w+\s+\w+\s+\w+\s+(?P\d+)\s+\w+\s+\((?P\d+)/(?P\d+)\)") - rtt_re = re.compile(r".*,\s+\S+\s+\S+\s+=\s+(?P\d+)/(?P\d+)/(?P\d+)\s+\w+\s*$|.*\s*$") - - rate = rate_re.match(ping_stats) - rtt = rtt_re.match(ping_stats) - - return rate.group("pct"), rate.group("rx"), rate.group("tx"), rtt.groupdict() - - -def validate_results(module, loss, results): - """ - This function is used to validate whether the ping results were unexpected per "state" param. - """ - state = module.params["state"] - if state == "present" and loss == 100: - module.fail_json(msg="Ping failed unexpectedly", **results) - elif state == "absent" and loss < 100: - module.fail_json(msg="Ping succeeded unexpectedly", **results) - - -if __name__ == "__main__": - main() diff --git a/lib/ansible/modules/network/ios/ios_static_route.py b/lib/ansible/modules/network/ios/ios_static_route.py deleted file mode 100644 index 541a76a0c15..00000000000 --- a/lib/ansible/modules/network/ios/ios_static_route.py +++ /dev/null @@ -1,313 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, Ansible by Red Hat, inc -# -# This file is part of Ansible by Red Hat -# -# 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 . -# - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_static_route -version_added: "2.4" -author: "Ricardo Carrillo Cruz (@rcarrillocruz)" -short_description: Manage static IP routes on Cisco IOS network devices -description: - - This module provides declarative management of static - IP routes on Cisco IOS network devices. -notes: - - Tested against IOS 15.6 -options: - prefix: - description: - - Network prefix of the static route. - mask: - description: - - Network prefix mask of the static route. - next_hop: - description: - - Next hop IP of the static route. - vrf: - description: - - VRF of the static route. - version_added: "2.8" - interface: - description: - - Interface of the static route. - version_added: "2.8" - name: - description: - - Name of the static route - aliases: ['description'] - version_added: "2.8" - admin_distance: - description: - - Admin distance of the static route. - tag: - description: - - Set tag of the static route. - version_added: "2.8" - track: - description: - - Tracked item to depend on for the static route. - version_added: "2.8" - aggregate: - description: List of static route definitions. - state: - description: - - State of the static route configuration. - default: present - choices: ['present', 'absent'] -extends_documentation_fragment: ios -""" - -EXAMPLES = """ -- name: configure static route - ios_static_route: - prefix: 192.168.2.0 - mask: 255.255.255.0 - next_hop: 10.0.0.1 - -- name: configure black hole in vrf blue depending on tracked item 10 - ios_static_route: - prefix: 192.168.2.0 - mask: 255.255.255.0 - vrf: blue - interface: null0 - track: 10 - -- name: configure ultimate route with name and tag - ios_static_route: - prefix: 192.168.2.0 - mask: 255.255.255.0 - interface: GigabitEthernet1 - name: hello world - tag: 100 - -- name: remove configuration - ios_static_route: - prefix: 192.168.2.0 - mask: 255.255.255.0 - next_hop: 10.0.0.1 - state: absent - -- name: Add static route aggregates - ios_static_route: - aggregate: - - { prefix: 172.16.32.0, mask: 255.255.255.0, next_hop: 10.0.0.8 } - - { prefix: 172.16.33.0, mask: 255.255.255.0, next_hop: 10.0.0.8 } - -- name: Remove static route aggregates - ios_static_route: - aggregate: - - { prefix: 172.16.32.0, mask: 255.255.255.0, next_hop: 10.0.0.8 } - - { prefix: 172.16.33.0, mask: 255.255.255.0, next_hop: 10.0.0.8 } - state: absent -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always - type: list - sample: - - ip route 192.168.2.0 255.255.255.0 10.0.0.1 -""" -from copy import deepcopy -from re import findall - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.utils import remove_default_spec, validate_ip_address -from ansible.module_utils.network.ios.ios import get_config, load_config -from ansible.module_utils.network.ios.ios import ios_argument_spec - - -def map_obj_to_commands(want, have): - commands = list() - - for w in want: - state = w['state'] - del w['state'] - # Try to match an existing config with the desired config - for h in have: - # To delete admin_distance param from have if not it want before comparing both fields - if not w.get('admin_distance') and h.get('admin_distance'): - del h['admin_distance'] - diff = list(set(w.items()) ^ set(h.items())) - if not diff: - break - # if route is present with name or name already starts with wanted name it will not change - elif len(diff) == 2 and diff[0][0] == diff[1][0] == 'name' and (not w['name'] or h['name'].startswith(w['name'])): - break - # If no matches found, clear `h` - else: - h = None - - command = 'ip route' - prefix = w['prefix'] - mask = w['mask'] - vrf = w.get('vrf') - if vrf: - command = ' '.join((command, 'vrf', vrf, prefix, mask)) - else: - command = ' '.join((command, prefix, mask)) - - for key in ['interface', 'next_hop', 'admin_distance', 'tag', 'name', 'track']: - if w.get(key): - if key == 'name' and len(w.get(key).split()) > 1: - command = ' '.join((command, key, '"%s"' % w.get(key))) # name with multiple words needs to be quoted - elif key in ('name', 'tag', 'track'): - command = ' '.join((command, key, w.get(key))) - else: - command = ' '.join((command, w.get(key))) - - if state == 'absent' and h: - commands.append('no %s' % command) - elif state == 'present' and not h: - commands.append(command) - - return commands - - -def map_config_to_obj(module): - obj = [] - - out = get_config(module, flags='| include ip route') - - for line in out.splitlines(): - splitted_line = findall(r'[^"\s]\S*|".+?"', line) # Split by whitespace but do not split quotes, needed for name parameter - - if splitted_line[2] == 'vrf': - route = {'vrf': splitted_line[3]} - del splitted_line[:4] # Removes the words ip route vrf vrf_name - else: - route = {} - del splitted_line[:2] # Removes the words ip route - - prefix = splitted_line[0] - mask = splitted_line[1] - route.update({'prefix': prefix, 'mask': mask, 'admin_distance': '1'}) - - next_word = None - for word in splitted_line[2:]: - if next_word: - route[next_word] = word.strip('"') # Remove quotes which is needed for name - next_word = None - elif validate_ip_address(word): - route.update(next_hop=word) - elif word.isdigit(): - route.update(admin_distance=word) - elif word in ('tag', 'name', 'track'): - next_word = word - else: - route.update(interface=word) - - obj.append(route) - - return obj - - -def map_params_to_obj(module, required_together=None): - keys = ['prefix', 'mask', 'state', 'next_hop', 'vrf', 'interface', 'name', 'admin_distance', 'track', 'tag'] - obj = [] - - aggregate = module.params.get('aggregate') - if aggregate: - for item in aggregate: - route = item.copy() - for key in keys: - if route.get(key) is None: - route[key] = module.params.get(key) - - route = dict((k, v) for k, v in route.items() if v is not None) - module._check_required_together(required_together, route) - obj.append(route) - else: - module._check_required_together(required_together, module.params) - route = dict() - for key in keys: - if module.params.get(key) is not None: - route[key] = module.params.get(key) - obj.append(route) - - return obj - - -def main(): - """ main entry point for module execution - """ - element_spec = dict( - prefix=dict(type='str'), - mask=dict(type='str'), - next_hop=dict(type='str'), - vrf=dict(type='str'), - interface=dict(type='str'), - name=dict(type='str', aliases=['description']), - admin_distance=dict(type='str'), - track=dict(type='str'), - tag=dict(type='str'), - state=dict(default='present', choices=['present', 'absent']) - ) - - aggregate_spec = deepcopy(element_spec) - aggregate_spec['prefix'] = dict(required=True) - - # remove default in aggregate spec, to handle common arguments - remove_default_spec(aggregate_spec) - - argument_spec = dict( - aggregate=dict(type='list', elements='dict', options=aggregate_spec), - ) - - argument_spec.update(element_spec) - argument_spec.update(ios_argument_spec) - - required_one_of = [['aggregate', 'prefix']] - required_together = [['prefix', 'mask']] - mutually_exclusive = [['aggregate', 'prefix']] - - module = AnsibleModule(argument_spec=argument_spec, - required_one_of=required_one_of, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True) - - warnings = list() - - result = {'changed': False} - if warnings: - result['warnings'] = warnings - want = map_params_to_obj(module, required_together=required_together) - have = map_config_to_obj(module) - - commands = map_obj_to_commands(want, have) - result['commands'] = commands - - if commands: - if not module.check_mode: - load_config(module, commands) - - result['changed'] = True - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_static_routes.py b/lib/ansible/modules/network/ios/ios_static_routes.py deleted file mode 100644 index dc76d04ffe3..00000000000 --- a/lib/ansible/modules/network/ios/ios_static_routes.py +++ /dev/null @@ -1,710 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The module file for ios_static_routes -""" - - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - -DOCUMENTATION = """ ---- -module: ios_static_routes -version_added: "2.10" -short_description: Configure and manage static routes on IOS devices. -description: This module configures and manages the static routes on IOS platforms. -author: Sumit Jaiswal (@justjais) -notes: -- Tested against Cisco IOSv Version 15.2 on VIRL -- This module works with connection C(network_cli). - See L(IOS Platform Options,../network/user_guide/platform_ios.html). -options: - config: - description: A dictionary of static route options - type: list - elements: dict - suboptions: - vrf: - description: - - IP VPN Routing/Forwarding instance name. - - NOTE, In case of IPV4/IPV6 VRF routing table should pre-exist before - configuring. - - NOTE, if the vrf information is not provided then the routes shall be - configured under global vrf. - type: str - address_families: - elements: dict - description: - - Address family to use for the static routes - type: list - suboptions: - afi: - description: - - Top level address family indicator. - required: true - type: str - choices: - - ipv4 - - ipv6 - routes: - description: Configuring static route - type: list - elements: dict - suboptions: - dest: - description: Destination prefix with its subnet mask - type: str - required: true - topology: - description: - - Configure static route for a Topology Routing/Forwarding instance - - NOTE, VRF and Topology can be used together only with Multicast and - Topology should pre-exist before it can be used - type: str - next_hops: - description: - - next hop address or interface - type: list - elements: dict - suboptions: - forward_router_address: - description: Forwarding router's address - type: str - interface: - description: Interface for directly connected static routes - type: str - dhcp: - description: Default gateway obtained from DHCP - type: bool - distance_metric: - description: Distance metric for this route - type: int - global: - description: Next hop address is global - type: bool - name: - description: Specify name of the next hop - type: str - multicast: - description: multicast route - type: bool - permanent: - description: permanent route - type: bool - tag: - description: - - Set tag for this route - - Refer to vendor documentation for valid values. - type: int - track: - description: - - Install route depending on tracked item with tracked object number. - - Tracking does not support multicast - - Refer to vendor documentation for valid values. - type: int - running_config: - description: - - The module, by default, will connect to the remote device and - retrieve the current running-config to use as a base for comparing - against the contents of source. There are times when it is not - desirable to have the task get the current running-config for - every task in a playbook. The I(running_config) argument allows the - implementer to pass in the configuration to use as the base - config for comparison. This value of this option should be the - output received from device by executing command - C(show configuration commands | grep 'static route') - type: str - state: - description: - - The state the configuration should be left in - - The states I(rendered), I(gathered) and I(parsed) does not perform any change on the - device. - - The state I(rendered) will transform the configuration in C(config) option to platform - specific CLI commands which will be returned in the I(rendered) key within the result. - For state I(rendered) active connection to remote host is not required. - - The state I(gathered) will fetch the running configuration from device and transform - it into structured data in the format as per the resource module argspec and the - value is returned in the I(gathered) key within the result. - - The state I(parsed) reads the configuration from C(running_config) option and transforms - it into JSON format as per the resource module parameters and the value is returned in - the I(parsed) key within the result. The value of C(running_config) option should be the - same format as the output of command I(show running-config | include ip route|ipv6 route) - executed on device. For state I(parsed) active connection to remote host is not required. - type: str - choices: - - merged - - replaced - - overridden - - deleted - - gathered - - rendered - - parsed - default: merged -""" - -EXAMPLES = """ ---- - -# Using merged - -# Before state: -# ------------- -# -# vios#show running-config | include ip route|ipv6 route - -- name: Merge provided configuration with device configuration - ios_static_routes: - config: - - vrf: blue - address_families: - - afi: ipv4 - routes: - - dest: 192.0.2.0/24 - next_hops: - - forward_router_address: 192.0.2.1 - name: merged_blue - tag: 50 - track: 150 - - address_families: - - afi: ipv4 - routes: - - dest: 198.51.100.0/24 - next_hops: - - forward_router_address: 198.51.101.1 - name: merged_route_1 - distance_metric: 110 - tag: 40 - multicast: True - - forward_router_address: 198.51.101.2 - name: merged_route_2 - distance_metric: 30 - - forward_router_address: 198.51.101.3 - name: merged_route_3 - - afi: ipv6 - routes: - - dest: 2001:DB8:0:3::/64 - next_hops: - - forward_router_address: 2001:DB8:0:3::2 - name: merged_v6 - tag: 105 - state: merged - -# Commands fired: -# --------------- -# ip route vrf blue 192.0.2.0 255.255.255.0 10.0.0.8 name merged_blue track 150 tag 50 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name merged_route_1 tag 40 -# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name merged_route_2 -# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name merged_route_3 -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name merged_v6 tag 105 - -# After state: -# ------------ -# -# vios#show running-config | include ip route|ipv6 route -# ip route vrf blue 192.0.2.0 255.255.255.0 192.0.2.1 tag 50 name merged_blue track 150 -# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name merged_route_3 -# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name merged_route_2 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 tag 40 name merged_route_1 multicast -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name merged_v6 - -# Using replaced - -# Before state: -# ------------- -# -# vios#show running-config | include ip route|ipv6 route -# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40 -# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105 - -- name: Replace provided configuration with device configuration - ios_static_routes: - config: - - address_families: - - afi: ipv4 - routes: - - dest: 198.51.100.0/24 - next_hops: - - forward_router_address: 198.51.101.1 - name: replaced_route - distance_metric: 175 - tag: 70 - multicast: True - state: replaced - -# Commands fired: -# --------------- -# no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40 -# no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 175 name replaced_route track 150 tag 70 - -# After state: -# ------------ -# -# vios#show running-config | include ip route|ipv6 route -# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 175 name replaced_route track 150 tag 70 -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name test_v6 - -# Using overridden - -# Before state: -# ------------- -# -# vios#show running-config | include ip route|ipv6 route -# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40 -# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105 - -- name: Override provided configuration with device configuration - ios_static_routes: - config: - - vrf: blue - address_families: - - afi: ipv4 - routes: - - dest: 192.0.2.0/24 - next_hops: - - forward_router_address: 192.0.2.1 - name: override_vrf - tag: 50 - track: 150 - state: overridden - -# Commands fired: -# --------------- -# no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40 -# no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# no ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 198.51.101.8 name test_vrf track 150 tag 50 -# no ipv6 route FD5D:12C9:2201:1::/64 FD5D:12C9:2202::2 name test_v6 tag 105 -# ip route vrf blue 192.0.2.0 255.255.255.0 198.51.101.4 name override_vrf track 150 tag 50 - -# After state: -# ------------ -# -# vios#show running-config | include ip route|ipv6 route -# ip route vrf blue 192.0.2.0 255.255.255.0 192.0.2.1 tag 50 name override_vrf track 150 - -# Using Deleted - -# Example 1: -# ---------- -# To delete the exact static routes, with all the static routes explicitly mentioned in want - -# Before state: -# ------------- -# -# vios#show running-config | include ip route|ipv6 route -# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40 -# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105 - -- name: Delete provided configuration from the device configuration - ios_static_routes: - config: - - vrf: ansible_temp_vrf - address_families: - - afi: ipv4 - routes: - - dest: 192.0.2.0/24 - next_hops: - - forward_router_address: 192.0.2.1 - name: test_vrf - tag: 50 - track: 150 - - address_families: - - afi: ipv4 - routes: - - dest: 198.51.100.0/24 - next_hops: - - forward_router_address: 198.51.101.1 - name: route_1 - distance_metric: 110 - tag: 40 - multicast: True - - forward_router_address: 198.51.101.2 - name: route_2 - distance_metric: 30 - - forward_router_address: 198.51.101.3 - name: route_3 - - afi: ipv6 - routes: - - dest: 2001:DB8:0:3::/64 - next_hops: - - forward_router_address: 2001:DB8:0:3::2 - name: test_v6 - tag: 105 - state: deleted - -# Commands fired: -# --------------- -# no ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 198.51.101.8 name test_vrf track 150 tag 50 -# no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40 -# no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# no ipv6 route FD5D:12C9:2201:1::/64 FD5D:12C9:2202::2 name test_v6 tag 105 - -# After state: -# ------------ -# -# vios#show running-config | include ip route|ipv6 route - -# Example 2: -# ---------- -# To delete the destination specific static routes - -# Before state: -# ------------- -# -# vios#show running-config | include ip route|ipv6 route -# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40 -# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105 - -- name: Delete provided configuration from the device configuration - ios_static_routes: - config: - - address_families: - - afi: ipv4 - routes: - - dest: 198.51.100.0/24 - state: deleted - -# Commands fired: -# --------------- -# no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 tag 40 name route_1 multicast - -# After state: -# ------------ -# -# vios#show running-config | include ip route|ipv6 route -# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 tag 50 name test_vrf track 150 -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name test_v6 - - -# Example 3: -# ---------- -# To delete the vrf specific static routes - -# Before state: -# ------------- -# -# vios#show running-config | include ip route|ipv6 route -# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40 -# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105 - -- name: Delete provided configuration from the device configuration - ios_static_routes: - config: - - vrf: ansible_temp_vrf - state: deleted - -# Commands fired: -# --------------- -# no ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50 - -# After state: -# ------------ -# -# vios#show running-config | include ip route|ipv6 route -# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 tag 40 name route_1 multicast -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name test_v6 - -# Using Deleted without any config passed -#"(NOTE: This will delete all of configured resource module attributes from each configured interface)" - -# Before state: -# ------------- -# -# vios#show running-config | include ip route|ipv6 route -# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40 -# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105 - -- name: Delete ALL configured IOS static routes - ios_static_routes: - state: deleted - -# Commands fired: -# --------------- -# no ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 tag 50 name test_vrf track 150 -# no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 tag 40 name route_1 multicast -# no ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name test_v6 - -# After state: -# ------------- -# -# vios#show running-config | include ip route|ipv6 route -# - -# Using gathered - -# Before state: -# ------------- -# -# vios#show running-config | include ip route|ipv6 route -# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40 -# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105 - -- name: Gather listed static routes with provided configurations - ios_static_routes: - config: - state: gathered - -# Module Execution Result: -# ------------------------ -# -# "gathered": [ -# { -# "address_families": [ -# { -# "afi": "ipv4", -# "routes": [ -# { -# "dest": "192.0.2.0/24", -# "next_hops": [ -# { -# "forward_router_address": "192.0.2.1", -# "name": "test_vrf", -# "tag": 50, -# "track": 150 -# } -# ] -# } -# ] -# } -# ], -# "vrf": "ansible_temp_vrf" -# }, -# { -# "address_families": [ -# { -# "afi": "ipv6", -# "routes": [ -# { -# "dest": "2001:DB8:0:3::/64", -# "next_hops": [ -# { -# "forward_router_address": "2001:DB8:0:3::2", -# "name": "test_v6", -# "tag": 105 -# } -# ] -# } -# ] -# }, -# { -# "afi": "ipv4", -# "routes": [ -# { -# "dest": "198.51.100.0/24", -# "next_hops": [ -# { -# "distance_metric": 110, -# "forward_router_address": "198.51.101.1", -# "multicast": true, -# "name": "route_1", -# "tag": 40 -# }, -# { -# "distance_metric": 30, -# "forward_router_address": "198.51.101.2", -# "name": "route_2" -# }, -# { -# "forward_router_address": "198.51.101.3", -# "name": "route_3" -# } -# ] -# } -# ] -# } -# ] -# } -# ] - -# After state: -# ------------ -# -# vios#show running-config | include ip route|ipv6 route -# ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50 -# ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40 -# ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 -# ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 -# ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105 - -# Using rendered - -- name: Render the commands for provided configuration - ios_static_routes: - config: - - vrf: ansible_temp_vrf - address_families: - - afi: ipv4 - routes: - - dest: 192.0.2.0/24 - next_hops: - - forward_router_address: 192.0.2.1 - name: test_vrf - tag: 50 - track: 150 - - address_families: - - afi: ipv4 - routes: - - dest: 198.51.100.0/24 - next_hops: - - forward_router_address: 198.51.101.1 - name: route_1 - distance_metric: 110 - tag: 40 - multicast: True - - forward_router_address: 198.51.101.2 - name: route_2 - distance_metric: 30 - - forward_router_address: 198.51.101.3 - name: route_3 - - afi: ipv6 - routes: - - dest: 2001:DB8:0:3::/64 - next_hops: - - forward_router_address: 2001:DB8:0:3::2 - name: test_v6 - tag: 105 - state: rendered - -# Module Execution Result: -# ------------------------ -# -# "rendered": [ -# "ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50", -# "ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40", -# "ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2", -# "ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3", -# "ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105" -# ] - -""" - -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: list - sample: The configuration returned will always be in the same format of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: list - sample: The configuration returned will always be in the same format of the parameters above. -commands: - description: The set of commands pushed to the remote device - returned: always - type: list - sample: ['ip route vrf test 172.31.10.0 255.255.255.0 10.10.10.2 name new_test multicast'] -rendered: - description: The set of CLI commands generated from the value in C(config) option - returned: When C(state) is I(rendered) - type: list - sample: ['interface Ethernet1/1', 'mtu 1800'] -gathered: - description: - - The configuration as structured data transformed for the running configuration - fetched from remote host - returned: When C(state) is I(gathered) - type: list - sample: > - The configuration returned will always be in the same format - of the parameters above. -parsed: - description: - - The configuration as structured data transformed for the value of - C(running_config) option - returned: When C(state) is I(parsed) - type: list - sample: > - The configuration returned will always be in the same format - of the parameters above. -""" - - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.static_routes.static_routes import Static_RoutesArgs -from ansible.module_utils.network.ios.config.static_routes.static_routes import Static_Routes - - -def main(): - """ - Main entry point for module execution - - :returns: the result form module invocation - """ - required_if = [('state', 'merged', ('config',)), - ('state', 'replaced', ('config',)), - ('state', 'overridden', ('config',)), - ('state', 'rendered', ('config',)), - ('state', 'parsed', ('running_config',))] - mutually_exclusive = [('config', 'running_config')] - - module = AnsibleModule(argument_spec=Static_RoutesArgs.argument_spec, - required_if=required_if, - supports_check_mode=True, - mutually_exclusive=mutually_exclusive) - - result = Static_Routes(module).execute_module() - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_system.py b/lib/ansible/modules/network/ios/ios_system.py deleted file mode 100644 index cb1d7824c6d..00000000000 --- a/lib/ansible/modules/network/ios/ios_system.py +++ /dev/null @@ -1,380 +0,0 @@ -#!/usr/bin/python -# -# 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 . -# - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_system -version_added: "2.3" -author: "Peter Sprygada (@privateip)" -short_description: Manage the system attributes on Cisco IOS devices -description: - - This module provides declarative management of node system attributes - on Cisco IOS devices. It provides an option to configure host system - parameters or remove those parameters from the device active - configuration. -extends_documentation_fragment: ios -notes: - - Tested against IOS 15.6 -options: - hostname: - description: - - Configure the device hostname parameter. This option takes an ASCII string value. - domain_name: - description: - - Configure the IP domain name - on the remote device to the provided value. Value - should be in the dotted name form and will be - appended to the C(hostname) to create a fully-qualified - domain name. - domain_search: - description: - - Provides the list of domain suffixes to - append to the hostname for the purpose of doing name resolution. - This argument accepts a list of names and will be reconciled - with the current active configuration on the running node. - lookup_source: - description: - - Provides one or more source - interfaces to use for performing DNS lookups. The interface - provided in C(lookup_source) must be a valid interface configured - on the device. - lookup_enabled: - description: - - Administrative control - for enabling or disabling DNS lookups. When this argument is - set to True, lookups are performed and when it is set to False, - lookups are not performed. - type: bool - name_servers: - description: - - List of DNS name servers by IP address to use to perform name resolution - lookups. This argument accepts either a list of DNS servers See - examples. - state: - description: - - State of the configuration - values in the device's current active configuration. When set - to I(present), the values should be configured in the device active - configuration and when set to I(absent) the values should not be - in the device active configuration - default: present - choices: ['present', 'absent'] -""" - -EXAMPLES = """ -- name: configure hostname and domain name - ios_system: - hostname: ios01 - domain_name: test.example.com - domain_search: - - ansible.com - - redhat.com - - cisco.com - -- name: remove configuration - ios_system: - state: absent - -- name: configure DNS lookup sources - ios_system: - lookup_source: MgmtEth0/0/CPU0/0 - lookup_enabled: yes - -- name: configure name servers - ios_system: - name_servers: - - 8.8.8.8 - - 8.8.4.4 -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always - type: list - sample: - - hostname ios01 - - ip domain name test.example.com -""" -import re - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.ios import get_config, load_config -from ansible.module_utils.network.ios.ios import ios_argument_spec -from ansible.module_utils.network.common.utils import ComplexList - -_CONFIGURED_VRFS = None - - -def has_vrf(module, vrf): - global _CONFIGURED_VRFS - if _CONFIGURED_VRFS is not None: - return vrf in _CONFIGURED_VRFS - config = get_config(module) - _CONFIGURED_VRFS = re.findall(r'vrf definition (\S+)', config) - return vrf in _CONFIGURED_VRFS - - -def requires_vrf(module, vrf): - if not has_vrf(module, vrf): - module.fail_json(msg='vrf %s is not configured' % vrf) - - -def diff_list(want, have): - adds = [w for w in want if w not in have] - removes = [h for h in have if h not in want] - return (adds, removes) - - -def map_obj_to_commands(want, have, module): - commands = list() - state = module.params['state'] - - def needs_update(x): - return want.get(x) is not None and (want.get(x) != have.get(x)) - - if state == 'absent': - if have['hostname'] != 'Router': - commands.append('no hostname') - - if have['lookup_source']: - commands.append('no ip domain lookup source-interface %s' % have['lookup_source']) - - if have['lookup_enabled'] is False: - commands.append('ip domain lookup') - - vrfs = set() - for item in have['domain_name']: - if item['vrf'] and item['vrf'] not in vrfs: - vrfs.add(item['vrf']) - commands.append('no ip domain name vrf %s' % item['vrf']) - elif None not in vrfs: - vrfs.add(None) - commands.append('no ip domain name') - - vrfs = set() - for item in have['domain_search']: - if item['vrf'] and item['vrf'] not in vrfs: - vrfs.add(item['vrf']) - commands.append('no ip domain list vrf %s' % item['vrf']) - elif None not in vrfs: - vrfs.add(None) - commands.append('no ip domain list') - - vrfs = set() - for item in have['name_servers']: - if item['vrf'] and item['vrf'] not in vrfs: - vrfs.add(item['vrf']) - commands.append('no ip name-server vrf %s' % item['vrf']) - elif None not in vrfs: - vrfs.add(None) - commands.append('no ip name-server') - - elif state == 'present': - if needs_update('hostname'): - commands.append('hostname %s' % want['hostname']) - - if needs_update('lookup_source'): - commands.append('ip domain lookup source-interface %s' % want['lookup_source']) - - if needs_update('lookup_enabled'): - cmd = 'ip domain lookup' - if want['lookup_enabled'] is False: - cmd = 'no %s' % cmd - commands.append(cmd) - - if want['domain_name']: - adds, removes = diff_list(want['domain_name'], have['domain_name']) - for item in removes: - if item['vrf']: - commands.append('no ip domain name vrf %s %s' % (item['vrf'], item['name'])) - else: - commands.append('no ip domain name %s' % item['name']) - for item in adds: - if item['vrf']: - requires_vrf(module, item['vrf']) - commands.append('ip domain name vrf %s %s' % (item['vrf'], item['name'])) - else: - commands.append('ip domain name %s' % item['name']) - - if want['domain_search']: - adds, removes = diff_list(want['domain_search'], have['domain_search']) - for item in removes: - if item['vrf']: - commands.append('no ip domain list vrf %s %s' % (item['vrf'], item['name'])) - else: - commands.append('no ip domain list %s' % item['name']) - for item in adds: - if item['vrf']: - requires_vrf(module, item['vrf']) - commands.append('ip domain list vrf %s %s' % (item['vrf'], item['name'])) - else: - commands.append('ip domain list %s' % item['name']) - - if want['name_servers']: - adds, removes = diff_list(want['name_servers'], have['name_servers']) - for item in removes: - if item['vrf']: - commands.append('no ip name-server vrf %s %s' % (item['vrf'], item['server'])) - else: - commands.append('no ip name-server %s' % item['server']) - for item in adds: - if item['vrf']: - requires_vrf(module, item['vrf']) - commands.append('ip name-server vrf %s %s' % (item['vrf'], item['server'])) - else: - commands.append('ip name-server %s' % item['server']) - - return commands - - -def parse_hostname(config): - match = re.search(r'^hostname (\S+)', config, re.M) - return match.group(1) - - -def parse_domain_name(config): - match = re.findall(r'^ip domain[- ]name (?:vrf (\S+) )*(\S+)', config, re.M) - matches = list() - for vrf, name in match: - if not vrf: - vrf = None - matches.append({'name': name, 'vrf': vrf}) - return matches - - -def parse_domain_search(config): - match = re.findall(r'^ip domain[- ]list (?:vrf (\S+) )*(\S+)', config, re.M) - matches = list() - for vrf, name in match: - if not vrf: - vrf = None - matches.append({'name': name, 'vrf': vrf}) - return matches - - -def parse_name_servers(config): - match = re.findall(r'^ip name-server (?:vrf (\S+) )*(.*)', config, re.M) - matches = list() - for vrf, servers in match: - if not vrf: - vrf = None - for server in servers.split(): - matches.append({'server': server, 'vrf': vrf}) - return matches - - -def parse_lookup_source(config): - match = re.search(r'ip domain[- ]lookup source-interface (\S+)', config, re.M) - if match: - return match.group(1) - - -def map_config_to_obj(module): - config = get_config(module) - return { - 'hostname': parse_hostname(config), - 'domain_name': parse_domain_name(config), - 'domain_search': parse_domain_search(config), - 'lookup_source': parse_lookup_source(config), - 'lookup_enabled': 'no ip domain lookup' not in config and 'no ip domain-lookup' not in config, - 'name_servers': parse_name_servers(config) - } - - -def map_params_to_obj(module): - obj = { - 'hostname': module.params['hostname'], - 'lookup_source': module.params['lookup_source'], - 'lookup_enabled': module.params['lookup_enabled'], - } - - domain_name = ComplexList(dict( - name=dict(key=True), - vrf=dict() - ), module) - - domain_search = ComplexList(dict( - name=dict(key=True), - vrf=dict() - ), module) - - name_servers = ComplexList(dict( - server=dict(key=True), - vrf=dict() - ), module) - - for arg, cast in [('domain_name', domain_name), - ('domain_search', domain_search), - ('name_servers', name_servers)]: - - if module.params[arg]: - obj[arg] = cast(module.params[arg]) - else: - obj[arg] = None - - return obj - - -def main(): - """ Main entry point for Ansible module execution - """ - argument_spec = dict( - hostname=dict(), - - domain_name=dict(type='list'), - domain_search=dict(type='list'), - name_servers=dict(type='list'), - - lookup_source=dict(), - lookup_enabled=dict(type='bool'), - - state=dict(choices=['present', 'absent'], default='present') - ) - - argument_spec.update(ios_argument_spec) - - module = AnsibleModule(argument_spec=argument_spec, - supports_check_mode=True) - - result = {'changed': False} - - warnings = list() - result['warnings'] = warnings - - want = map_params_to_obj(module) - have = map_config_to_obj(module) - - commands = map_obj_to_commands(want, have, module) - result['commands'] = commands - - if commands: - if not module.check_mode: - load_config(module, commands) - result['changed'] = True - - module.exit_json(**result) - - -if __name__ == "__main__": - main() diff --git a/lib/ansible/modules/network/ios/ios_user.py b/lib/ansible/modules/network/ios/ios_user.py deleted file mode 100644 index 37afe741dd2..00000000000 --- a/lib/ansible/modules/network/ios/ios_user.py +++ /dev/null @@ -1,533 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, Ansible by Red Hat, inc -# -# This file is part of Ansible by Red Hat -# -# 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 . -# - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - -DOCUMENTATION = """ ---- -module: ios_user -version_added: "2.4" -author: "Trishna Guha (@trishnaguha)" -short_description: Manage the aggregate of local users on Cisco IOS device -description: - - This module provides declarative management of the local usernames - configured on network devices. It allows playbooks to manage - either individual usernames or the aggregate of usernames in the - current running config. It also supports purging usernames from the - configuration that are not explicitly defined. -notes: - - Tested against IOS 15.6 -options: - aggregate: - description: - - The set of username objects to be configured on the remote - Cisco IOS device. The list entries can either be the username - or a hash of username and properties. This argument is mutually - exclusive with the C(name) argument. - aliases: ['users', 'collection'] - name: - description: - - The username to be configured on the Cisco IOS device. - This argument accepts a string value and is mutually exclusive - with the C(aggregate) argument. - Please note that this option is not same as C(provider username). - configured_password: - description: - - The password to be configured on the Cisco IOS device. The - password needs to be provided in clear and it will be encrypted - on the device. - Please note that this option is not same as C(provider password). - update_password: - description: - - Since passwords are encrypted in the device running config, this - argument will instruct the module when to change the password. When - set to C(always), the password will always be updated in the device - and when set to C(on_create) the password will be updated only if - the username is created. - default: always - choices: ['on_create', 'always'] - password_type: - description: - - This argument determines whether a 'password' or 'secret' will be - configured. - default: secret - choices: ['secret', 'password'] - version_added: "2.8" - hashed_password: - description: - - This option allows configuring hashed passwords on Cisco IOS devices. - suboptions: - type: - description: - - Specifies the type of hash (e.g., 5 for MD5, 8 for PBKDF2, etc.) - - For this to work, the device needs to support the desired hash type - type: int - required: True - value: - description: - - The actual hashed password to be configured on the device - required: True - version_added: "2.8" - privilege: - description: - - The C(privilege) argument configures the privilege level of the - user when logged into the system. This argument accepts integer - values in the range of 1 to 15. - view: - description: - - Configures the view for the username in the - device running configuration. The argument accepts a string value - defining the view name. This argument does not check if the view - has been configured on the device. - aliases: ['role'] - sshkey: - description: - - Specifies one or more SSH public key(s) to configure - for the given username. - - This argument accepts a valid SSH key value. - version_added: "2.7" - nopassword: - description: - - Defines the username without assigning - a password. This will allow the user to login to the system - without being authenticated by a password. - type: bool - purge: - description: - - Instructs the module to consider the - resource definition absolute. It will remove any previously - configured usernames on the device with the exception of the - `admin` user (the current defined set of users). - type: bool - default: false - state: - description: - - Configures the state of the username definition - as it relates to the device operational configuration. When set - to I(present), the username(s) should be configured in the device active - configuration and when set to I(absent) the username(s) should not be - in the device active configuration - default: present - choices: ['present', 'absent'] -extends_documentation_fragment: ios -""" - -EXAMPLES = """ -- name: create a new user - ios_user: - name: ansible - nopassword: True - sshkey: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" - state: present - -- name: create a new user with multiple keys - ios_user: - name: ansible - sshkey: - - "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" - - "{{ lookup('file', '~/path/to/public_key') }}" - state: present - -- name: remove all users except admin - ios_user: - purge: yes - -- name: remove all users except admin and these listed users - ios_user: - aggregate: - - name: testuser1 - - name: testuser2 - - name: testuser3 - purge: yes - -- name: set multiple users to privilege level 15 - ios_user: - aggregate: - - name: netop - - name: netend - privilege: 15 - state: present - -- name: set user view/role - ios_user: - name: netop - view: network-operator - state: present - -- name: Change Password for User netop - ios_user: - name: netop - configured_password: "{{ new_password }}" - update_password: always - state: present - -- name: Aggregate of users - ios_user: - aggregate: - - name: ansibletest2 - - name: ansibletest3 - view: network-admin - -- name: Add a user specifying password type - ios_user: - name: ansibletest4 - configured_password: "{{ new_password }}" - password_type: password - -- name: Add a user with MD5 hashed password - ios_user: - name: ansibletest5 - hashed_password: - type: 5 - value: $3$8JcDilcYgFZi.yz4ApaqkHG2.8/ - -- name: Delete users with aggregate - ios_user: - aggregate: - - name: ansibletest1 - - name: ansibletest2 - - name: ansibletest3 - state: absent -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always - type: list - sample: - - username ansible secret password - - username admin secret admin -""" -import base64 -import hashlib -import re -from copy import deepcopy -from functools import partial - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.utils import remove_default_spec -from ansible.module_utils.network.ios.ios import get_config, load_config -from ansible.module_utils.network.ios.ios import ios_argument_spec -from ansible.module_utils.six import iteritems - - -def validate_privilege(value, module): - if value and not 1 <= value <= 15: - module.fail_json(msg='privilege must be between 1 and 15, got %s' % value) - - -def user_del_cmd(username): - return { - 'command': 'no username %s' % username, - 'prompt': 'This operation will remove all username related configurations with same name', - 'answer': 'y', - 'newline': False, - } - - -def sshkey_fingerprint(sshkey): - # IOS will accept a MD5 fingerprint of the public key - # and is easier to configure in a single line - # we calculate this fingerprint here - if not sshkey: - return None - if ' ' in sshkey: - # ssh-rsa AAA...== comment - keyparts = sshkey.split(' ') - keyparts[1] = hashlib.md5(base64.b64decode(keyparts[1])).hexdigest().upper() - return ' '.join(keyparts) - else: - # just the key, assume rsa type - return 'ssh-rsa %s' % hashlib.md5(base64.b64decode(sshkey)).hexdigest().upper() - - -def map_obj_to_commands(updates, module): - commands = list() - update_password = module.params['update_password'] - password_type = module.params['password_type'] - - def needs_update(want, have, x): - return want.get(x) and (want.get(x) != have.get(x)) - - def add(command, want, x): - command.append('username %s %s' % (want['name'], x)) - - def add_hashed_password(command, want, x): - command.append('username %s secret %s %s' % (want['name'], x.get('type'), - x.get('value'))) - - def add_ssh(command, want, x=None): - command.append('ip ssh pubkey-chain') - if x: - command.append('username %s' % want['name']) - for item in x: - command.append('key-hash %s' % item) - command.append('exit') - else: - command.append('no username %s' % want['name']) - command.append('exit') - - for update in updates: - want, have = update - - if want['state'] == 'absent': - if have['sshkey']: - add_ssh(commands, want) - else: - commands.append(user_del_cmd(want['name'])) - - if needs_update(want, have, 'view'): - add(commands, want, 'view %s' % want['view']) - - if needs_update(want, have, 'privilege'): - add(commands, want, 'privilege %s' % want['privilege']) - - if needs_update(want, have, 'sshkey'): - add_ssh(commands, want, want['sshkey']) - - if needs_update(want, have, 'configured_password'): - if update_password == 'always' or not have: - if have and password_type != have['password_type']: - module.fail_json(msg='Can not have both a user password and a user secret.' + - ' Please choose one or the other.') - add(commands, want, '%s %s' % (password_type, want['configured_password'])) - - if needs_update(want, have, 'hashed_password'): - add_hashed_password(commands, want, want['hashed_password']) - - if needs_update(want, have, 'nopassword'): - if want['nopassword']: - add(commands, want, 'nopassword') - else: - add(commands, want, user_del_cmd(want['name'])) - - return commands - - -def parse_view(data): - match = re.search(r'view (\S+)', data, re.M) - if match: - return match.group(1) - - -def parse_sshkey(data, user): - sshregex = r'username %s(\n\s+key-hash .+$)+' % user - sshcfg = re.search(sshregex, data, re.M) - key_list = [] - if sshcfg: - match = re.findall(r'key-hash (\S+ \S+(?: .+)?)$', sshcfg.group(), re.M) - if match: - key_list = match - return key_list - - -def parse_privilege(data): - match = re.search(r'privilege (\S+)', data, re.M) - if match: - return int(match.group(1)) - - -def parse_password_type(data): - type = None - if data and data.split()[-3] in ['password', 'secret']: - type = data.split()[-3] - return type - - -def map_config_to_obj(module): - data = get_config(module, flags=['| section username']) - - match = re.findall(r'(?:^(?:u|\s{2}u))sername (\S+)', data, re.M) - if not match: - return list() - - instances = list() - - for user in set(match): - regex = r'username %s .+$' % user - cfg = re.findall(regex, data, re.M) - cfg = '\n'.join(cfg) - obj = { - 'name': user, - 'state': 'present', - 'nopassword': 'nopassword' in cfg, - 'configured_password': None, - 'hashed_password': None, - 'password_type': parse_password_type(cfg), - 'sshkey': parse_sshkey(data, user), - 'privilege': parse_privilege(cfg), - 'view': parse_view(cfg) - } - instances.append(obj) - - return instances - - -def get_param_value(key, item, module): - # if key doesn't exist in the item, get it from module.params - if not item.get(key): - value = module.params[key] - - # if key does exist, do a type check on it to validate it - else: - value_type = module.argument_spec[key].get('type', 'str') - type_checker = module._CHECK_ARGUMENT_TYPES_DISPATCHER[value_type] - type_checker(item[key]) - value = item[key] - - # validate the param value (if validator func exists) - validator = globals().get('validate_%s' % key) - if all((value, validator)): - validator(value, module) - - return value - - -def map_params_to_obj(module): - users = module.params['aggregate'] - if not users: - if not module.params['name'] and module.params['purge']: - return list() - elif not module.params['name']: - module.fail_json(msg='username is required') - else: - aggregate = [{'name': module.params['name']}] - else: - aggregate = list() - for item in users: - if not isinstance(item, dict): - aggregate.append({'name': item}) - elif 'name' not in item: - module.fail_json(msg='name is required') - else: - aggregate.append(item) - - objects = list() - - for item in aggregate: - get_value = partial(get_param_value, item=item, module=module) - item['configured_password'] = get_value('configured_password') - item['hashed_password'] = get_value('hashed_password') - item['nopassword'] = get_value('nopassword') - item['privilege'] = get_value('privilege') - item['view'] = get_value('view') - item['sshkey'] = render_key_list(get_value('sshkey')) - item['state'] = get_value('state') - objects.append(item) - - return objects - - -def render_key_list(ssh_keys): - key_list = [] - if ssh_keys: - for item in ssh_keys: - key_list.append(sshkey_fingerprint(item)) - return key_list - - -def update_objects(want, have): - updates = list() - for entry in want: - item = next((i for i in have if i['name'] == entry['name']), None) - if all((item is None, entry['state'] == 'present')): - updates.append((entry, {})) - elif item: - for key, value in iteritems(entry): - if value and value != item[key]: - updates.append((entry, item)) - return updates - - -def main(): - """ main entry point for module execution - """ - hashed_password_spec = dict( - type=dict(type='int', required=True), - value=dict(no_log=True, required=True) - ) - - element_spec = dict( - name=dict(), - - configured_password=dict(no_log=True), - hashed_password=dict(no_log=True, type='dict', options=hashed_password_spec), - nopassword=dict(type='bool'), - update_password=dict(default='always', choices=['on_create', 'always']), - password_type=dict(default='secret', choices=['secret', 'password']), - - privilege=dict(type='int'), - view=dict(aliases=['role']), - - sshkey=dict(type='list'), - - state=dict(default='present', choices=['present', 'absent']) - ) - aggregate_spec = deepcopy(element_spec) - aggregate_spec['name'] = dict(required=True) - - # remove default in aggregate spec, to handle common arguments - remove_default_spec(aggregate_spec) - - argument_spec = dict( - aggregate=dict(type='list', elements='dict', options=aggregate_spec, aliases=['users', 'collection']), - purge=dict(type='bool', default=False) - ) - - argument_spec.update(element_spec) - argument_spec.update(ios_argument_spec) - - mutually_exclusive = [('name', 'aggregate'), ('nopassword', 'hashed_password', 'configured_password')] - - module = AnsibleModule(argument_spec=argument_spec, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True) - - warnings = list() - result = {'changed': False, 'warnings': warnings} - - want = map_params_to_obj(module) - have = map_config_to_obj(module) - - commands = map_obj_to_commands(update_objects(want, have), module) - - if module.params['purge']: - want_users = [x['name'] for x in want] - have_users = [x['name'] for x in have] - for item in set(have_users).difference(want_users): - if item != 'admin': - commands.append(user_del_cmd(item)) - - result['commands'] = commands - - if commands: - if not module.check_mode: - load_config(module, commands) - result['changed'] = True - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_vlans.py b/lib/ansible/modules/network/ios/ios_vlans.py deleted file mode 100644 index 7de87dbb527..00000000000 --- a/lib/ansible/modules/network/ios/ios_vlans.py +++ /dev/null @@ -1,464 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The module file for ios_vlans -""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network' -} - -DOCUMENTATION = """ -module: ios_vlans -version_added: 2.9 -short_description: Manage VLANs on Cisco IOS devices. -description: This module provides declarative management of VLANs on Cisco IOS network devices. -author: Sumit Jaiswal (@justjais) -notes: - - Tested against Cisco IOSv Version 15.2 on VIRL - - This module works with connection C(network_cli). - See L(IOS Platform Options,../network/user_guide/platform_ios.html). -options: - config: - description: A dictionary of VLANs options - type: list - elements: dict - suboptions: - name: - description: - - Ascii name of the VLAN. - - NOTE, I(name) should not be named/appended with I(default) as it is reserved for device default vlans. - type: str - vlan_id: - description: - - ID of the VLAN. Range 1-4094 - type: int - required: True - mtu: - description: - - VLAN Maximum Transmission Unit. - - Refer to vendor documentation for valid values. - type: int - state: - description: - - Operational state of the VLAN - type: str - choices: - - active - - suspend - remote_span: - description: - - Configure as Remote SPAN VLAN - type: bool - shutdown: - description: - - Shutdown VLAN switching. - type: str - choices: - - enabled - - disabled - state: - description: - - The state of the configuration after module completion - type: str - choices: - - merged - - replaced - - overridden - - deleted - default: merged -""" -EXAMPLES = """ ---- -# Using merged - -# Before state: -# ------------- -# -# vios#show vlan -# VLAN Name Status Ports -# ---- -------------------------------- --------- ------------------------------- -# 1 default active Gi0/1, Gi0/2 -# 1002 fddi-default act/unsup -# 1003 token-ring-default act/unsup -# 1004 fddinet-default act/unsup -# 1005 trnet-default act/unsup -# -# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2 -# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------ -# 1 enet 100001 1500 - - - - - 0 0 -# 1002 fddi 101002 1500 - - - - - 0 0 -# 1003 tr 101003 1500 - - - - - 0 0 -# 1004 fdnet 101004 1500 - - - ieee - 0 0 -# 1005 trnet 101005 1500 - - - ibm - 0 0 - -- name: Merge provided configuration with device configuration - ios_vlans: - config: - - name: Vlan_10 - vlan_id: 10 - state: active - shutdown: disabled - remote_span: 10 - - name: Vlan_20 - vlan_id: 20 - mtu: 610 - state: active - shutdown: enabled - - name: Vlan_30 - vlan_id: 30 - state: suspend - shutdown: enabled - state: merged - -# After state: -# ------------ -# -# vios#show vlan -# VLAN Name Status Ports -# ---- -------------------------------- --------- ------------------------------- -# 1 default active Gi0/1, Gi0/2 -# 10 vlan_10 active -# 20 vlan_20 act/lshut -# 30 vlan_30 sus/lshut -# 1002 fddi-default act/unsup -# 1003 token-ring-default act/unsup -# 1004 fddinet-default act/unsup -# 1005 trnet-default act/unsup -# -# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2 -# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------ -# 1 enet 100001 1500 - - - - - 0 0 -# 10 enet 100010 1500 - - - - - 0 0 -# 20 enet 100020 610 - - - - - 0 0 -# 30 enet 100030 1500 - - - - - 0 0 -# 1002 fddi 101002 1500 - - - - - 0 0 -# 1003 tr 101003 1500 - - - - - 0 0 -# 1004 fdnet 101004 1500 - - - ieee - 0 0 -# 1005 trnet 101005 1500 - - - ibm - 0 0 -# -# Remote SPAN VLANs -# ------------------------------------------------------------------------------ -# 10 - -# Using overridden - -# Before state: -# ------------- -# -# vios#show vlan -# VLAN Name Status Ports -# ---- -------------------------------- --------- ------------------------------- -# 1 default active Gi0/1, Gi0/2 -# 10 vlan_10 active -# 20 vlan_20 act/lshut -# 30 vlan_30 sus/lshut -# 1002 fddi-default act/unsup -# 1003 token-ring-default act/unsup -# 1004 fddinet-default act/unsup -# 1005 trnet-default act/unsup -# -# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2 -# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------ -# 1 enet 100001 1500 - - - - - 0 0 -# 10 enet 100010 1500 - - - - - 0 0 -# 20 enet 100020 610 - - - - - 0 0 -# 30 enet 100030 1500 - - - - - 0 0 -# 1002 fddi 101002 1500 - - - - - 0 0 -# 1003 tr 101003 1500 - - - - - 0 0 -# 1004 fdnet 101004 1500 - - - ieee - 0 0 -# 1005 trnet 101005 1500 - - - ibm - 0 0 -# -# Remote SPAN VLANs -# ------------------------------------------------------------------------------ -# 10 - -- name: Override device configuration of all VLANs with provided configuration - ios_vlans: - config: - - name: Vlan_10 - vlan_id: 10 - mtu: 1000 - state: overridden - -# After state: -# ------------ -# -# vios#show vlan -# VLAN Name Status Ports -# ---- -------------------------------- --------- ------------------------------- -# 10 Vlan_10 active -# -# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2 -# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------ -# 10 enet 100010 1000 - - - - - 0 0 - -# Using replaced - -# Before state: -# ------------- -# -# vios#show vlan -# VLAN Name Status Ports -# ---- -------------------------------- --------- ------------------------------- -# 1 default active Gi0/1, Gi0/2 -# 10 vlan_10 active -# 20 vlan_20 act/lshut -# 30 vlan_30 sus/lshut -# 1002 fddi-default act/unsup -# 1003 token-ring-default act/unsup -# 1004 fddinet-default act/unsup -# 1005 trnet-default act/unsup -# -# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2 -# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------ -# 1 enet 100001 1500 - - - - - 0 0 -# 10 enet 100010 1500 - - - - - 0 0 -# 20 enet 100020 610 - - - - - 0 0 -# 30 enet 100030 1500 - - - - - 0 0 -# 1002 fddi 101002 1500 - - - - - 0 0 -# 1003 tr 101003 1500 - - - - - 0 0 -# 1004 fdnet 101004 1500 - - - ieee - 0 0 -# 1005 trnet 101005 1500 - - - ibm - 0 0 -# -# Remote SPAN VLANs -# ------------------------------------------------------------------------------ -# 10 - -- name: Replaces device configuration of listed VLANs with provided configuration - ios_vlans: - config: - - vlan_id: 20 - name: Test_VLAN20 - mtu: 700 - shutdown: disabled - - vlan_id: 30 - name: Test_VLAN30 - mtu: 1000 - state: replaced - -# After state: -# ------------ -# -# vios#show vlan -# VLAN Name Status Ports -# ---- -------------------------------- --------- ------------------------------- -# 1 default active Gi0/1, Gi0/2 -# 10 vlan_10 active -# 20 Test_VLAN20 active -# 30 Test_VLAN30 sus/lshut -# 1002 fddi-default act/unsup -# 1003 token-ring-default act/unsup -# 1004 fddinet-default act/unsup -# 1005 trnet-default act/unsup -# -# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2 -# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------ -# 1 enet 100001 1500 - - - - - 0 0 -# 10 enet 100010 1500 - - - - - 0 0 -# 20 enet 100020 700 - - - - - 0 0 -# 30 enet 100030 1000 - - - - - 0 0 -# 1002 fddi 101002 1500 - - - - - 0 0 -# 1003 tr 101003 1500 - - - - - 0 0 -# 1004 fdnet 101004 1500 - - - ieee - 0 0 -# 1005 trnet 101005 1500 - - - ibm - 0 0 -# -# Remote SPAN VLANs -# ------------------------------------------------------------------------------ -# 10 - -# Using deleted - -# Before state: -# ------------- -# -# vios#show vlan -# VLAN Name Status Ports -# ---- -------------------------------- --------- ------------------------------- -# 1 default active Gi0/1, Gi0/2 -# 10 vlan_10 active -# 20 vlan_20 act/lshut -# 30 vlan_30 sus/lshut -# 1002 fddi-default act/unsup -# 1003 token-ring-default act/unsup -# 1004 fddinet-default act/unsup -# 1005 trnet-default act/unsup -# -# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2 -# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------ -# 1 enet 100001 1500 - - - - - 0 0 -# 10 enet 100010 1500 - - - - - 0 0 -# 20 enet 100020 610 - - - - - 0 0 -# 30 enet 100030 1500 - - - - - 0 0 -# 1002 fddi 101002 1500 - - - - - 0 0 -# 1003 tr 101003 1500 - - - - - 0 0 -# 1004 fdnet 101004 1500 - - - ieee - 0 0 -# 1005 trnet 101005 1500 - - - ibm - 0 0 -# -# Remote SPAN VLANs -# ------------------------------------------------------------------------------ -# 10 - -- name: Delete attributes of given VLANs - ios_vlans: - config: - - vlan_id: 10 - - vlan_id: 20 - state: deleted - -# After state: -# ------------- -# -# vios#show vlan -# VLAN Name Status Ports -# ---- -------------------------------- --------- ------------------------------- -# 1 default active Gi0/1, Gi0/2 -# 30 vlan_30 sus/lshut -# 1002 fddi-default act/unsup -# 1003 token-ring-default act/unsup -# 1004 fddinet-default act/unsup -# 1005 trnet-default act/unsup -# -# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2 -# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------ -# 1 enet 100001 1500 - - - - - 0 0 -# 30 enet 100030 1500 - - - - - 0 0 -# 1002 fddi 101002 1500 - - - - - 0 0 -# 1003 tr 101003 1500 - - - - - 0 0 -# 1004 fdnet 101004 1500 - - - ieee - 0 0 -# 1005 trnet 101005 1500 - - - ibm - 0 0 - -# Using Deleted without any config passed -#"(NOTE: This will delete all of configured vlans attributes)" - -# Before state: -# ------------- -# -# vios#show vlan -# VLAN Name Status Ports -# ---- -------------------------------- --------- ------------------------------- -# 1 default active Gi0/1, Gi0/2 -# 10 vlan_10 active -# 20 vlan_20 act/lshut -# 30 vlan_30 sus/lshut -# 1002 fddi-default act/unsup -# 1003 token-ring-default act/unsup -# 1004 fddinet-default act/unsup -# 1005 trnet-default act/unsup -# -# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2 -# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------ -# 1 enet 100001 1500 - - - - - 0 0 -# 10 enet 100010 1500 - - - - - 0 0 -# 20 enet 100020 610 - - - - - 0 0 -# 30 enet 100030 1500 - - - - - 0 0 -# 1002 fddi 101002 1500 - - - - - 0 0 -# 1003 tr 101003 1500 - - - - - 0 0 -# 1004 fdnet 101004 1500 - - - ieee - 0 0 -# 1005 trnet 101005 1500 - - - ibm - 0 0 -# -# Remote SPAN VLANs -# ------------------------------------------------------------------------------ -# 10 - -- name: Delete attributes of ALL VLANs - ios_vlans: - state: deleted - -# After state: -# ------------- -# -# vios#show vlan -# VLAN Name Status Ports -# ---- -------------------------------- --------- ------------------------------- -# 1 default active Gi0/1, Gi0/2 -# 1002 fddi-default act/unsup -# 1003 token-ring-default act/unsup -# 1004 fddinet-default act/unsup -# 1005 trnet-default act/unsup -# -# VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2 -# ---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------ -# 1 enet 100001 1500 - - - - - 0 0 -# 1002 fddi 101002 1500 - - - - - 0 0 -# 1003 tr 101003 1500 - - - - - 0 0 -# 1004 fdnet 101004 1500 - - - ieee - 0 0 -# 1005 trnet 101005 1500 - - - ibm - 0 0 - -""" -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: list - sample: > - The configuration returned will always be in the same format - of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: list - sample: > - The configuration returned will always be in the same format - of the parameters above. -commands: - description: The set of commands pushed to the remote device. - returned: always - type: list - sample: ['vlan 20', 'name vlan_20', 'mtu 600', 'remote-span'] -""" - - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.ios.argspec.vlans.vlans import VlansArgs -from ansible.module_utils.network.ios.config.vlans.vlans import Vlans - - -def main(): - """ - Main entry point for module execution - - :returns: the result form module invocation - """ - required_if = [('state', 'merged', ('config',)), - ('state', 'replaced', ('config',)), - ('state', 'overridden', ('config',))] - - module = AnsibleModule(argument_spec=VlansArgs.argument_spec, - required_if=required_if, - supports_check_mode=True) - - result = Vlans(module).execute_module() - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/network/ios/ios_vrf.py b/lib/ansible/modules/network/ios/ios_vrf.py deleted file mode 100644 index 1ac01e1339f..00000000000 --- a/lib/ansible/modules/network/ios/ios_vrf.py +++ /dev/null @@ -1,719 +0,0 @@ -#!/usr/bin/python -# -# 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 . -# -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'network'} - - -DOCUMENTATION = """ ---- -module: ios_vrf -version_added: "2.3" -author: "Peter Sprygada (@privateip)" -short_description: Manage the collection of VRF definitions on Cisco IOS devices -description: - - This module provides declarative management of VRF definitions on - Cisco IOS devices. It allows playbooks to manage individual or - the entire VRF collection. It also supports purging VRF definitions from - the configuration that are not explicitly defined. -extends_documentation_fragment: ios -notes: - - Tested against IOS 15.6 -options: - vrfs: - description: - - The set of VRF definition objects to be configured on the remote - IOS device. Ths list entries can either be the VRF name or a hash - of VRF definitions and attributes. This argument is mutually - exclusive with the C(name) argument. - name: - description: - - The name of the VRF definition to be managed on the remote IOS - device. The VRF definition name is an ASCII string name used - to uniquely identify the VRF. This argument is mutually exclusive - with the C(vrfs) argument - description: - description: - - Provides a short description of the VRF definition in the - current active configuration. The VRF definition value accepts - alphanumeric characters used to provide additional information - about the VRF. - rd: - description: - - The router-distinguisher value uniquely identifies the VRF to - routing processes on the remote IOS system. The RD value takes - the form of C(A:B) where C(A) and C(B) are both numeric values. - interfaces: - description: - - Identifies the set of interfaces that - should be configured in the VRF. Interfaces must be routed - interfaces in order to be placed into a VRF. - associated_interfaces: - description: - - This is a intent option and checks the operational state of the for given vrf C(name) - for associated interfaces. If the value in the C(associated_interfaces) does not match with - the operational state of vrf interfaces on device it will result in failure. - version_added: "2.5" - delay: - description: - - Time in seconds to wait before checking for the operational state on remote - device. - version_added: "2.4" - default: 10 - purge: - description: - - Instructs the module to consider the - VRF definition absolute. It will remove any previously configured - VRFs on the device. - default: false - type: bool - state: - description: - - Configures the state of the VRF definition - as it relates to the device operational configuration. When set - to I(present), the VRF should be configured in the device active - configuration and when set to I(absent) the VRF should not be - in the device active configuration - default: present - choices: ['present', 'absent'] - route_both: - description: - - Adds an export and import list of extended route target communities to the VRF. - version_added: "2.5" - route_export: - description: - - Adds an export list of extended route target communities to the VRF. - version_added: "2.5" - route_import: - description: - - Adds an import list of extended route target communities to the VRF. - version_added: "2.5" - route_both_ipv4: - description: - - Adds an export and import list of extended route target communities in address-family configuration submode to the VRF. - version_added: "2.7" - route_export_ipv4: - description: - - Adds an export list of extended route target communities in address-family configuration submode to the VRF. - version_added: "2.7" - route_import_ipv4: - description: - - Adds an import list of extended route target communities in address-family configuration submode to the VRF. - version_added: "2.7" - route_both_ipv6: - description: - - Adds an export and import list of extended route target communities in address-family configuration submode to the VRF. - version_added: "2.7" - route_export_ipv6: - description: - - Adds an export list of extended route target communities in address-family configuration submode to the VRF. - version_added: "2.7" - route_import_ipv6: - description: - - Adds an import list of extended route target communities in address-family configuration submode to the VRF. - version_added: "2.7" - -""" -EXAMPLES = """ -- name: configure a vrf named management - ios_vrf: - name: management - description: oob mgmt vrf - interfaces: - - Management1 - -- name: remove a vrf named test - ios_vrf: - name: test - state: absent - -- name: configure set of VRFs and purge any others - ios_vrf: - vrfs: - - red - - blue - - green - purge: yes - -- name: Creates a list of import RTs for the VRF with the same parameters - ios_vrf: - name: test_import - rd: 1:100 - route_import: - - 1:100 - - 3:100 - -- name: Creates a list of import RTs in address-family configuration submode for the VRF with the same parameters - ios_vrf: - name: test_import_ipv4 - rd: 1:100 - route_import_ipv4: - - 1:100 - - 3:100 - -- name: Creates a list of import RTs in address-family configuration submode for the VRF with the same parameters - ios_vrf: - name: test_import_ipv6 - rd: 1:100 - route_import_ipv6: - - 1:100 - - 3:100 - -- name: Creates a list of export RTs for the VRF with the same parameters - ios_vrf: - name: test_export - rd: 1:100 - route_export: - - 1:100 - - 3:100 - -- name: Creates a list of export RTs in address-family configuration submode for the VRF with the same parameters - ios_vrf: - name: test_export_ipv4 - rd: 1:100 - route_export_ipv4: - - 1:100 - - 3:100 - -- name: Creates a list of export RTs in address-family configuration submode for the VRF with the same parameters - ios_vrf: - name: test_export_ipv6 - rd: 1:100 - route_export_ipv6: - - 1:100 - - 3:100 - -- name: Creates a list of import and export route targets for the VRF with the same parameters - ios_vrf: - name: test_both - rd: 1:100 - route_both: - - 1:100 - - 3:100 - -- name: Creates a list of import and export route targets in address-family configuration submode for the VRF with the same parameters - ios_vrf: - name: test_both_ipv4 - rd: 1:100 - route_both_ipv4: - - 1:100 - - 3:100 - -- name: Creates a list of import and export route targets in address-family configuration submode for the VRF with the same parameters - ios_vrf: - name: test_both_ipv6 - rd: 1:100 - route_both_ipv6: - - 1:100 - - 3:100 - -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always - type: list - sample: - - vrf definition ansible - - description management vrf - - rd: 1:100 -start: - description: The time the job started - returned: always - type: str - sample: "2016-11-16 10:38:15.126146" -end: - description: The time the job ended - returned: always - type: str - sample: "2016-11-16 10:38:25.595612" -delta: - description: The time elapsed to perform all operations - returned: always - type: str - sample: "0:00:10.469466" -""" -import re -import time -from functools import partial - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.connection import exec_command -from ansible.module_utils.network.ios.ios import load_config, get_config -from ansible.module_utils.network.ios.ios import ios_argument_spec -from ansible.module_utils.network.common.config import NetworkConfig -from ansible.module_utils.six import iteritems - - -def get_interface_type(interface): - - if interface.upper().startswith('ET'): - return 'ethernet' - elif interface.upper().startswith('VL'): - return 'svi' - elif interface.upper().startswith('LO'): - return 'loopback' - elif interface.upper().startswith('MG'): - return 'management' - elif interface.upper().startswith('MA'): - return 'management' - elif interface.upper().startswith('PO'): - return 'portchannel' - elif interface.upper().startswith('NV'): - return 'nve' - else: - return 'unknown' - - -def add_command_to_vrf(name, cmd, commands): - if 'vrf definition %s' % name not in commands: - commands.extend(['vrf definition %s' % name]) - commands.append(cmd) - - -def map_obj_to_commands(updates, module): - commands = list() - - for update in updates: - want, have = update - - def needs_update(want, have, x): - if isinstance(want.get(x), list) and isinstance(have.get(x), list): - return want.get(x) and (want.get(x) != have.get(x)) and not all(elem in have.get(x) for elem in want.get(x)) - return want.get(x) and (want.get(x) != have.get(x)) - - if want['state'] == 'absent': - commands.append('no vrf definition %s' % want['name']) - continue - - if not have.get('state'): - commands.extend(['vrf definition %s' % want['name']]) - ipv6 = len([k for k, v in module.params.items() if (k.endswith('_ipv6') or k.endswith('_both')) and v]) != 0 - ipv4 = len([k for k, v in module.params.items() if (k.endswith('_ipv4') or k.endswith('_both')) and v]) != 0 - if ipv4: - commands.extend(['address-family ipv4', 'exit']) - if ipv6: - commands.extend(['address-family ipv6', 'exit']) - - if needs_update(want, have, 'description'): - cmd = 'description %s' % want['description'] - add_command_to_vrf(want['name'], cmd, commands) - - if needs_update(want, have, 'rd'): - cmd = 'rd %s' % want['rd'] - add_command_to_vrf(want['name'], cmd, commands) - - if needs_update(want, have, 'route_import'): - for route in want['route_import']: - cmd = 'route-target import %s' % route - add_command_to_vrf(want['name'], cmd, commands) - - if needs_update(want, have, 'route_export'): - for route in want['route_export']: - cmd = 'route-target export %s' % route - add_command_to_vrf(want['name'], cmd, commands) - - if needs_update(want, have, 'route_import_ipv4'): - cmd = 'address-family ipv4' - add_command_to_vrf(want['name'], cmd, commands) - for route in want['route_import_ipv4']: - cmd = 'route-target import %s' % route - add_command_to_vrf(want['name'], cmd, commands) - cmd = 'exit-address-family' - add_command_to_vrf(want['name'], cmd, commands) - - if needs_update(want, have, 'route_export_ipv4'): - cmd = 'address-family ipv4' - add_command_to_vrf(want['name'], cmd, commands) - for route in want['route_export_ipv4']: - cmd = 'route-target export %s' % route - add_command_to_vrf(want['name'], cmd, commands) - cmd = 'exit-address-family' - add_command_to_vrf(want['name'], cmd, commands) - - if needs_update(want, have, 'route_import_ipv6'): - cmd = 'address-family ipv6' - add_command_to_vrf(want['name'], cmd, commands) - for route in want['route_import_ipv6']: - cmd = 'route-target import %s' % route - add_command_to_vrf(want['name'], cmd, commands) - cmd = 'exit-address-family' - add_command_to_vrf(want['name'], cmd, commands) - - if needs_update(want, have, 'route_export_ipv6'): - cmd = 'address-family ipv6' - add_command_to_vrf(want['name'], cmd, commands) - for route in want['route_export_ipv6']: - cmd = 'route-target export %s' % route - add_command_to_vrf(want['name'], cmd, commands) - cmd = 'exit-address-family' - add_command_to_vrf(want['name'], cmd, commands) - - if want['interfaces'] is not None: - # handle the deletes - for intf in set(have.get('interfaces', [])).difference(want['interfaces']): - commands.extend(['interface %s' % intf, - 'no vrf forwarding %s' % want['name']]) - - # handle the adds - for intf in set(want['interfaces']).difference(have.get('interfaces', [])): - cfg = get_config(module) - configobj = NetworkConfig(indent=1, contents=cfg) - children = configobj['interface %s' % intf].children - intf_config = '\n'.join(children) - - commands.extend(['interface %s' % intf, - 'vrf forwarding %s' % want['name']]) - - match = re.search('ip address .+', intf_config, re.M) - if match: - commands.append(match.group()) - - return commands - - -def parse_description(configobj, name): - cfg = configobj['vrf definition %s' % name] - cfg = '\n'.join(cfg.children) - match = re.search(r'description (.+)$', cfg, re.M) - if match: - return match.group(1) - - -def parse_rd(configobj, name): - cfg = configobj['vrf definition %s' % name] - cfg = '\n'.join(cfg.children) - match = re.search(r'rd (.+)$', cfg, re.M) - if match: - return match.group(1) - - -def parse_interfaces(configobj): - vrf_cfg = 'vrf forwarding' - interfaces = dict() - for intf in set(re.findall('^interface .+', str(configobj), re.M)): - for line in configobj[intf].children: - if vrf_cfg in line: - try: - interfaces[line.split()[-1]].append(intf.split(' ')[1]) - except KeyError: - interfaces[line.split()[-1]] = [intf.split(' ')[1]] - return interfaces - - -def parse_import(configobj, name): - cfg = configobj['vrf definition %s' % name] - cfg = '\n'.join(cfg.children) - matches = re.findall(r'route-target\s+import\s+(.+)', cfg, re.M) - return matches - - -def parse_export(configobj, name): - cfg = configobj['vrf definition %s' % name] - cfg = '\n'.join(cfg.children) - matches = re.findall(r'route-target\s+export\s+(.+)', cfg, re.M) - return matches - - -def parse_both(configobj, name, address_family='global'): - rd_pattern = re.compile('(?P.+:.+)') - matches = list() - export_match = None - import_match = None - if address_family == "global": - export_match = parse_export(configobj, name) - import_match = parse_import(configobj, name) - elif address_family == "ipv4": - export_match = parse_export_ipv4(configobj, name) - import_match = parse_import_ipv4(configobj, name) - elif address_family == "ipv6": - export_match = parse_export_ipv6(configobj, name) - import_match = parse_import_ipv6(configobj, name) - if import_match and export_match: - for ex in export_match: - exrd = rd_pattern.search(ex) - exrd = exrd.groupdict().get('rd') - for im in import_match: - imrd = rd_pattern.search(im) - imrd = imrd.groupdict().get('rd') - if exrd == imrd: - matches.extend([exrd]) if exrd not in matches else None - matches.extend([imrd]) if imrd not in matches else None - return matches - - -def parse_import_ipv4(configobj, name): - cfg = configobj['vrf definition %s' % name] - try: - subcfg = cfg['address-family ipv4'] - subcfg = '\n'.join(subcfg.children) - matches = re.findall(r'route-target\s+import\s+(.+)', subcfg, re.M) - return matches - except KeyError: - pass - - -def parse_export_ipv4(configobj, name): - cfg = configobj['vrf definition %s' % name] - try: - subcfg = cfg['address-family ipv4'] - subcfg = '\n'.join(subcfg.children) - matches = re.findall(r'route-target\s+export\s+(.+)', subcfg, re.M) - return matches - except KeyError: - pass - - -def parse_import_ipv6(configobj, name): - cfg = configobj['vrf definition %s' % name] - try: - subcfg = cfg['address-family ipv6'] - subcfg = '\n'.join(subcfg.children) - matches = re.findall(r'route-target\s+import\s+(.+)', subcfg, re.M) - return matches - except KeyError: - pass - - -def parse_export_ipv6(configobj, name): - cfg = configobj['vrf definition %s' % name] - try: - subcfg = cfg['address-family ipv6'] - subcfg = '\n'.join(subcfg.children) - matches = re.findall(r'route-target\s+export\s+(.+)', subcfg, re.M) - return matches - except KeyError: - pass - - -def map_config_to_obj(module): - config = get_config(module) - configobj = NetworkConfig(indent=1, contents=config) - match = re.findall(r'^vrf definition (\S+)', config, re.M) - if not match: - return list() - - instances = list() - - interfaces = parse_interfaces(configobj) - - for item in set(match): - obj = { - 'name': item, - 'state': 'present', - 'description': parse_description(configobj, item), - 'rd': parse_rd(configobj, item), - 'interfaces': interfaces.get(item), - 'route_import': parse_import(configobj, item), - 'route_export': parse_export(configobj, item), - 'route_both': parse_both(configobj, item), - 'route_import_ipv4': parse_import_ipv4(configobj, item), - 'route_export_ipv4': parse_export_ipv4(configobj, item), - 'route_both_ipv4': parse_both(configobj, item, address_family='ipv4'), - 'route_import_ipv6': parse_import_ipv6(configobj, item), - 'route_export_ipv6': parse_export_ipv6(configobj, item), - 'route_both_ipv6': parse_both(configobj, item, address_family='ipv6'), - } - instances.append(obj) - return instances - - -def get_param_value(key, item, module): - # if key doesn't exist in the item, get it from module.params - if not item.get(key): - value = module.params[key] - - # if key does exist, do a type check on it to validate it - else: - value_type = module.argument_spec[key].get('type', 'str') - type_checker = module._CHECK_ARGUMENT_TYPES_DISPATCHER[value_type] - type_checker(item[key]) - value = item[key] - - # validate the param value (if validator func exists) - validator = globals().get('validate_%s' % key) - if validator: - validator(value, module) - - return value - - -def map_params_to_obj(module): - vrfs = module.params.get('vrfs') - if not vrfs: - if not module.params['name'] and module.params['purge']: - return list() - elif not module.params['name']: - module.fail_json(msg='name is required') - collection = [{'name': module.params['name']}] - else: - collection = list() - for item in vrfs: - if not isinstance(item, dict): - collection.append({'name': item}) - elif 'name' not in item: - module.fail_json(msg='name is required') - else: - collection.append(item) - - objects = list() - for item in collection: - get_value = partial(get_param_value, item=item, module=module) - item['description'] = get_value('description') - item['rd'] = get_value('rd') - item['interfaces'] = get_value('interfaces') - item['state'] = get_value('state') - item['route_import'] = get_value('route_import') - item['route_export'] = get_value('route_export') - item['route_both'] = get_value('route_both') - item['route_import_ipv4'] = get_value('route_import_ipv4') - item['route_export_ipv4'] = get_value('route_export_ipv4') - item['route_both_ipv4'] = get_value('route_both_ipv4') - item['route_import_ipv6'] = get_value('route_import_ipv6') - item['route_export_ipv6'] = get_value('route_export_ipv6') - item['route_both_ipv6'] = get_value('route_both_ipv6') - both_addresses_family = ["", "_ipv6", "_ipv4"] - for address_family in both_addresses_family: - if item["route_both%s" % address_family]: - if not item["route_export%s" % address_family]: - item["route_export%s" % address_family] = list() - if not item["route_import%s" % address_family]: - item["route_import%s" % address_family] = list() - item["route_export%s" % address_family].extend(get_value("route_both%s" % address_family)) - item["route_import%s" % address_family].extend(get_value("route_both%s" % address_family)) - item['associated_interfaces'] = get_value('associated_interfaces') - objects.append(item) - - return objects - - -def update_objects(want, have): - updates = list() - for entry in want: - item = next((i for i in have if i['name'] == entry['name']), None) - if all((item is None, entry['state'] == 'present')): - updates.append((entry, {})) - else: - for key, value in iteritems(entry): - if value: - try: - if isinstance(value, list): - if sorted(value) != sorted(item[key]): - if (entry, item) not in updates: - updates.append((entry, item)) - elif value != item[key]: - if (entry, item) not in updates: - updates.append((entry, item)) - except TypeError: - pass - return updates - - -def check_declarative_intent_params(want, module, result): - if module.params['associated_interfaces']: - - if result['changed']: - time.sleep(module.params['delay']) - - name = module.params['name'] - rc, out, err = exec_command(module, 'show vrf | include {0}'.format(name)) - - if rc == 0: - data = out.strip().split() - # data will be empty if the vrf was just added - if not data: - return - vrf = data[0] - interface = data[-1] - - for w in want: - if w['name'] == vrf: - if w.get('associated_interfaces') is None: - continue - for i in w['associated_interfaces']: - if get_interface_type(i) is not get_interface_type(interface): - module.fail_json(msg="Interface %s not configured on vrf %s" % (interface, name)) - - -def main(): - """ main entry point for module execution - """ - argument_spec = dict( - vrfs=dict(type='list'), - - name=dict(), - description=dict(), - rd=dict(), - route_export=dict(type='list'), - route_import=dict(type='list'), - route_both=dict(type='list'), - route_export_ipv4=dict(type='list'), - route_import_ipv4=dict(type='list'), - route_both_ipv4=dict(type='list'), - route_export_ipv6=dict(type='list'), - route_import_ipv6=dict(type='list'), - route_both_ipv6=dict(type='list'), - - - interfaces=dict(type='list'), - associated_interfaces=dict(type='list'), - - delay=dict(default=10, type='int'), - purge=dict(type='bool', default=False), - state=dict(default='present', choices=['present', 'absent']) - ) - - argument_spec.update(ios_argument_spec) - - mutually_exclusive = [('name', 'vrfs')] - module = AnsibleModule(argument_spec=argument_spec, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True) - - result = {'changed': False} - - warnings = list() - result['warnings'] = warnings - - want = map_params_to_obj(module) - have = map_config_to_obj(module) - commands = map_obj_to_commands(update_objects(want, have), module) - - if module.params['purge']: - want_vrfs = [x['name'] for x in want] - have_vrfs = [x['name'] for x in have] - for item in set(have_vrfs).difference(want_vrfs): - cmd = 'no vrf definition %s' % item - if cmd not in commands: - commands.append(cmd) - - result['commands'] = commands - - if commands: - if not module.check_mode: - load_config(module, commands) - result['changed'] = True - - check_declarative_intent_params(want, module, result) - - module.exit_json(**result) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/plugins/action/ios.py b/lib/ansible/plugins/action/ios.py deleted file mode 100644 index 5ab0c602873..00000000000 --- a/lib/ansible/plugins/action/ios.py +++ /dev/null @@ -1,95 +0,0 @@ -# -# (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 . -# -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import sys -import copy - -from ansible.plugins.action.network import ActionModule as ActionNetworkModule -from ansible.module_utils.network.common.utils import load_provider -from ansible.module_utils.network.ios.ios import ios_provider_spec -from ansible.utils.display import Display - -display = Display() - - -class ActionModule(ActionNetworkModule): - - def run(self, tmp=None, task_vars=None): - del tmp # tmp no longer has any effect - - module_name = self._task.action.split('.')[-1] - self._config_module = True if module_name == 'ios_config' else False - persistent_connection = self._play_context.connection.split('.')[-1] - warnings = [] - - if persistent_connection == 'network_cli': - provider = self._task.args.get('provider', {}) - if any(provider.values()): - display.warning('provider is unnecessary when using network_cli and will be ignored') - del self._task.args['provider'] - elif self._play_context.connection == 'local': - provider = load_provider(ios_provider_spec, self._task.args) - pc = copy.deepcopy(self._play_context) - pc.connection = 'ansible.netcommon.network_cli' - pc.network_os = 'cisco.ios.ios' - pc.remote_addr = provider['host'] or self._play_context.remote_addr - pc.port = int(provider['port'] or self._play_context.port or 22) - pc.remote_user = provider['username'] or self._play_context.connection_user - pc.password = provider['password'] or self._play_context.password - pc.private_key_file = provider['ssh_keyfile'] or self._play_context.private_key_file - pc.become = provider['authorize'] or False - if pc.become: - pc.become_method = 'enable' - pc.become_pass = provider['auth_pass'] - - connection = self._shared_loader_obj.connection_loader.get('ansible.netcommon.persistent', pc, sys.stdin, - task_uuid=self._task._uuid) - - # TODO: Remove below code after ansible minimal is cut out - if connection is None: - pc.connection = 'network_cli' - pc.network_os = 'ios' - connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin, task_uuid=self._task._uuid) - - display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr) - - command_timeout = int(provider['timeout']) if provider['timeout'] else connection.get_option('persistent_command_timeout') - connection.set_options(direct={'persistent_command_timeout': command_timeout}) - - socket_path = connection.run() - display.vvvv('socket_path: %s' % socket_path, pc.remote_addr) - if not socket_path: - return {'failed': True, - 'msg': 'unable to open shell. Please see: ' + - 'https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell'} - - task_vars['ansible_socket'] = socket_path - warnings.append(['connection local support for this module is deprecated and will be removed in version 2.14, use connection %s' % pc.connection]) - else: - return {'failed': True, 'msg': 'Connection type %s is not valid for this module' % self._play_context.connection} - - result = super(ActionModule, self).run(task_vars=task_vars) - if warnings: - if 'warnings' in result: - result['warnings'].extend(warnings) - else: - result['warnings'] = warnings - return result diff --git a/lib/ansible/plugins/cliconf/ios.py b/lib/ansible/plugins/cliconf/ios.py deleted file mode 100644 index c057a8386ce..00000000000 --- a/lib/ansible/plugins/cliconf/ios.py +++ /dev/null @@ -1,387 +0,0 @@ -# -# (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 . -# -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -DOCUMENTATION = """ ---- -author: Ansible Networking Team -cliconf: ios -short_description: Use ios cliconf to run command on Cisco IOS platform -description: - - This ios plugin provides low level abstraction apis for - sending and receiving CLI commands from Cisco IOS network devices. -version_added: "2.4" -""" - -import re -import time -import json - -from ansible.errors import AnsibleConnectionFailure -from ansible.module_utils._text import to_text -from ansible.module_utils.common._collections_compat import Mapping -from ansible.module_utils.six import iteritems -from ansible.module_utils.network.common.config import NetworkConfig, dumps -from ansible.module_utils.network.common.utils import to_list -from ansible.plugins.cliconf import CliconfBase, enable_mode - - -class Cliconf(CliconfBase): - - @enable_mode - def get_config(self, source='running', flags=None, format=None): - if source not in ('running', 'startup'): - raise ValueError("fetching configuration from %s is not supported" % source) - - if format: - raise ValueError("'format' value %s is not supported for get_config" % format) - - if not flags: - flags = [] - if source == 'running': - cmd = 'show running-config ' - else: - cmd = 'show startup-config ' - - cmd += ' '.join(to_list(flags)) - cmd = cmd.strip() - - return self.send_command(cmd) - - def get_diff(self, candidate=None, running=None, diff_match='line', diff_ignore_lines=None, path=None, diff_replace='line'): - """ - Generate diff between candidate and running configuration. If the - remote host supports onbox diff capabilities ie. supports_onbox_diff in that case - candidate and running configurations are not required to be passed as argument. - In case if onbox diff capability is not supported candidate argument is mandatory - and running argument is optional. - :param candidate: The configuration which is expected to be present on remote host. - :param running: The base configuration which is used to generate diff. - :param diff_match: Instructs how to match the candidate configuration with current device configuration - Valid values are 'line', 'strict', 'exact', 'none'. - 'line' - commands are matched line by line - 'strict' - command lines are matched with respect to position - 'exact' - command lines must be an equal match - 'none' - will not compare the candidate configuration with the running configuration - :param diff_ignore_lines: Use this argument to specify one or more lines that should be - ignored during the diff. This is used for lines in the configuration - that are automatically updated by the system. This argument takes - a list of regular expressions or exact line matches. - :param path: The ordered set of parents that uniquely identify the section or hierarchy - the commands should be checked against. If the parents argument - is omitted, the commands are checked against the set of top - level or global commands. - :param diff_replace: Instructs on the way to perform the configuration on the device. - If the replace argument is set to I(line) then the modified lines are - pushed to the device in configuration mode. If the replace argument is - set to I(block) then the entire command block is pushed to the device in - configuration mode if any line is not correct. - :return: Configuration diff in json format. - { - 'config_diff': '', - 'banner_diff': {} - } - - """ - diff = {} - device_operations = self.get_device_operations() - option_values = self.get_option_values() - - if candidate is None and device_operations['supports_generate_diff']: - raise ValueError("candidate configuration is required to generate diff") - - if diff_match not in option_values['diff_match']: - raise ValueError("'match' value %s in invalid, valid values are %s" % (diff_match, ', '.join(option_values['diff_match']))) - - if diff_replace not in option_values['diff_replace']: - raise ValueError("'replace' value %s in invalid, valid values are %s" % (diff_replace, ', '.join(option_values['diff_replace']))) - - # prepare candidate configuration - candidate_obj = NetworkConfig(indent=1) - want_src, want_banners = self._extract_banners(candidate) - candidate_obj.load(want_src) - - if running and diff_match != 'none': - # running configuration - have_src, have_banners = self._extract_banners(running) - running_obj = NetworkConfig(indent=1, contents=have_src, ignore_lines=diff_ignore_lines) - configdiffobjs = candidate_obj.difference(running_obj, path=path, match=diff_match, replace=diff_replace) - - else: - configdiffobjs = candidate_obj.items - have_banners = {} - - diff['config_diff'] = dumps(configdiffobjs, 'commands') if configdiffobjs else '' - banners = self._diff_banners(want_banners, have_banners) - diff['banner_diff'] = banners if banners else {} - return diff - - @enable_mode - def edit_config(self, candidate=None, commit=True, replace=None, comment=None): - resp = {} - operations = self.get_device_operations() - self.check_edit_config_capability(operations, candidate, commit, replace, comment) - - results = [] - requests = [] - if commit: - self.send_command('configure terminal') - for line in to_list(candidate): - if not isinstance(line, Mapping): - line = {'command': line} - - cmd = line['command'] - if cmd != 'end' and cmd[0] != '!': - results.append(self.send_command(**line)) - requests.append(cmd) - - self.send_command('end') - else: - raise ValueError('check mode is not supported') - - resp['request'] = requests - resp['response'] = results - return resp - - def edit_macro(self, candidate=None, commit=True, replace=None, comment=None): - """ - ios_config: - lines: "{{ macro_lines }}" - parents: "macro name {{ macro_name }}" - after: '@' - match: line - replace: block - """ - resp = {} - operations = self.get_device_operations() - self.check_edit_config_capability(operations, candidate, commit, replace, comment) - - results = [] - requests = [] - if commit: - commands = '' - self.send_command('config terminal') - time.sleep(0.1) - # first item: macro command - commands += (candidate.pop(0) + '\n') - multiline_delimiter = candidate.pop(-1) - for line in candidate: - commands += (' ' + line + '\n') - commands += (multiline_delimiter + '\n') - obj = {'command': commands, 'sendonly': True} - results.append(self.send_command(**obj)) - requests.append(commands) - - time.sleep(0.1) - self.send_command('end', sendonly=True) - time.sleep(0.1) - results.append(self.send_command('\n')) - requests.append('\n') - - resp['request'] = requests - resp['response'] = results - return resp - - def get(self, command=None, prompt=None, answer=None, sendonly=False, output=None, newline=True, check_all=False): - if not command: - raise ValueError('must provide value of command to execute') - if output: - raise ValueError("'output' value %s is not supported for get" % output) - - return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, newline=newline, check_all=check_all) - - def get_device_info(self): - device_info = {} - - device_info['network_os'] = 'ios' - reply = self.get(command='show version') - data = to_text(reply, errors='surrogate_or_strict').strip() - - match = re.search(r'Version (\S+)', data) - if match: - device_info['network_os_version'] = match.group(1).strip(',') - - model_search_strs = [r'^[Cc]isco (.+) \(revision', r'^[Cc]isco (\S+).+bytes of .*memory'] - for item in model_search_strs: - match = re.search(item, data, re.M) - if match: - version = match.group(1).split(' ') - device_info['network_os_model'] = version[0] - break - - match = re.search(r'^(.+) uptime', data, re.M) - if match: - device_info['network_os_hostname'] = match.group(1) - - match = re.search(r'image file is "(.+)"', data) - if match: - device_info['network_os_image'] = match.group(1) - - return device_info - - def get_device_operations(self): - return { - 'supports_diff_replace': True, - 'supports_commit': False, - 'supports_rollback': False, - 'supports_defaults': True, - 'supports_onbox_diff': False, - 'supports_commit_comment': False, - 'supports_multiline_delimiter': True, - 'supports_diff_match': True, - 'supports_diff_ignore_lines': True, - 'supports_generate_diff': True, - 'supports_replace': False - } - - def get_option_values(self): - return { - 'format': ['text'], - 'diff_match': ['line', 'strict', 'exact', 'none'], - 'diff_replace': ['line', 'block'], - 'output': [] - } - - def get_capabilities(self): - result = super(Cliconf, self).get_capabilities() - result['rpc'] += ['edit_banner', 'get_diff', 'run_commands', 'get_defaults_flag'] - result['device_operations'] = self.get_device_operations() - result.update(self.get_option_values()) - return json.dumps(result) - - def edit_banner(self, candidate=None, multiline_delimiter="@", commit=True): - """ - Edit banner on remote device - :param banners: Banners to be loaded in json format - :param multiline_delimiter: Line delimiter for banner - :param commit: Boolean value that indicates if the device candidate - configuration should be pushed in the running configuration or discarded. - :param diff: Boolean flag to indicate if configuration that is applied on remote host should - generated and returned in response or not - :return: Returns response of executing the configuration command received - from remote host - """ - resp = {} - banners_obj = json.loads(candidate) - results = [] - requests = [] - if commit: - for key, value in iteritems(banners_obj): - key += ' %s' % multiline_delimiter - self.send_command('config terminal', sendonly=True) - for cmd in [key, value, multiline_delimiter]: - obj = {'command': cmd, 'sendonly': True} - results.append(self.send_command(**obj)) - requests.append(cmd) - - self.send_command('end', sendonly=True) - time.sleep(0.1) - results.append(self.send_command('\n')) - requests.append('\n') - - resp['request'] = requests - resp['response'] = results - - return resp - - def run_commands(self, commands=None, check_rc=True): - if commands is None: - raise ValueError("'commands' value is required") - - responses = list() - for cmd in to_list(commands): - if not isinstance(cmd, Mapping): - cmd = {'command': cmd} - - output = cmd.pop('output', None) - if output: - raise ValueError("'output' value %s is not supported for run_commands" % output) - - try: - out = self.send_command(**cmd) - except AnsibleConnectionFailure as e: - if check_rc: - raise - out = getattr(e, 'err', to_text(e)) - - responses.append(out) - - return responses - - def get_defaults_flag(self): - """ - The method identifies the filter that should be used to fetch running-configuration - with defaults. - :return: valid default filter - """ - out = self.get('show running-config ?') - out = to_text(out, errors='surrogate_then_replace') - - commands = set() - for line in out.splitlines(): - if line.strip(): - commands.add(line.strip().split()[0]) - - if 'all' in commands: - return 'all' - else: - return 'full' - - def set_cli_prompt_context(self): - """ - Make sure we are in the operational cli mode - :return: None - """ - if self._connection.connected: - out = self._connection.get_prompt() - - if out is None: - raise AnsibleConnectionFailure(message=u'cli prompt is not identified from the last received' - u' response window: %s' % self._connection._last_recv_window) - - if re.search(r'config.*\)#', to_text(out, errors='surrogate_then_replace').strip()): - self._connection.queue_message('vvvv', 'wrong context, sending end to device') - self._connection.send_command('end') - - def _extract_banners(self, config): - banners = {} - banner_cmds = re.findall(r'^banner (\w+)', config, re.M) - for cmd in banner_cmds: - regex = r'banner %s \^C(.+?)(?=\^C)' % cmd - match = re.search(regex, config, re.S) - if match: - key = 'banner %s' % cmd - banners[key] = match.group(1).strip() - - for cmd in banner_cmds: - regex = r'banner %s \^C(.+?)(?=\^C)' % cmd - match = re.search(regex, config, re.S) - if match: - config = config.replace(str(match.group(1)), '') - - config = re.sub(r'banner \w+ \^C\^C', '!! banner removed', config) - return config, banners - - def _diff_banners(self, want, have): - candidate = {} - for key, value in iteritems(want): - if value != have.get(key): - candidate[key] = value - return candidate diff --git a/lib/ansible/plugins/doc_fragments/ios.py b/lib/ansible/plugins/doc_fragments/ios.py deleted file mode 100644 index 49e723516ef..00000000000 --- a/lib/ansible/plugins/doc_fragments/ios.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Peter Sprygada -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -class ModuleDocFragment(object): - - # Standard files documentation fragment - DOCUMENTATION = r''' -options: - provider: - description: - - B(Deprecated) - - "Starting with Ansible 2.5 we recommend using C(connection: network_cli)." - - For more information please see the L(IOS Platform Options guide, ../network/user_guide/platform_ios.html). - - HORIZONTALLINE - - A dict object containing connection details. - type: dict - suboptions: - host: - description: - - Specifies the DNS host name or address for connecting to the remote - device over the specified transport. The value of host is used as - the destination address for the transport. - type: str - required: true - port: - description: - - Specifies the port to use when building the connection to the remote device. - type: int - default: 22 - username: - description: - - Configures the username to use to authenticate the connection to - the remote device. This value is used to authenticate - the SSH session. If the value is not specified in the task, the - value of environment variable C(ANSIBLE_NET_USERNAME) will be used instead. - type: str - password: - description: - - Specifies the password to use to authenticate the connection to - the remote device. This value is used to authenticate - the SSH session. If the value is not specified in the task, the - value of environment variable C(ANSIBLE_NET_PASSWORD) will be used instead. - type: str - timeout: - description: - - Specifies the timeout in seconds for communicating with the network device - for either connecting or sending commands. If the timeout is - exceeded before the operation is completed, the module will error. - type: int - default: 10 - ssh_keyfile: - description: - - Specifies the SSH key to use to authenticate the connection to - the remote device. This value is the path to the - key used to authenticate the SSH session. If the value is not specified - in the task, the value of environment variable C(ANSIBLE_NET_SSH_KEYFILE) - will be used instead. - type: path - authorize: - description: - - Instructs the module to enter privileged mode on the remote device - before sending any commands. If not specified, the device will - attempt to execute all commands in non-privileged mode. If the value - is not specified in the task, the value of environment variable - C(ANSIBLE_NET_AUTHORIZE) will be used instead. - type: bool - default: no - auth_pass: - description: - - Specifies the password to use if required to enter privileged mode - on the remote device. If I(authorize) is false, then this argument - does nothing. If the value is not specified in the task, the value of - environment variable C(ANSIBLE_NET_AUTH_PASS) will be used instead. - type: str -notes: - - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` - - For more information on using Ansible to manage Cisco devices see the `Cisco integration page `_. -''' diff --git a/lib/ansible/plugins/terminal/ios.py b/lib/ansible/plugins/terminal/ios.py deleted file mode 100644 index d7973577380..00000000000 --- a/lib/ansible/plugins/terminal/ios.py +++ /dev/null @@ -1,102 +0,0 @@ -# -# (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 . -# -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import json -import re - -from ansible.errors import AnsibleConnectionFailure -from ansible.module_utils._text import to_text, to_bytes -from ansible.plugins.terminal import TerminalBase -from ansible.utils.display import Display - -display = Display() - - -class TerminalModule(TerminalBase): - - terminal_stdout_re = [ - re.compile(br"[\r\n]?[\w\+\-\.:\/\[\]]+(?:\([^\)]+\)){0,3}(?:[>#]) ?$") - ] - - terminal_stderr_re = [ - re.compile(br"% ?Error"), - # re.compile(br"^% \w+", re.M), - re.compile(br"% ?Bad secret"), - re.compile(br"[\r\n%] Bad passwords"), - re.compile(br"invalid input", re.I), - re.compile(br"(?:incomplete|ambiguous) command", re.I), - re.compile(br"connection timed out", re.I), - re.compile(br"[^\r\n]+ not found"), - re.compile(br"'[^']' +returned error code: ?\d+"), - re.compile(br"Bad mask", re.I), - re.compile(br"% ?(\S+) ?overlaps with ?(\S+)", re.I), - re.compile(br"[%\S] ?Error: ?[\s]+", re.I), - re.compile(br"[%\S] ?Informational: ?[\s]+", re.I), - re.compile(br"Command authorization failed") - ] - - def on_open_shell(self): - try: - self._exec_cli_command(b'terminal length 0') - except AnsibleConnectionFailure: - raise AnsibleConnectionFailure('unable to set terminal parameters') - - try: - self._exec_cli_command(b'terminal width 512') - try: - self._exec_cli_command(b'terminal width 0') - except AnsibleConnectionFailure: - pass - except AnsibleConnectionFailure: - display.display('WARNING: Unable to set terminal width, command responses may be truncated') - - def on_become(self, passwd=None): - if self._get_prompt().endswith(b'#'): - return - - cmd = {u'command': u'enable'} - if passwd: - # Note: python-3.5 cannot combine u"" and r"" together. Thus make - # an r string and use to_text to ensure it's text on both py2 and py3. - cmd[u'prompt'] = to_text(r"[\r\n]?(?:.*)?[Pp]assword: ?$", errors='surrogate_or_strict') - cmd[u'answer'] = passwd - cmd[u'prompt_retry_check'] = True - try: - self._exec_cli_command(to_bytes(json.dumps(cmd), errors='surrogate_or_strict')) - prompt = self._get_prompt() - if prompt is None or not prompt.endswith(b'#'): - raise AnsibleConnectionFailure('failed to elevate privilege to enable mode still at prompt [%s]' % prompt) - except AnsibleConnectionFailure as e: - prompt = self._get_prompt() - raise AnsibleConnectionFailure('unable to elevate privilege to enable mode, at prompt [%s] with error: %s' % (prompt, e.message)) - - def on_unbecome(self): - prompt = self._get_prompt() - if prompt is None: - # if prompt is None most likely the terminal is hung up at a prompt - return - - if b'(config' in prompt: - self._exec_cli_command(b'end') - self._exec_cli_command(b'disable') - - elif prompt.endswith(b'#'): - self._exec_cli_command(b'disable') diff --git a/test/integration/targets/ios_acl_interfaces/defaults/main.yaml b/test/integration/targets/ios_acl_interfaces/defaults/main.yaml deleted file mode 100644 index 164afead284..00000000000 --- a/test/integration/targets/ios_acl_interfaces/defaults/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -testcase: "[^_].*" -test_items: [] diff --git a/test/integration/targets/ios_acl_interfaces/tasks/cli.yaml b/test/integration/targets/ios_acl_interfaces/tasks/cli.yaml deleted file mode 100644 index 242420aa7f5..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tasks/cli.yaml +++ /dev/null @@ -1,21 +0,0 @@ ---- -- name: Collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - use_regex: true - register: test_cases - delegate_to: localhost - -- name: Set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - delegate_to: localhost - -- name: Run test case (connection=network_cli) - include: "{{ test_case_to_run }}" - vars: - ansible_connection: network_cli - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli diff --git a/test/integration/targets/ios_acl_interfaces/tasks/main.yaml b/test/integration/targets/ios_acl_interfaces/tasks/main.yaml deleted file mode 100644 index 415c99d8b12..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/ios_acl_interfaces/tests/cli/_parsed.cfg b/test/integration/targets/ios_acl_interfaces/tests/cli/_parsed.cfg deleted file mode 100644 index 1462c135300..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tests/cli/_parsed.cfg +++ /dev/null @@ -1,8 +0,0 @@ -interface GigabitEthernet0/1 -ip access-group 110 in -ip access-group 123 out -ipv6 traffic-filter temp_v6 in -ipv6 traffic-filter test_v6 out -interface GigabitEthernet0/2 -ip access-group 110 in -ip access-group 123 out diff --git a/test/integration/targets/ios_acl_interfaces/tests/cli/_populate_config.yaml b/test/integration/targets/ios_acl_interfaces/tests/cli/_populate_config.yaml deleted file mode 100644 index 68ee0265f2c..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tests/cli/_populate_config.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -- name: Populate Config - cli_config: - config: "{{ lines }}" - vars: - lines: | - interface GigabitEthernet 0/1 - ip access-group 110 in - ip access-group 123 out - ipv6 traffic-filter temp_v6 in - ipv6 traffic-filter test_v6 out - interface GigabitEthernet 0/2 - ip access-group 110 in - ip access-group 123 out diff --git a/test/integration/targets/ios_acl_interfaces/tests/cli/_remove_config.yaml b/test/integration/targets/ios_acl_interfaces/tests/cli/_remove_config.yaml deleted file mode 100644 index 9560e2bbf7c..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tests/cli/_remove_config.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: Remove Config - cli_config: - config: "{{ lines }}" - vars: - lines: | - interface GigabitEthernet 0/1 - no ip access-group 110 in - no ip access-group 100 out - no ip access-group 123 out - no ipv6 traffic-filter temp_v6 in - no ipv6 traffic-filter test_v6 out - interface GigabitEthernet 0/2 - no ip access-group 110 in - no ip access-group 123 out diff --git a/test/integration/targets/ios_acl_interfaces/tests/cli/deleted.yaml b/test/integration/targets/ios_acl_interfaces/tests/cli/deleted.yaml deleted file mode 100644 index c101b6b8fa4..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tests/cli/deleted.yaml +++ /dev/null @@ -1,65 +0,0 @@ ---- -- debug: - msg: "Start ios_acl_interfaces deleted integration tests ansible_connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml -- include_tasks: _populate_config.yaml - -- block: - - - name: Delete module attributes of given Interface based on AFI - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv6 - state: deleted - register: result - - - assert: - that: - - "result.commands|length == 3" - - "result.changed == true" - - "'no ipv6 traffic-filter temp_v6 in' in result.commands" - - "'no ipv6 traffic-filter test_v6 out' in result.commands" - - - name: Delete module attributes of given Interface based on AFI (IDEMPOTENT) - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv6 - state: deleted - register: result - - - assert: - that: - - "result.changed == false" - - - name: Delete module attributes of given Interface. - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - state: deleted - register: result - - - assert: - that: - - "result.commands|length == 3" - - "result.changed == true" - - "'no ip access-group 110 in' in result.commands" - - "'no ip access-group 123 out' in result.commands" - - - name: Delete module attributes of given Interface (IDEMPOTENT) - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - state: deleted - register: result - - - assert: - that: - - "result.changed == false" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_acl_interfaces/tests/cli/empty_config.yaml b/test/integration/targets/ios_acl_interfaces/tests/cli/empty_config.yaml deleted file mode 100644 index 85e3bdf7aab..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tests/cli/empty_config.yaml +++ /dev/null @@ -1,58 +0,0 @@ ---- -- debug: - msg: "START ios_acl_interfaces empty_config.yaml integration tests on connection={{ ansible_connection }}" - -- name: Merged with empty config should give appropriate error message - ios_acl_interfaces: - config: - state: merged - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state merged' - -- name: Replaced with empty config should give appropriate error message - ios_acl_interfaces: - config: - state: replaced - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state replaced' - -- name: Overridden with empty config should give appropriate error message - ios_acl_interfaces: - config: - state: overridden - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state overridden' - -- name: Rendered with empty config should give appropriate error message - ios_acl_interfaces: - config: - state: rendered - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state rendered' - -- name: Parsed with empty config should give appropriate error message - ios_acl_interfaces: - running_config: - state: parsed - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of running_config parameter must not be empty for state parsed' diff --git a/test/integration/targets/ios_acl_interfaces/tests/cli/gathered.yaml b/test/integration/targets/ios_acl_interfaces/tests/cli/gathered.yaml deleted file mode 100644 index e11c78adf14..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tests/cli/gathered.yaml +++ /dev/null @@ -1,21 +0,0 @@ ---- -- debug: - msg: "START ios_acl_interfaces gathered integration tests on connection={{ ansible_connection }}" - -- include_tasks: _populate_config.yaml - -- block: - - name: Gather the provided configuration with the exisiting running configuration - ios_acl_interfaces: &gathered - config: - state: gathered - register: result - - - name: Assert - assert: - that: - - "gathered['config'] | symmetric_difference(result.gathered) == []" - - "result['changed'] == false" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_acl_interfaces/tests/cli/merged.yaml b/test/integration/targets/ios_acl_interfaces/tests/cli/merged.yaml deleted file mode 100644 index 46be05105f1..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tests/cli/merged.yaml +++ /dev/null @@ -1,53 +0,0 @@ ---- -- debug: - msg: "Start ios_acl_interfaces merged integration tests ansible_connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- block: - - - name: Merge the provided configuration with the exisiting running configuration - ios_acl_interfaces: &merged - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv4 - acls: - - name: 110 - direction: in - - name: 123 - direction: out - - afi: ipv6 - acls: - - name: temp_v6 - direction: in - - name: test_v6 - direction: out - - name: GigabitEthernet0/2 - access_groups: - - afi: ipv4 - acls: - - name: 110 - direction: in - - name: 123 - direction: out - state: merged - register: result - - - assert: - that: - - "result.commands|length == 8" - - "result.changed == true" - - "result.commands|symmetric_difference(merged.commands) == []" - - - name: Merge the provided configuration with the exisiting running configuration (IDEMPOTENT) - ios_acl_interfaces: *merged - register: result - - - assert: - that: - - "result.commands|length == 0" - - "result.changed == false" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_acl_interfaces/tests/cli/overridden.yaml b/test/integration/targets/ios_acl_interfaces/tests/cli/overridden.yaml deleted file mode 100644 index 89b303846fc..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tests/cli/overridden.yaml +++ /dev/null @@ -1,41 +0,0 @@ ---- -- debug: - msg: "Start ios_acl_interfaces overridden integration tests ansible_connection={{ ansible_connection }}" - -- include_tasks: _populate_config.yaml - -- block: - - - name: Override device configuration of all acl_interfaces with provided configuration - ios_acl_interfaces: &overridden - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv4 - acls: - - name: 100 - direction: out - - name: 110 - direction: in - state: overridden - become: yes - register: result - - - assert: - that: - - "result.commands|length == 8" - - "result.changed == true" - - "result.commands|symmetric_difference(overridden.commands) == []" - - - name: Override device configuration of all acl_interfaces with provided configuration (IDEMPOTENT) - ios_acl_interfaces: *overridden - become: yes - register: result - - - assert: - that: - - "result.commands|length == 0" - - "result.changed == false" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_acl_interfaces/tests/cli/parsed.yaml b/test/integration/targets/ios_acl_interfaces/tests/cli/parsed.yaml deleted file mode 100644 index 96efd878989..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tests/cli/parsed.yaml +++ /dev/null @@ -1,16 +0,0 @@ ---- -- debug: - msg: "START ios_acl_interfaces parsed integration tests on connection={{ ansible_connection }}" - -- name: Parse the commands for provided configuration - ios_acl_interfaces: &parsed - running_config: - "{{ lookup('file', '_parsed.cfg') }}" - state: parsed - become: yes - register: result - -- assert: - that: - - "result.changed == false" - - "parsed['config']|symmetric_difference(result.parsed) == []" diff --git a/test/integration/targets/ios_acl_interfaces/tests/cli/rendered.yaml b/test/integration/targets/ios_acl_interfaces/tests/cli/rendered.yaml deleted file mode 100644 index 0d83ef0d221..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tests/cli/rendered.yaml +++ /dev/null @@ -1,39 +0,0 @@ ---- -- debug: - msg: "Start ios_acl_interfaces rendered integration tests ansible_connection={{ ansible_connection }}" - -- block: - - - name: Render the commands for provided configuration - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv4 - acls: - - name: 110 - direction: in - - name: 123 - direction: out - - afi: ipv6 - acls: - - name: test_v6 - direction: out - - name: temp_v6 - direction: in - - name: GigabitEthernet0/2 - access_groups: - - afi: ipv4 - acls: - - name: 110 - direction: in - - name: 123 - direction: out - state: rendered - become: yes - register: result - - - assert: - that: - - "result.changed == false" - - "result.rendered|symmetric_difference(merged.commands) == []" diff --git a/test/integration/targets/ios_acl_interfaces/tests/cli/replaced.yaml b/test/integration/targets/ios_acl_interfaces/tests/cli/replaced.yaml deleted file mode 100644 index ef569ebac7c..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tests/cli/replaced.yaml +++ /dev/null @@ -1,41 +0,0 @@ ---- -- debug: - msg: "Start ios_acl_interfaces replced integration tests ansible_connection={{ ansible_connection }}" - -- include_tasks: _populate_config.yaml - -- block: - - - name: Replaces device configuration of listed acl_interfaces with provided configuration - ios_acl_interfaces: &replaced - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv4 - acls: - - name: 100 - direction: out - - name: 110 - direction: in - state: replaced - become: yes - register: result - - - assert: - that: - - "result.commands|length == 5" - - "result.changed == true" - - "result.commands|symmetric_difference(replaced.commands) == []" - - - name: Replaces device configuration of listed acl_interfaces with provided configuration (IDEMPOTENT) - ios_acl_interfaces: *replaced - become: yes - register: result - - - assert: - that: - - "result.commands|length == 0" - - "result.changed == false" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_acl_interfaces/tests/cli/rtt.yaml b/test/integration/targets/ios_acl_interfaces/tests/cli/rtt.yaml deleted file mode 100644 index 999901092fa..00000000000 --- a/test/integration/targets/ios_acl_interfaces/tests/cli/rtt.yaml +++ /dev/null @@ -1,78 +0,0 @@ ---- -- debug: - msg: "START ios_acl_interfaces round trip integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- block: - - - name: Apply the provided configuration (Base config) - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv4 - acls: - - name: 110 - direction: in - - name: 123 - direction: out - - afi: ipv6 - acls: - - name: temp_v6 - direction: in - - name: test_v6 - direction: out - - name: GigabitEthernet0/2 - access_groups: - - afi: ipv4 - acls: - - name: 110 - direction: in - - name: 123 - direction: out - state: merged - register: base_config - - - name: Gather acl interfaces facts - ios_facts: - gather_subset: - - "!all" - - "!min" - gather_network_resources: - - acl_interfaces - - - name: Apply the provided configuration (config to be reverted) - ios_acl_interfaces: - config: - - name: GigabitEthernet0/1 - access_groups: - - afi: ipv4 - acls: - - name: 100 - direction: out - - name: 110 - direction: in - state: overridden - register: result - - - assert: - that: - - "result.commands|length == 8" - - "result.changed == true" - - "result.commands|symmetric_difference(overridden.commands) == []" - - - name: Revert back to base config using facts round trip - ios_acl_interfaces: - config: "{{ ansible_facts['network_resources']['acl_interfaces'] }}" - state: overridden - register: revert - - - assert: - that: - - "revert.commands|length == 8" - - "revert.changed == true" - - "revert.commands|symmetric_difference(rtt.commands) == []" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_acl_interfaces/vars/main.yaml b/test/integration/targets/ios_acl_interfaces/vars/main.yaml deleted file mode 100644 index 424499b53a3..00000000000 --- a/test/integration/targets/ios_acl_interfaces/vars/main.yaml +++ /dev/null @@ -1,99 +0,0 @@ ---- -interfaces: - int1: - GigabitEthernet0/1 - int2: - GigabitEthernet0/2 - - -merged: - commands: - - interface GigabitEthernet0/1 - - ip access-group 110 in - - ip access-group 123 out - - ipv6 traffic-filter temp_v6 in - - ipv6 traffic-filter test_v6 out - - interface GigabitEthernet0/2 - - ip access-group 110 in - - ip access-group 123 out - -replaced: - commands: - - interface GigabitEthernet0/1 - - no ip access-group 123 out - - no ipv6 traffic-filter temp_v6 in - - no ipv6 traffic-filter test_v6 out - - ip access-group 100 out - -overridden: - commands: - - interface GigabitEthernet0/1 - - no ip access-group 123 out - - no ipv6 traffic-filter test_v6 out - - no ipv6 traffic-filter temp_v6 in - - ip access-group 100 out - - interface GigabitEthernet0/2 - - no ip access-group 110 in - - no ip access-group 123 out - -gathered: - config: - - name: GigabitEthernet0/0 - - access_groups: - - acls: - - direction: 'in' - name: '110' - - direction: 'out' - name: '123' - afi: 'ipv4' - - acls: - - direction: 'in' - name: 'temp_v6' - - direction: 'out' - name: 'test_v6' - afi: 'ipv6' - name: GigabitEthernet0/1 - - access_groups: - - acls: - - direction: 'in' - name: '110' - - direction: 'out' - name: '123' - afi: ipv4 - name: GigabitEthernet0/2 - -parsed: - config: - - access_groups: - - acls: - - direction: in - name: '110' - - direction: out - name: '123' - afi: ipv4 - - acls: - - direction: in - name: temp_v6 - - direction: out - name: test_v6 - afi: ipv6 - name: GigabitEthernet0/1 - - access_groups: - - acls: - - direction: in - name: '110' - - direction: out - name: '123' - afi: ipv4 - name: GigabitEthernet0/2 - -rtt: - commands: - - interface GigabitEthernet0/1 - - no ip access-group 100 out - - ip access-group 123 out - - ipv6 traffic-filter temp_v6 in - - ipv6 traffic-filter test_v6 out - - interface GigabitEthernet0/2 - - ip access-group 110 in - - ip access-group 123 out diff --git a/test/integration/targets/ios_acls/defaults/main.yaml b/test/integration/targets/ios_acls/defaults/main.yaml deleted file mode 100644 index 164afead284..00000000000 --- a/test/integration/targets/ios_acls/defaults/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -testcase: "[^_].*" -test_items: [] diff --git a/test/integration/targets/ios_acls/meta/main.yaml b/test/integration/targets/ios_acls/meta/main.yaml deleted file mode 100644 index 32cf5dda7ed..00000000000 --- a/test/integration/targets/ios_acls/meta/main.yaml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] diff --git a/test/integration/targets/ios_acls/tasks/cli.yaml b/test/integration/targets/ios_acls/tasks/cli.yaml deleted file mode 100644 index 242420aa7f5..00000000000 --- a/test/integration/targets/ios_acls/tasks/cli.yaml +++ /dev/null @@ -1,21 +0,0 @@ ---- -- name: Collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - use_regex: true - register: test_cases - delegate_to: localhost - -- name: Set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - delegate_to: localhost - -- name: Run test case (connection=network_cli) - include: "{{ test_case_to_run }}" - vars: - ansible_connection: network_cli - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli diff --git a/test/integration/targets/ios_acls/tasks/main.yaml b/test/integration/targets/ios_acls/tasks/main.yaml deleted file mode 100644 index 415c99d8b12..00000000000 --- a/test/integration/targets/ios_acls/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/ios_acls/tests/cli/_parsed.cfg b/test/integration/targets/ios_acls/tests/cli/_parsed.cfg deleted file mode 100644 index c873eac4cda..00000000000 --- a/test/integration/targets/ios_acls/tests/cli/_parsed.cfg +++ /dev/null @@ -1,7 +0,0 @@ -ip access-list extended test_acl -deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 -ip access-list extended 123 -deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 -deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 -ipv6 access-list R1_TRAFFIC -deny tcp any eq www any eq telnet ack dscp af11 \ No newline at end of file diff --git a/test/integration/targets/ios_acls/tests/cli/_populate_config.yaml b/test/integration/targets/ios_acls/tests/cli/_populate_config.yaml deleted file mode 100644 index 02f69c026db..00000000000 --- a/test/integration/targets/ios_acls/tests/cli/_populate_config.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: Populate Config - cli_config: - config: "{{ lines }}" - vars: - lines: | - ip access-list extended test_acl - deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 - ip access-list extended 110 - deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10 - ip access-list extended 123 - deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 - deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 - ipv6 access-list R1_TRAFFIC - deny tcp any eq www any eq telnet ack dscp af11 diff --git a/test/integration/targets/ios_acls/tests/cli/_remove_config.yaml b/test/integration/targets/ios_acls/tests/cli/_remove_config.yaml deleted file mode 100644 index 29e24cd55eb..00000000000 --- a/test/integration/targets/ios_acls/tests/cli/_remove_config.yaml +++ /dev/null @@ -1,12 +0,0 @@ ---- -- name: Remove Config - cli_config: - config: "{{ lines }}" - vars: - lines: | - no ip access-list standard std_acl - no ip access-list extended test_acl - no ip access-list extended 110 - no ip access-list extended 123 - no ip access-list extended 150 - no ipv6 access-list R1_TRAFFIC diff --git a/test/integration/targets/ios_acls/tests/cli/deleted.yaml b/test/integration/targets/ios_acls/tests/cli/deleted.yaml deleted file mode 100644 index bbf51119b6a..00000000000 --- a/test/integration/targets/ios_acls/tests/cli/deleted.yaml +++ /dev/null @@ -1,70 +0,0 @@ ---- -- debug: - msg: "Start Deleted integration state for ios_acls ansible_connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _populate_config.yaml - -- block: - - name: Delete attributes of provided configured ACLs - ios_acls: &deleted - config: - - afi: ipv4 - acls: - - name: test_acl - acl_type: extended - - name: 110 - aces: - - sequence: 10 - - name: 123 - - afi: ipv6 - acls: - - name: R1_TRAFFIC - state: deleted - register: result - - - assert: - that: - - "result.commands|length == 5" - - "result.changed == true" - - "result.commands|symmetric_difference(deleted.commands) == []" - - - name: Delete attributes of all configured interfaces (IDEMPOTENT) - ios_acls: *deleted - register: result - - - name: Assert that the previous task was idempotent - assert: - that: - - "result.commands|length == 0" - - "result.changed == false" - - - include_tasks: _remove_config.yaml - - include_tasks: _populate_config.yaml - - - name: Delete ACL attributes of provided configured interfaces based on AFI - ios_acls: &deleted_afi - config: - - afi: ipv4 - state: deleted - register: result - - - assert: - that: - - "result.commands|length == 3" - - "result.changed == true" - - "result.commands|symmetric_difference(deleted_afi.commands) == []" - - - name: Delete ACL attributes of provided configured interfaces based on AFI (IDEMPOTENT) - ios_acls: *deleted_afi - register: result - - - name: Assert that the previous task was idempotent - assert: - that: - - "result.commands|length == 0" - - "result.changed == false" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_acls/tests/cli/empty_config.yaml b/test/integration/targets/ios_acls/tests/cli/empty_config.yaml deleted file mode 100644 index 8a911eff28d..00000000000 --- a/test/integration/targets/ios_acls/tests/cli/empty_config.yaml +++ /dev/null @@ -1,58 +0,0 @@ ---- -- debug: - msg: "START ios_acls empty_config.yaml integration tests on connection={{ ansible_connection }}" - -- name: Merged with empty config should give appropriate error message - ios_acls: - config: - state: merged - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state merged' - -- name: Replaced with empty config should give appropriate error message - ios_acls: - config: - state: replaced - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state replaced' - -- name: Overridden with empty config should give appropriate error message - ios_acls: - config: - state: overridden - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state overridden' - -- name: Rendered with empty config should give appropriate error message - ios_acls: - config: - state: rendered - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state rendered' - -- name: Parsed with empty config should give appropriate error message - ios_acls: - running_config: - state: parsed - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of running_config parameter must not be empty for state parsed' diff --git a/test/integration/targets/ios_acls/tests/cli/gathered.yaml b/test/integration/targets/ios_acls/tests/cli/gathered.yaml deleted file mode 100644 index 9b95aec1f3a..00000000000 --- a/test/integration/targets/ios_acls/tests/cli/gathered.yaml +++ /dev/null @@ -1,21 +0,0 @@ ---- -- debug: - msg: "START ios_acls gathered integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml -- include_tasks: _populate_config.yaml - -- block: - - name: Gather the provided configuration with the exisiting running configuration - ios_acls: &gathered - config: - state: gathered - register: result - - - assert: - that: - - "gathered['config'] | symmetric_difference(result.gathered) == []" - - "result['changed'] == false" - - always: - - include_tasks: _remove_config.yaml \ No newline at end of file diff --git a/test/integration/targets/ios_acls/tests/cli/merged.yaml b/test/integration/targets/ios_acls/tests/cli/merged.yaml deleted file mode 100644 index 4bdc9ed0e09..00000000000 --- a/test/integration/targets/ios_acls/tests/cli/merged.yaml +++ /dev/null @@ -1,123 +0,0 @@ ---- -- debug: - msg: "START Merged ios_acls state for integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- block: - - name: Merge provided configuration with device configuration - ios_acls: &merged - config: - - afi: ipv4 - acls: - - name: std_acl - acl_type: standard - aces: - - grant: deny - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - - name: test_acl - acl_type: extended - aces: - - grant: deny - protocol_options: - tcp: - fin: true - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - option: - traceroute: true - ttl: - eq: 10 - - name: 110 - aces: - - grant: deny - sequence: 10 - protocol_options: - icmp: - echo: true - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - dscp: ef - ttl: - eq: 10 - - name: 123 - aces: - - grant: deny - protocol_options: - tcp: - ack: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - destination: - address: 198.51.101.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - tos: - service_value: 12 - - grant: deny - protocol_options: - tcp: - ack: true - source: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.4.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - dscp: ef - ttl: - lt: 20 - - afi: ipv6 - acls: - - name: R1_TRAFFIC - aces: - - grant: deny - protocol_options: - tcp: - ack: true - source: - any: true - port_protocol: - eq: www - destination: - any: true - port_protocol: - eq: telnet - dscp: af11 - state: merged - register: result - - - assert: - that: - - "result.commands|length == 11" - - "result.changed == true" - - "result.commands|symmetric_difference(merged.commands) == []" - - - name: Merge provided configuration with device configuration (IDEMPOTENT) - ios_acls: *merged - register: result - - - name: Assert that the previous task was idempotent - assert: - that: - - "result.commands|length == 0" - - "result['changed'] == false" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_acls/tests/cli/overridden.yaml b/test/integration/targets/ios_acls/tests/cli/overridden.yaml deleted file mode 100644 index ea8a581cfc4..00000000000 --- a/test/integration/targets/ios_acls/tests/cli/overridden.yaml +++ /dev/null @@ -1,73 +0,0 @@ ---- -- debug: - msg: "START Overridden ios_acls state for integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _populate_config.yaml - -- block: - - name: Override device configuration of all interfaces with provided configuration - ios_acls: &overridden - config: - - afi: ipv4 - acls: - - name: 110 - aces: - - grant: deny - protocol_options: - tcp: - ack: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - destination: - address: 198.51.110.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - dscp: ef - ttl: - eq: 10 - - name: 150 - aces: - - grant: deny - protocol_options: - tcp: - syn: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - destination: - address: 198.51.110.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - dscp: ef - ttl: - eq: 10 - state: overridden - register: result - - - assert: - that: - - "result.commands|length == 8" - - "result.changed == true" - - "result.commands|symmetric_difference(overridden.commands) == []" - - - name: Override device configuration of all interfaces with provided configuration (IDEMPOTENT) - ios_acls: *overridden - register: result - - - name: Assert that task was idempotent - assert: - that: - - "result.commands|length == 0" - - "result['changed'] == false" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_acls/tests/cli/parsed.yaml b/test/integration/targets/ios_acls/tests/cli/parsed.yaml deleted file mode 100644 index 4219bc4a9e8..00000000000 --- a/test/integration/targets/ios_acls/tests/cli/parsed.yaml +++ /dev/null @@ -1,16 +0,0 @@ ---- -- debug: - msg: "START ios_acls parsed integration tests on connection={{ ansible_connection }}" - -- name: Parse the commands for provided configuration - ios_acls: &parsed - running_config: - "{{ lookup('file', '_parsed.cfg') }}" - state: parsed - become: yes - register: result - -- assert: - that: - - "result.changed == false" - - "parsed['config']|symmetric_difference(result.parsed) == []" \ No newline at end of file diff --git a/test/integration/targets/ios_acls/tests/cli/rendered.yaml b/test/integration/targets/ios_acls/tests/cli/rendered.yaml deleted file mode 100644 index c5888e7faea..00000000000 --- a/test/integration/targets/ios_acls/tests/cli/rendered.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -- debug: - msg: "Start ios_acls rendered integration tests ansible_connection={{ ansible_connection }}" - -- block: - - name: Rendered the provided configuration with the exisiting running configuration - ios_acls: - config: - - afi: ipv4 - acls: - - name: 110 - aces: - - grant: deny - sequence: 10 - protocol_options: - tcp: - syn: true - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - dscp: ef - ttl: - eq: 10 - - name: 150 - aces: - - grant: deny - protocol_options: - tcp: - syn: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - destination: - address: 198.51.110.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - dscp: ef - ttl: - eq: 10 - state: rendered - register: result - - - assert: - that: - - "result.changed == false" - - "result.rendered|symmetric_difference(rendered.commands) == []" \ No newline at end of file diff --git a/test/integration/targets/ios_acls/tests/cli/replaced.yaml b/test/integration/targets/ios_acls/tests/cli/replaced.yaml deleted file mode 100644 index 1562adae8d5..00000000000 --- a/test/integration/targets/ios_acls/tests/cli/replaced.yaml +++ /dev/null @@ -1,72 +0,0 @@ ---- -- debug: - msg: "START Replaced ios_acls state for integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _populate_config.yaml - -- block: - - name: Replaces device configuration of listed interfaces with provided configuration - ios_acls: &replaced - config: - - afi: ipv4 - acls: - - name: 110 - aces: - - grant: deny - protocol_options: - tcp: - syn: true - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - dscp: ef - ttl: - eq: 10 - - name: 150 - aces: - - grant: deny - sequence: 20 - protocol_options: - tcp: - syn: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - destination: - address: 198.51.110.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - dscp: ef - ttl: - eq: 10 - state: replaced - register: result - - - assert: - that: - - "result.commands|length == 5" - - "result.changed == true" - - "result.commands|symmetric_difference(replaced.commands) == []" - - - name: Replaces device configuration of listed interfaces with provided configuration (IDEMPOTENT) - ios_acls: *replaced - register: result - - - name: Assert that task was idempotent - assert: - that: - - "result.commands|length == 0" - - "result['changed'] == false" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_acls/tests/cli/rtt.yaml b/test/integration/targets/ios_acls/tests/cli/rtt.yaml deleted file mode 100644 index f2f38573177..00000000000 --- a/test/integration/targets/ios_acls/tests/cli/rtt.yaml +++ /dev/null @@ -1,173 +0,0 @@ ---- -- debug: - msg: "START ios_acls round trip integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _populate_config.yaml - -- block: - - name: Apply the provided configuration (base config) - ios_acls: - config: - - afi: ipv4 - acls: - - name: test_acl - acl_type: extended - aces: - - grant: deny - protocol_options: - tcp: - fin: true - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - option: - traceroute: true - ttl: - eq: 10 - - name: 110 - aces: - - grant: deny - protocol_options: - icmp: - echo: true - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - dscp: ef - ttl: - eq: 10 - - name: 123 - aces: - - grant: deny - protocol_options: - tcp: - ack: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - destination: - address: 198.51.101.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - tos: - service_value: 12 - - grant: deny - protocol_options: - tcp: - ack: true - source: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - destination: - address: 192.0.4.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - dscp: ef - ttl: - lt: 20 - - afi: ipv6 - acls: - - name: R1_TRAFFIC - aces: - - grant: deny - protocol_options: - tcp: - ack: true - source: - any: true - port_protocol: - eq: www - destination: - any: true - port_protocol: - eq: telnet - dscp: af11 - state: merged - register: base_config - - - name: Gather ACLs facts - ios_facts: - gather_subset: - - "!all" - - "!min" - gather_network_resources: - - acls - - - name: Apply the configuration which need to be reverted - ios_acls: - config: - - afi: ipv4 - acls: - - name: 110 - aces: - - grant: deny - protocol_options: - tcp: - ack: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - destination: - address: 198.51.110.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: www - dscp: ef - ttl: - eq: 10 - - name: 150 - aces: - - grant: deny - protocol_options: - tcp: - syn: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - destination: - address: 198.51.110.0 - wildcard_bits: 0.0.0.255 - port_protocol: - eq: telnet - dscp: ef - ttl: - eq: 10 - state: overridden - register: result - - - assert: - that: - - "result.commands|length == 8" - - "result.changed == true" - - "result.commands|symmetric_difference(overridden.commands) == []" - - - name: Revert back to base config using facts round trip - ios_acls: - config: "{{ ansible_facts['network_resources']['acls'] }}" - state: overridden - register: revert - - - assert: - that: - - "revert.commands|length == 11" - - "revert.changed == true" - - "revert.commands|symmetric_difference(rtt.commands) == []" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_acls/vars/main.yaml b/test/integration/targets/ios_acls/vars/main.yaml deleted file mode 100644 index 18ff8ef5389..00000000000 --- a/test/integration/targets/ios_acls/vars/main.yaml +++ /dev/null @@ -1,242 +0,0 @@ ---- -deleted: - commands: - - "no ip access-list extended test_acl" - - "ip access-list extended 110" - - "no 10" - - "no ip access-list extended 123" - - "no ipv6 access-list R1_TRAFFIC" - -deleted_afi: - commands: - - "no ip access-list extended 110" - - "no ip access-list extended 123" - - "no ip access-list extended test_acl" - -merged: - commands: - - "ip access-list standard std_acl" - - "deny 192.0.2.0 0.0.0.255" - - "ip access-list extended test_acl" - - "deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10" - - "ip access-list extended 110" - - "10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10" - - "ip access-list extended 123" - - "deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12" - - "deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20" - - "ipv6 access-list R1_TRAFFIC" - - "deny tcp any eq www any eq telnet ack dscp af11" - -replaced: - commands: - - "ip access-list extended 110" - - "no 10" - - "deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10" - - "ip access-list extended 150" - - "20 deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10" - -overridden: - commands: - - "no ip access-list extended 123" - - "no ip access-list extended test_acl" - - "no ipv6 access-list R1_TRAFFIC" - - "ip access-list extended 110" - - "no 10" - - "deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq www ack dscp ef ttl eq 10" - - "ip access-list extended 150" - - "deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10" - -gathered: - config: - - acls: - - aces: - - destination: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - dscp: ef - grant: deny - protocol: icmp - protocol_options: - icmp: - echo: true - sequence: 10 - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - ttl: - eq: 10 - acl_type: extended - name: '110' - - aces: - - destination: - address: 198.51.101.0 - port_protocol: - eq: telnet - wildcard_bits: 0.0.0.255 - grant: deny - protocol: tcp - protocol_options: - tcp: - ack: true - sequence: 10 - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - tos: - service_value: 12 - - destination: - address: 192.0.4.0 - port_protocol: - eq: www - wildcard_bits: 0.0.0.255 - dscp: ef - grant: deny - protocol: tcp - protocol_options: - tcp: - ack: true - sequence: 20 - source: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - ttl: - lt: 20 - acl_type: extended - name: '123' - - aces: - - destination: - address: 192.0.3.0 - port_protocol: - eq: www - wildcard_bits: 0.0.0.255 - grant: deny - option: - traceroute: true - protocol: tcp - protocol_options: - tcp: - fin: true - sequence: 10 - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - ttl: - eq: 10 - acl_type: extended - name: test_acl - afi: ipv4 - - acls: - - aces: - - destination: - any: true - port_protocol: - eq: telnet - dscp: af11 - grant: deny - protocol: tcp - protocol_options: - tcp: - ack: true - sequence: 10 - source: - any: true - port_protocol: - eq: www - name: R1_TRAFFIC - afi: ipv6 - -parsed: - config: - - acls: - - aces: - - destination: - address: 192.0.3.0 - port_protocol: - eq: www - wildcard_bits: 0.0.0.255 - grant: deny - option: - traceroute: true - protocol: tcp - protocol_options: - tcp: - fin: true - source: - address: 192.0.2.0 - wildcard_bits: 0.0.0.255 - ttl: - eq: 10 - name: test_acl - - aces: - - destination: - address: 198.51.101.0 - port_protocol: - eq: telnet - wildcard_bits: 0.0.0.255 - grant: deny - protocol: tcp - protocol_options: - tcp: - ack: true - source: - address: 198.51.100.0 - wildcard_bits: 0.0.0.255 - tos: - service_value: 12 - - destination: - address: 192.0.4.0 - port_protocol: - eq: www - wildcard_bits: 0.0.0.255 - dscp: ef - grant: deny - protocol: tcp - protocol_options: - tcp: - ack: true - source: - address: 192.0.3.0 - wildcard_bits: 0.0.0.255 - ttl: - lt: 20 - name: '123' - afi: ipv4 - - acls: - - aces: - - destination: - any: true - port_protocol: - eq: telnet - dscp: af11 - grant: deny - protocol: tcp - protocol_options: - tcp: - ack: true - source: - any: true - port_protocol: - eq: www - name: R1_TRAFFIC - afi: ipv6 - -rendered: - commands: - - ip access-list extended 110 - - 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10 - - ip access-list extended 150 - - deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10 - -rtt: - commands: - - no ip access-list extended 150 - - ip access-list extended 110 - - no 10 - - 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10 - - ip access-list extended 123 - - 10 deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12 - - 20 deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20 - - ip access-list extended test_acl - - 10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10 - - ipv6 access-list R1_TRAFFIC - - sequence 10 deny tcp any eq www any eq telnet ack dscp af11 diff --git a/test/integration/targets/ios_banner/defaults/main.yaml b/test/integration/targets/ios_banner/defaults/main.yaml deleted file mode 100644 index 5f709c5aac1..00000000000 --- a/test/integration/targets/ios_banner/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" diff --git a/test/integration/targets/ios_banner/meta/main.yml b/test/integration/targets/ios_banner/meta/main.yml deleted file mode 100644 index 159cea8d383..00000000000 --- a/test/integration/targets/ios_banner/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_ios_tests diff --git a/test/integration/targets/ios_banner/tasks/cli.yaml b/test/integration/targets/ios_banner/tasks/cli.yaml deleted file mode 100644 index 6b93fd5400e..00000000000 --- a/test/integration/targets/ios_banner/tasks/cli.yaml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- name: collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - register: test_cases - delegate_to: localhost - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=network_cli) - include: "{{ test_case_to_run }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli - -- name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_local diff --git a/test/integration/targets/ios_banner/tasks/main.yaml b/test/integration/targets/ios_banner/tasks/main.yaml deleted file mode 100644 index 415c99d8b12..00000000000 --- a/test/integration/targets/ios_banner/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/ios_banner/tests/cli/basic-login.yaml b/test/integration/targets/ios_banner/tests/cli/basic-login.yaml deleted file mode 100644 index 5102087d4e5..00000000000 --- a/test/integration/targets/ios_banner/tests/cli/basic-login.yaml +++ /dev/null @@ -1,50 +0,0 @@ ---- - -- name: setup - remove login - ios_banner: - banner: login - state: absent - provider: "{{ cli }}" - - -- name: Set login - ios_banner: - banner: login - text: | - this is my login banner - that has a multiline - string - state: present - provider: "{{ cli }}" - - register: result - -- debug: - msg: "{{ result }}" - -- assert: - that: - - "result.changed == true" - - "'banner login @\nthis is my login banner\nthat has a multiline\nstring\n@' in result.commands" - -- name: Set login again (idempotent) - ios_banner: - banner: login - text: | - this is my login banner - that has a multiline - string - state: present - provider: "{{ cli }}" - - register: result - -- assert: - that: - - "result.changed == false" - - "result.commands | length == 0" - - -# FIXME add in tests for everything defined in docs -# FIXME Test state:absent + test: -# FIXME Without powers ensure "privileged mode required" diff --git a/test/integration/targets/ios_banner/tests/cli/basic-motd.yaml b/test/integration/targets/ios_banner/tests/cli/basic-motd.yaml deleted file mode 100644 index 792758a157a..00000000000 --- a/test/integration/targets/ios_banner/tests/cli/basic-motd.yaml +++ /dev/null @@ -1,50 +0,0 @@ ---- - -- name: setup - remove motd - ios_banner: - banner: motd - state: absent - provider: "{{ cli }}" - - -- name: Set motd - ios_banner: - banner: motd - text: | - this is my motd banner - that has a multiline - string - state: present - provider: "{{ cli }}" - - register: result - -- debug: - msg: "{{ result }}" - -- assert: - that: - - "result.changed == true" - - "'banner motd @\nthis is my motd banner\nthat has a multiline\nstring\n@' in result.commands" - -- name: Set motd again (idempotent) - ios_banner: - banner: motd - text: | - this is my motd banner - that has a multiline - string - state: present - provider: "{{ cli }}" - - register: result - -- assert: - that: - - "result.changed == false" - - "result.commands | length == 0" - - -# FIXME add in tests for everything defined in docs -# FIXME Test state:absent + test: -# FIXME Without powers ensure "privileged mode required" diff --git a/test/integration/targets/ios_banner/tests/cli/basic-no-login.yaml b/test/integration/targets/ios_banner/tests/cli/basic-no-login.yaml deleted file mode 100644 index 1fbe53a4a17..00000000000 --- a/test/integration/targets/ios_banner/tests/cli/basic-no-login.yaml +++ /dev/null @@ -1,41 +0,0 @@ ---- -- name: Setup - ios_banner: - banner: login - text: | - Junk login banner - over multiple lines - state: present - provider: "{{ cli }}" - -- name: remove login - ios_banner: - banner: login - state: absent - provider: "{{ cli }}" - register: result - -- debug: - msg: "{{ result }}" - -- assert: - that: - - "result.changed == true" - - "'no banner login' in result.commands" # does this break due to "contains?" - -- name: remove login (idempotent) - ios_banner: - banner: login - state: absent - provider: "{{ cli }}" - register: result - -- assert: - that: - - "result.changed == false" - - "result.commands | length == 0" - - -# FIXME add in tests for everything defined in docs -# FIXME Test state:absent + test: -# FIXME Without powers ensure "privileged mode required" diff --git a/test/integration/targets/ios_banner/tests/cli/multiple-login-exec.yaml b/test/integration/targets/ios_banner/tests/cli/multiple-login-exec.yaml deleted file mode 100644 index d70f2195743..00000000000 --- a/test/integration/targets/ios_banner/tests/cli/multiple-login-exec.yaml +++ /dev/null @@ -1,55 +0,0 @@ ---- - -- name: Setup - set login and exec - ios_banner: - banner: "{{ item }}" - text: | - this is my login banner - that as a multiline - string - state: present - provider: "{{ cli }}" - loop: - - login - - exec - - -- name: Set login - ios_banner: - banner: "login" - text: | - this is my login banner - that as a multiline - string - state: present - provider: "{{ cli }}" - - register: result - -- debug: - msg: "{{ result }}" - -- assert: - that: - - "result.changed == false" - - "result.commands | length == 0" - -- name: Set exec - ios_banner: - banner: "exec" - text: | - this is my login banner - that as a multiline - string - state: present - provider: "{{ cli }}" - - register: result - -- debug: - msg: "{{ result }}" - -- assert: - that: - - "result.changed == false" - - "result.commands | length == 0" diff --git a/test/integration/targets/ios_banner/tests/cli/net_banner.yml b/test/integration/targets/ios_banner/tests/cli/net_banner.yml deleted file mode 100644 index 49e98f631d7..00000000000 --- a/test/integration/targets/ios_banner/tests/cli/net_banner.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -- debug: msg="START ios cli/net_banner.yaml on connection={{ ansible_connection }}" - -# Add minimal testcase to check args are passed correctly to -# implementation module and module run is successful. - -- name: setup - remove login - net_banner: - banner: login - state: absent - authorize: yes - -- name: Set login - net_banner: - banner: login - text: this is my login banner confgiured by net_banner - state: present - authorize: yes - register: result - -- assert: - that: - - "result.changed == true" - - "'banner login @\nthis is my login banner confgiured by net_banner\n@' in result.commands" - -- name: teardown - remove login - net_banner: - banner: login - state: absent - authorize: yes - -- debug: msg="END ios cli/net_banner.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_bgp/defaults/main.yaml b/test/integration/targets/ios_bgp/defaults/main.yaml deleted file mode 100644 index 5f709c5aac1..00000000000 --- a/test/integration/targets/ios_bgp/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" diff --git a/test/integration/targets/ios_bgp/meta/main.yaml b/test/integration/targets/ios_bgp/meta/main.yaml deleted file mode 100644 index 159cea8d383..00000000000 --- a/test/integration/targets/ios_bgp/meta/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_ios_tests diff --git a/test/integration/targets/ios_bgp/tasks/cli.yaml b/test/integration/targets/ios_bgp/tasks/cli.yaml deleted file mode 100644 index 575f5d0a8e0..00000000000 --- a/test/integration/targets/ios_bgp/tasks/cli.yaml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - register: test_cases - delegate_to: localhost - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=network_cli) - include: "{{ test_case_to_run }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli diff --git a/test/integration/targets/ios_bgp/tasks/main.yaml b/test/integration/targets/ios_bgp/tasks/main.yaml deleted file mode 100644 index 415c99d8b12..00000000000 --- a/test/integration/targets/ios_bgp/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/ios_bgp/tests/cli/basic.yaml b/test/integration/targets/ios_bgp/tests/cli/basic.yaml deleted file mode 100644 index 9d6713530ae..00000000000 --- a/test/integration/targets/ios_bgp/tests/cli/basic.yaml +++ /dev/null @@ -1,504 +0,0 @@ -- debug: msg="START ios cli/ios_bgp.yaml on connection={{ ansible_connection }}" - -- name: Clear existing BGP config - ios_bgp: - operation: delete - ignore_errors: yes - -- block: - - - name: Add fake config with 'bgp' string - ios_config: - match: none - replace: block - lines: - - "no ip access-list extended BGP_ACL" - - "ip access-list extended BGP_ACL" - - "permit tcp any any eq bgp" - - - name: Try delete fake bgp config - register: result - ios_bgp: - operation: delete - - - assert: - that: - - 'result.changed == false' - - - name: Clean fake config with 'bgp' string - ios_config: - match: none - replace: block - lines: - - "no ip access-list extended BGP_ACL" - - - name: Add fake bgp-like config - ios_config: - match: none - replace: block - lines: - - "no ip access-list extended BGP_ACL_2" - - "ip access-list extended BGP_ACL_2" - - "remark router bgp 64496" - - "remark neighbor 192.0.2.10 remote-as 64496" - - "remark neighbor 192.0.2.10 shutdown" - - "remark address-family ipv4" - - "remark neighbor 192.0.2.10 activate" - - "remark exit-address-family" - - "permit tcp any any eq bgp" - - - name: Try delete fake bgp-like config - register: result - ios_bgp: - operation: delete - - - assert: - that: - - 'result.changed == false' - - - name: Clean fake bgp-like config - ios_config: - match: none - replace: block - lines: - - "no ip access-list extended BGP_ACL_2" - - - name: Configure BGP with AS 64496 and a router-id - ios_bgp: &config - operation: merge - config: - bgp_as: 64496 - router_id: 192.0.2.2 - register: result - - - 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) - ios_bgp: *config - register: result - - - assert: - that: - - 'result.changed == false' - - - name: Configure BGP neighbors - ios_bgp: &nbr - operation: merge - config: - bgp_as: 64496 - neighbors: - - neighbor: 192.0.2.10 - remote_as: 64496 - password: ansible - description: IBGP_NBR_1 - ebgp_multihop: 100 - timers: - keepalive: 300 - holdtime: 360 - min_neighbor_holdtime: 360 - - - neighbor: 192.0.2.15 - remote_as: 64496 - description: IBGP_NBR_2 - ebgp_multihop: 150 - register: result - - - assert: - that: - - 'result.changed == true' - - "'router bgp 64496' in result.commands" - - "'neighbor 192.0.2.10 remote-as 64496' in result.commands" - - "'neighbor 192.0.2.10 description IBGP_NBR_1' in result.commands" - - "'neighbor 192.0.2.10 ebgp-multihop 100' in result.commands" - - "'neighbor 192.0.2.10 timers 300 360 360' in result.commands" - - "'neighbor 192.0.2.15 remote-as 64496' in result.commands" - - "'neighbor 192.0.2.15 description IBGP_NBR_2' in result.commands" - - "'neighbor 192.0.2.15 ebgp-multihop 150' in result.commands" - - - name: Configure BGP neighbors (idempotent) - ios_bgp: *nbr - register: result - - - assert: - that: - - 'result.changed == false' - - - name: Configure BGP neighbors with operation replace - ios_bgp: &nbr_rplc - operation: replace - config: - bgp_as: 64496 - neighbors: - - neighbor: 192.0.2.15 - remote_as: 64496 - description: IBGP_NBR_2 - ebgp_multihop: 150 - - - neighbor: 203.0.113.10 - remote_as: 64511 - description: EBGP_NBR_1 - local_as: 64497 - - - neighbor: 10.10.20.20 - remote_as: 65012 - description: BGP_NBR_2 - ebgp_multihop: 100 - register: result - - - assert: - that: - - 'result.changed == true' - - "'neighbor 203.0.113.10 remote-as 64511' in result.commands" - - "'neighbor 203.0.113.10 description EBGP_NBR_1' in result.commands" - - "'neighbor 203.0.113.10 local-as 64497' in result.commands" - - "'neighbor 10.10.20.20 remote-as 65012' in result.commands" - - "'neighbor 10.10.20.20 description BGP_NBR_2' in result.commands" - - "'no neighbor 192.0.2.10' in result.commands" - - - name: Configure BGP neighbors with operation replace (idempotent) - ios_bgp: *nbr_rplc - register: result - - - assert: - that: - - 'result.changed == false' - - - name: Configure root-level networks for BGP - ios_bgp: &net - operation: merge - config: - bgp_as: 64496 - networks: - - prefix: 203.0.113.0 - masklen: 27 - route_map: RMAP_1 - - - prefix: 203.0.113.32 - masklen: 27 - route_map: RMAP_2 - register: result - - - assert: - that: - - 'result.changed == True' - - "'router bgp 64496' in result.commands" - - "'network 203.0.113.0 mask 255.255.255.224 route-map RMAP_1' in result.commands" - - "'network 203.0.113.32 mask 255.255.255.224 route-map RMAP_2' in result.commands" - - - name: Configure root-level networks for BGP (idempotent) - ios_bgp: *net - register: result - - - assert: - that: - - 'result.changed == false' - - - name: Configure root-level networks for BGP with operation replace - ios_bgp: &net_rplc - operation: replace - config: - bgp_as: 64496 - networks: - - prefix: 203.0.113.0 - masklen: 27 - route_map: RMAP_1 - - - prefix: 198.51.100.16 - masklen: 28 - register: result - - - assert: - that: - - 'result.changed == True' - - "'router bgp 64496' in result.commands" - - "'network 198.51.100.16 mask 255.255.255.240' in result.commands" - - "'no network 203.0.113.32 mask 255.255.255.224 route-map RMAP_2' in result.commands" - - - name: Configure root-level networks for BGP with operation replace (idempotent) - ios_bgp: *net_rplc - register: result - - - assert: - that: - - 'result.changed == false' - - - name: Configure BGP neighbors under address family mode - ios_bgp: &af_nbr - operation: merge - config: - bgp_as: 64496 - address_family: - - afi: ipv4 - safi: unicast - neighbors: - - neighbor: 203.0.113.10 - activate: yes - maximum_prefix: 250 - advertisement_interval: 120 - - - neighbor: 192.0.2.15 - activate: yes - route_reflector_client: True - - - neighbor: 10.10.20.20 - activate: yes - prefix_list_in: incoming-prefixes - prefix_list_out: outgoing-prefixes - register: result - - - assert: - that: - - 'result.changed == true' - - "'router bgp 64496' in result.commands" - - "'address-family ipv4' in result.commands" - - "'neighbor 203.0.113.10 activate' in result.commands" - - "'neighbor 203.0.113.10 maximum-prefix 250' in result.commands" - - "'neighbor 203.0.113.10 advertisement-interval 120' in result.commands" - - "'neighbor 192.0.2.15 activate' in result.commands" - - "'neighbor 192.0.2.15 route-reflector-client' in result.commands" - - "'neighbor 10.10.20.20 activate' in result.commands" - - "'neighbor 10.10.20.20 prefix-list incoming-prefixes in' in result.commands" - - "'neighbor 10.10.20.20 prefix-list outgoing-prefixes out' in result.commands" - - - name: Configure BGP neighbors under address family mode (idempotent) - ios_bgp: *af_nbr - register: result - - - assert: - that: - - 'result.changed == false' - - - name: Configure networks under address family - ios_bgp: &af_net - operation: merge - config: - bgp_as: 64496 - address_family: - - afi: ipv4 - safi: multicast - 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 - route_map: RMAP_2 - - - afi: ipv4 - safi: unicast - networks: - - prefix: 198.51.100.64 - masklen: 28 - register: result - - - assert: - that: - - 'result.changed == true' - - "'router bgp 64496' in result.commands" - - "'address-family ipv4 multicast' in result.commands" - - "'network 198.51.100.48 mask 255.255.255.240 route-map RMAP_1' in result.commands" - - "'network 192.0.2.64 mask 255.255.255.224' in result.commands" - - "'network 203.0.113.160 mask 255.255.255.224 route-map RMAP_2' in result.commands" - - "'exit-address-family' in result.commands" - - "'address-family ipv4' in result.commands" - - "'network 198.51.100.64 mask 255.255.255.240' in result.commands" - - "'exit-address-family' in result.commands" - - - name: Configure networks under address family (idempotent) - ios_bgp: *af_net - register: result - - - assert: - that: - - 'result.changed == false' - - - name: Configure networks under address family with operation replace - ios_bgp: &af_net_rplc - operation: replace - config: - bgp_as: 64496 - address_family: - - afi: ipv4 - safi: multicast - 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: unicast - networks: - - prefix: 198.51.100.64 - masklen: 28 - register: result - - - assert: - that: - - 'result.changed == true' - - '"router bgp 64496" in result.commands' - - '"address-family ipv4 multicast" in result.commands' - - '"network 198.51.100.80 mask 255.255.255.240" in result.commands' - - '"network 203.0.113.192 mask 255.255.255.224" in result.commands' - - '"no network 198.51.100.48 mask 255.255.255.240 route-map RMAP_1" in result.commands' - - '"no network 203.0.113.160 mask 255.255.255.224 route-map RMAP_2" in result.commands' - - '"exit-address-family" in result.commands' - - - name: Configure networks under address family with operation replace (idempotent) - ios_bgp: *af_net_rplc - register: result - - - assert: - that: - - 'result.changed == false' - - - name: Configure redistribute information under address family mode - ios_bgp: &af_rdr - operation: merge - config: - bgp_as: 64496 - address_family: - - afi: ipv4 - safi: multicast - redistribute: - - protocol: ospf - id: 112 - metric: 64 - - - protocol: eigrp - id: 233 - metric: 256 - register: result - - - assert: - that: - - 'result.changed == true' - - "'router bgp 64496' in result.commands" - - "'address-family ipv4 multicast' in result.commands" - - "'redistribute ospf 112 metric 64' in result.commands" - - "'redistribute eigrp 233 metric 256' in result.commands" - - "'exit-address-family' in result.commands" - - - name: Configure redistribute information under address family mode (idempotent) - ios_bgp: *af_rdr - register: result - - - assert: - that: - - 'result.changed == false' - - - name: Get the IOS version - ios_facts: - gather_subset: all - - - name: Configure redistribute information under address family mode with operation replace - ios_bgp: &af_rdr_rplc - operation: replace - config: - bgp_as: 64496 - address_family: - - afi: ipv4 - safi: multicast - redistribute: - - protocol: ospf - id: 112 - metric: 64 - register: result - - - assert: - that: - - 'result.changed == true' - - "'router bgp 64496' in result.commands" - - "'address-family ipv4 multicast' in result.commands" - - "'no redistribute eigrp 233' in result.commands" - - "'exit-address-family' in result.commands" - - - name: Configure redistribute information under address family mode with operation replace (idempotent) - ios_bgp: *af_rdr_rplc - register: result - when: ansible_net_version != "15.6(2)T" - - - assert: - that: - - 'result.changed == false' - when: ansible_net_version != "15.6(2)T" - - - name: Override all the exisiting BGP config - ios_bgp: - operation: override - config: - bgp_as: 64497 - router_id: 192.0.2.10 - log_neighbor_changes: True - register: result - - - assert: - that: - - 'result.changed == true' - - "'no router bgp 64496' in result.commands" - - "'router bgp 64497' in result.commands" - - "'bgp router-id 192.0.2.10' in result.commands" - - "'bgp log-neighbor-changes' in result.commands" - - - name: "Configure BGP neighbors with classful boundary" - ios_bgp: &classful - config: - bgp_as: 64497 - log_neighbor_changes: true - networks: - - prefix: 198.51.100.0 - masklen: 23 - - - prefix: 201.0.113.32 - masklen: 24 - - operation: merge - register: result - - - assert: - that: - - 'result.changed == true' - - "'router bgp 64497' in result.commands" - - "'network 198.51.100.0 mask 255.255.254.0' in result.commands" - - "'network 201.0.113.32' in result.commands" - - - name: Configure BGP neighbors with classful boundary (idempotent) - ios_bgp: *classful - register: result - - - assert: - that: - - 'result.changed == false' - - always: - - name: Teardown - ios_bgp: &rm - operation: delete - register: result - - - assert: - that: - - 'result.changed == true' - - "'no router bgp 64497' in result.commands" - - - name: Teardown again (idempotent) - ios_bgp: *rm - register: result - - - assert: - that: - - 'result.changed == false' - -- debug: msg="END ios cli/ios_bgp.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_command/defaults/main.yaml b/test/integration/targets/ios_command/defaults/main.yaml deleted file mode 100644 index 9ef5ba51651..00000000000 --- a/test/integration/targets/ios_command/defaults/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -testcase: "*" -test_items: [] diff --git a/test/integration/targets/ios_command/meta/main.yml b/test/integration/targets/ios_command/meta/main.yml deleted file mode 100644 index 159cea8d383..00000000000 --- a/test/integration/targets/ios_command/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_ios_tests diff --git a/test/integration/targets/ios_command/tasks/cli.yaml b/test/integration/targets/ios_command/tasks/cli.yaml deleted file mode 100644 index 6b93fd5400e..00000000000 --- a/test/integration/targets/ios_command/tasks/cli.yaml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- name: collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - register: test_cases - delegate_to: localhost - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=network_cli) - include: "{{ test_case_to_run }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli - -- name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_local diff --git a/test/integration/targets/ios_command/tasks/main.yaml b/test/integration/targets/ios_command/tasks/main.yaml deleted file mode 100644 index 415c99d8b12..00000000000 --- a/test/integration/targets/ios_command/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/ios_command/tests/cli/bad_operator.yaml b/test/integration/targets/ios_command/tests/cli/bad_operator.yaml deleted file mode 100644 index 99ad05420b7..00000000000 --- a/test/integration/targets/ios_command/tests/cli/bad_operator.yaml +++ /dev/null @@ -1,20 +0,0 @@ ---- -- debug: msg="START cli/bad_operator.yaml on connection={{ ansible_connection }}" - -- name: test bad operator - ios_command: - commands: - - show version - - show interfaces GigabitEthernet 0/0 - provider: "{{ cli }}" - wait_for: - - "result[0] contains 'Description: Foo'" - register: result - ignore_errors: yes - -- assert: - that: - - "result.failed == true" - - "result.msg is defined" - -- debug: msg="END cli/bad_operator.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_command/tests/cli/cli_command.yaml b/test/integration/targets/ios_command/tests/cli/cli_command.yaml deleted file mode 100644 index a2a252d3abc..00000000000 --- a/test/integration/targets/ios_command/tests/cli/cli_command.yaml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- debug: - msg: "START cli/cli_command.yaml on connection={{ ansible_connection }}" - -- block: - - name: get output for single command - cli_command: - command: show version - register: result - - - assert: - that: - - "result.changed == false" - - "result.stdout is defined" - - - name: send invalid command - cli_command: - command: 'show foo' - register: result - ignore_errors: yes - - - assert: - that: - - "result.failed == true" - - "result.msg is defined" - when: "ansible_connection == 'network_cli'" - -- debug: msg="END cli/cli_command.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_command/tests/cli/contains.yaml b/test/integration/targets/ios_command/tests/cli/contains.yaml deleted file mode 100644 index 3e41f903993..00000000000 --- a/test/integration/targets/ios_command/tests/cli/contains.yaml +++ /dev/null @@ -1,20 +0,0 @@ ---- -- debug: msg="START cli/contains.yaml on connection={{ ansible_connection }}" - -- name: test contains operator - ios_command: - commands: - - show version - - show interface loopback 888 - provider: "{{ cli }}" - wait_for: - - "result[0] contains Cisco" - - "result[1] contains Loopback888" - register: result - -- assert: - that: - - "result.changed == false" - - "result.stdout is defined" - -- debug: msg="END cli/contains.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_command/tests/cli/error_regex.yaml b/test/integration/targets/ios_command/tests/cli/error_regex.yaml deleted file mode 100644 index c8c8a47c046..00000000000 --- a/test/integration/targets/ios_command/tests/cli/error_regex.yaml +++ /dev/null @@ -1,59 +0,0 @@ ---- -- debug: msg="START cli/error_regex.yaml on connection={{ ansible_connection }}" - -- block: - - name: clear logs 1 - cli_command: &clear_logs - command: clear logging - prompt: - - Clear logging buffer - answer: - - "\r" - ignore_errors: True - - - name: send log with error regex match 1 - cli_command: &send_logs - command: "send log 'IPSEC-3-REPLAY_ERROR: test log_1'" - ignore_errors: True - - - name: fetch logs without command specific error regex - ios_command: - commands: - - show logging - register: result - ignore_errors: True - - - name: ensure task fails due to mismatched regex - assert: - that: - - "result.failed == true" - - - name: pause to avoid rate limiting - pause: - seconds: 10 - - - name: clear logs 2 - cli_command: *clear_logs - ignore_errors: True - - - name: send log with error regex match 2 - cli_command: *send_logs - ignore_errors: True - - - name: fetch logs with command specific error regex - ios_command: - commands: - - show logging - register: result - vars: - ansible_terminal_stderr_re: - - pattern: 'connection timed out' - flags: 're.I' - - - name: ensure task with modified error regex is success - assert: - that: - - "result.failed == false" - when: ansible_connection == 'network_cli' - -- debug: msg="END cli/error_regex.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_command/tests/cli/invalid.yaml b/test/integration/targets/ios_command/tests/cli/invalid.yaml deleted file mode 100644 index 35829ff605c..00000000000 --- a/test/integration/targets/ios_command/tests/cli/invalid.yaml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- debug: msg="START cli/invalid.yaml on connection={{ ansible_connection }}" - -- name: run invalid command - ios_command: - commands: show foo - provider: "{{ cli }}" - register: result - ignore_errors: yes - -- assert: - that: - - "result.failed" - -- name: run commands that include invalid command - ios_command: - commands: - - show version - - show foo - provider: "{{ cli }}" - register: result - ignore_errors: yes - -- assert: - that: - - "result.failed" - -- debug: msg="END cli/invalid.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_command/tests/cli/output.yaml b/test/integration/targets/ios_command/tests/cli/output.yaml deleted file mode 100644 index 945b388b172..00000000000 --- a/test/integration/targets/ios_command/tests/cli/output.yaml +++ /dev/null @@ -1,30 +0,0 @@ ---- -- debug: msg="START cli/output.yaml on connection={{ ansible_connection }}" - -- name: get output for single command - ios_command: - commands: - - show version - provider: "{{ cli }}" - register: result - -- assert: - that: - - "result.changed == false" - - "result.stdout is defined" - -- name: get output for multiple commands - ios_command: - commands: - - show version - - show interfaces - provider: "{{ cli }}" - register: result - -- assert: - that: - - "result.changed == false" - - "result.stdout is defined" - - "result.stdout | length == 2" - -- debug: msg="END cli/output.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_command/tests/cli/timeout.yaml b/test/integration/targets/ios_command/tests/cli/timeout.yaml deleted file mode 100644 index 4f430edeb2b..00000000000 --- a/test/integration/targets/ios_command/tests/cli/timeout.yaml +++ /dev/null @@ -1,19 +0,0 @@ ---- -- debug: msg="START cli/timeout.yaml on connection={{ ansible_connection }}" - -- name: test bad condition - ios_command: - commands: - - show version - provider: "{{ cli }}" - wait_for: - - "result[0] contains bad_value_string" - register: result - ignore_errors: yes - -- assert: - that: - - "result.failed == true" - - "result.msg is defined" - -- debug: msg="END cli/timeout.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/defaults/main.yaml b/test/integration/targets/ios_config/defaults/main.yaml deleted file mode 100644 index 9ef5ba51651..00000000000 --- a/test/integration/targets/ios_config/defaults/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -testcase: "*" -test_items: [] diff --git a/test/integration/targets/ios_config/meta/main.yml b/test/integration/targets/ios_config/meta/main.yml deleted file mode 100644 index 159cea8d383..00000000000 --- a/test/integration/targets/ios_config/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_ios_tests diff --git a/test/integration/targets/ios_config/tasks/cli.yaml b/test/integration/targets/ios_config/tasks/cli.yaml deleted file mode 100644 index 82d196e4edc..00000000000 --- a/test/integration/targets/ios_config/tasks/cli.yaml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - register: test_cases - delegate_to: localhost - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=network_cli) - include: "{{ test_case_to_run }} ansible_connection=network_cli" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli diff --git a/test/integration/targets/ios_config/tasks/cli_config.yaml b/test/integration/targets/ios_config/tasks/cli_config.yaml deleted file mode 100644 index a3c82d63844..00000000000 --- a/test/integration/targets/ios_config/tasks/cli_config.yaml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: collect all cli_config test cases - find: - paths: "{{ role_path }}/tests/cli_config" - patterns: "{{ testcase }}.yaml" - register: test_cases - delegate_to: localhost - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=network_cli) - include: "{{ test_case_to_run }} ansible_connection=network_cli" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli diff --git a/test/integration/targets/ios_config/tasks/main.yaml b/test/integration/targets/ios_config/tasks/main.yaml deleted file mode 100644 index 5e327e8d521..00000000000 --- a/test/integration/targets/ios_config/tasks/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } -- { include: cli_config.yaml, tags: ['cli_config'] } diff --git a/test/integration/targets/ios_config/templates/basic/base_running_config b/test/integration/targets/ios_config/templates/basic/base_running_config deleted file mode 100644 index 37254dc9634..00000000000 --- a/test/integration/targets/ios_config/templates/basic/base_running_config +++ /dev/null @@ -1,9 +0,0 @@ -version 15.6 -service timestamps debug datetime msec -service timestamps log datetime msec -no service password-encryption -! -hostname an-ios-01.ansible.com -! -boot-start-marker -boot-end-marker diff --git a/test/integration/targets/ios_config/templates/basic/config.j2 b/test/integration/targets/ios_config/templates/basic/config.j2 deleted file mode 100644 index 06f98488836..00000000000 --- a/test/integration/targets/ios_config/templates/basic/config.j2 +++ /dev/null @@ -1,4 +0,0 @@ -interface Loopback999 - description this is a test - shutdown - diff --git a/test/integration/targets/ios_config/templates/basic/configblock.j2 b/test/integration/targets/ios_config/templates/basic/configblock.j2 deleted file mode 100644 index 46150c4d900..00000000000 --- a/test/integration/targets/ios_config/templates/basic/configblock.j2 +++ /dev/null @@ -1,5 +0,0 @@ -ip access-list extended test - permit ip host 192.0.2.1 any log - permit ip host 192.0.2.2 any log - permit ip host 192.0.2.3 any log - permit ip host 192.0.2.4 any log diff --git a/test/integration/targets/ios_config/templates/basic/configexact1.j2 b/test/integration/targets/ios_config/templates/basic/configexact1.j2 deleted file mode 100644 index 82ad080c5d9..00000000000 --- a/test/integration/targets/ios_config/templates/basic/configexact1.j2 +++ /dev/null @@ -1,6 +0,0 @@ -no ip access-list extended test -ip access-list extended test - permit ip host 192.0.2.1 any log - permit ip host 192.0.2.2 any log - permit ip host 192.0.2.3 any log - permit ip host 192.0.2.4 any log diff --git a/test/integration/targets/ios_config/templates/basic/configexact2.j2 b/test/integration/targets/ios_config/templates/basic/configexact2.j2 deleted file mode 100644 index 46150c4d900..00000000000 --- a/test/integration/targets/ios_config/templates/basic/configexact2.j2 +++ /dev/null @@ -1,5 +0,0 @@ -ip access-list extended test - permit ip host 192.0.2.1 any log - permit ip host 192.0.2.2 any log - permit ip host 192.0.2.3 any log - permit ip host 192.0.2.4 any log diff --git a/test/integration/targets/ios_config/templates/basic/configstrict1.j2 b/test/integration/targets/ios_config/templates/basic/configstrict1.j2 deleted file mode 100644 index 46150c4d900..00000000000 --- a/test/integration/targets/ios_config/templates/basic/configstrict1.j2 +++ /dev/null @@ -1,5 +0,0 @@ -ip access-list extended test - permit ip host 192.0.2.1 any log - permit ip host 192.0.2.2 any log - permit ip host 192.0.2.3 any log - permit ip host 192.0.2.4 any log diff --git a/test/integration/targets/ios_config/templates/basic/intended_running_config b/test/integration/targets/ios_config/templates/basic/intended_running_config deleted file mode 100644 index bdad8d3d8b0..00000000000 --- a/test/integration/targets/ios_config/templates/basic/intended_running_config +++ /dev/null @@ -1,9 +0,0 @@ -version 15.6 -service timestamps debug datetime msec -service timestamps log datetime msec -no service password-encryption -! -hostname an-ios-02.ansible.com -! -boot-start-marker -boot-end-marker diff --git a/test/integration/targets/ios_config/templates/basic/macro.j2 b/test/integration/targets/ios_config/templates/basic/macro.j2 deleted file mode 100644 index 44a7a9bdbd5..00000000000 --- a/test/integration/targets/ios_config/templates/basic/macro.j2 +++ /dev/null @@ -1,8 +0,0 @@ - A12345678 123456789 123456789 123456789 123456789 123456789 123456789 - B12345678 123456789 123456789 123456789 123456789 123456789 123456789 - C12345678 123456789 123456789 123456789 123456789 123456789 123456789 - D12345678 123456789 123456789 123456789 123456789 123456789 123456789 - E12345678 123456789 123456789 123456789 123456789 123456789 123456789 - F12345678 123456789 123456789 123456789 123456789 123456789 123456789 - G12345678 123456789 123456789 123456789 123456789 123456789 123456789 - H12345678 123456789 123456789 123456789 123456789 123456789 123456789 diff --git a/test/integration/targets/ios_config/templates/basic/setupblock.j2 b/test/integration/targets/ios_config/templates/basic/setupblock.j2 deleted file mode 100644 index f57aa49b732..00000000000 --- a/test/integration/targets/ios_config/templates/basic/setupblock.j2 +++ /dev/null @@ -1,5 +0,0 @@ -no ip access-list extended test -ip access-list extended test - permit ip host 192.0.2.1 any log - permit ip host 192.0.2.2 any log - permit ip host 192.0.2.3 any log diff --git a/test/integration/targets/ios_config/templates/basic/setupexact.j2 b/test/integration/targets/ios_config/templates/basic/setupexact.j2 deleted file mode 100644 index e8791e272e1..00000000000 --- a/test/integration/targets/ios_config/templates/basic/setupexact.j2 +++ /dev/null @@ -1,7 +0,0 @@ -no ip access-list extended test -ip access-list extended test - permit ip host 192.0.2.1 any log - permit ip host 192.0.2.2 any log - permit ip host 192.0.2.3 any log - permit ip host 192.0.2.4 any log - permit ip host 192.0.2.5 any log diff --git a/test/integration/targets/ios_config/templates/basic/setupstrict.j2 b/test/integration/targets/ios_config/templates/basic/setupstrict.j2 deleted file mode 100644 index e8791e272e1..00000000000 --- a/test/integration/targets/ios_config/templates/basic/setupstrict.j2 +++ /dev/null @@ -1,7 +0,0 @@ -no ip access-list extended test -ip access-list extended test - permit ip host 192.0.2.1 any log - permit ip host 192.0.2.2 any log - permit ip host 192.0.2.3 any log - permit ip host 192.0.2.4 any log - permit ip host 192.0.2.5 any log diff --git a/test/integration/targets/ios_config/templates/defaults/config.j2 b/test/integration/targets/ios_config/templates/defaults/config.j2 deleted file mode 100644 index 1d4d9da8d41..00000000000 --- a/test/integration/targets/ios_config/templates/defaults/config.j2 +++ /dev/null @@ -1,4 +0,0 @@ -interface Loopback999 - description this is a test - no shutdown - diff --git a/test/integration/targets/ios_config/tests/cli/backup.yaml b/test/integration/targets/ios_config/tests/cli/backup.yaml deleted file mode 100644 index 0921d0086b0..00000000000 --- a/test/integration/targets/ios_config/tests/cli/backup.yaml +++ /dev/null @@ -1,125 +0,0 @@ ---- -- debug: msg="START cli/cli_backup.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - commands: - - no description - - no shutdown - parents: - - interface Loopback999 - match: none - -- name: collect any backup files - find: - paths: "{{ role_path }}/backup" - pattern: "{{ inventory_hostname_short }}_config*" - register: backup_files - connection: local - -- name: delete backup files - file: - path: "{{ item.path }}" - state: absent - with_items: "{{backup_files.files|default([])}}" - -- name: configure device with config - ios_config: - src: basic/config.j2 - backup: yes - register: result - -- assert: - that: - - "result.changed == true" -# FIXME Bug https://github.com/ansible/ansible/issues/19382 -# - "result.updates is not defined" - -- name: collect any backup files - find: - paths: "{{ role_path }}/backup" - pattern: "{{ inventory_hostname_short }}_config*" - register: backup_files - connection: local - -- assert: - that: - - "backup_files.files is defined" - -- name: delete configurable backup file path - 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 - ios_config: - backup: yes - backup_options: - filename: backup.cfg - dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - become: yes - register: result - -- assert: - that: - - "result.changed == true" - -- name: check if the backup file-1 exist - find: - paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup.cfg" - register: backup_file - connection: local - -- assert: - that: - - "backup_file.files is defined" - -- name: take configuration backup in custom filename - ios_config: - backup: yes - backup_options: - filename: backup.cfg - become: yes - register: result - -- assert: - that: - - "result.changed == true" - -- name: check if the backup file-2 exist - find: - paths: "{{ role_path }}/backup/backup.cfg" - register: backup_file - connection: local - -- assert: - that: - - "backup_file.files is defined" - -- name: take configuration backup in custom path and default filename - ios_config: - backup: yes - backup_options: - dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - become: yes - register: result - -- assert: - that: - - "result.changed == true" - -- name: check if the backup file-3 exist - find: - paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - pattern: "{{ inventory_hostname_short }}_config*" - register: backup_file - connection: local - -- assert: - that: - - "backup_file.files is defined" - -- debug: msg="END cli/cli_backup.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/defaults.yaml b/test/integration/targets/ios_config/tests/cli/defaults.yaml deleted file mode 100644 index 3792a9eb6ad..00000000000 --- a/test/integration/targets/ios_config/tests/cli/defaults.yaml +++ /dev/null @@ -1,57 +0,0 @@ ---- -- debug: msg="START cli/defaults.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - commands: - - no description - - shutdown - parents: - - interface Loopback999 - match: none - -- name: configure device with defaults included - ios_config: - src: defaults/config.j2 - defaults: yes - register: result - -- debug: var=result - -- assert: - that: - - "result.changed == true" -# FIXME Bug https://github.com/ansible/ansible/issues/19382 -# - "result.updates is not defined" - -- name: check device with defaults included - ios_config: - src: defaults/config.j2 - defaults: yes - register: result - -- debug: var=result - -- assert: - that: - - "result.changed == false" - - "result.updates is not defined" - -- name: Check device is in proper prompt after error - ios_config: - lines: - - mac-address-table notification mac-move - ignore_errors: yes - -- name: show interfaces brief to ensure deivce goes to valid prompt - ios_command: - commands: - - show interfaces - register: result - -- assert: - that: - - "result.changed == false" - - "result.stdout is defined" - -- debug: msg="END cli/defaults.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/diff.yaml b/test/integration/targets/ios_config/tests/cli/diff.yaml deleted file mode 100644 index dbdd033a894..00000000000 --- a/test/integration/targets/ios_config/tests/cli/diff.yaml +++ /dev/null @@ -1,33 +0,0 @@ ---- -- debug: msg="START cli/diff.yaml on connection={{ ansible_connection }}" - -- name: Ensure hostname is preset - ios_system: - hostname: "{{ shorter_hostname }}" - -- name: ios_config diff against retrieved config - ios_config: - diff_against: intended - intended_config: "{{ lookup('file', '{{ role_path }}/templates/basic/intended_running_config') }}" - diff: true - register: result - -- assert: - that: - - "'hostname an-ios-02.ansible.com' in result['diff']['after']" - - "'hostname {{ shorter_hostname }}' in result['diff']['before']" - -- name: ios_config diff against provided running_config - ios_config: - diff_against: intended - intended_config: "{{ lookup('file', '{{ role_path }}/templates/basic/intended_running_config') }}" - running_config: "{{ lookup('file', '{{ role_path }}/templates/basic/base_running_config') }}" - diff: true - register: result - -- assert: - that: - - "'hostname an-ios-02.ansible.com' in result['diff']['after']" - - "'hostname an-ios-01.ansible.com' in result['diff']['before']" - -- debug: msg="END cli/diff.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/macro.yaml b/test/integration/targets/ios_config/tests/cli/macro.yaml deleted file mode 100644 index b526f47dc5c..00000000000 --- a/test/integration/targets/ios_config/tests/cli/macro.yaml +++ /dev/null @@ -1,66 +0,0 @@ ---- - -- debug: msg="START cli/cli_macro.yaml on connection={{ ansible_connection }}" - -- name: "Check for macro support" - ios_command: - commands: - - "show parser macro brief" - register: supports_macro - ignore_errors: yes - -- name: "ios_config macro integration tests" - when: supports_macro is succeeded - block: - - - name: "Define macro name" - set_fact: - macro_name: 'MACRO_ANSIBLE_TEST' - - - name: "setup - remove configuration" - ios_config: - lines: - - 'no macro name {{ macro_name }}' - - 'do show clock' - match: none - - - name: "configure macro" - ios_config: - parents: "macro name {{ macro_name }}" - # before: [ 'no macro name ...'] - multiline_delimiter: '@' - after: '@' - match: line - replace: block - lines: "{{ lookup('template', 'basic/macro.j2') }}" - register: result - - - name: "Check if macro has been added" - assert: - that: - - "result.changed == true" - - - name: "configure macro again - idempotent check" - ios_config: - parents: "macro name {{ macro_name }}" - multiline_delimiter: '@' - after: '@' - match: line - replace: block - lines: "{{ lookup('template', 'basic/macro.j2') }}" - register: result - - - name: "macro already/correctly configured ?" - assert: - that: - - "result.changed == false" - - always: - - name: "teardown" - ios_config: - lines: - - "no macro name {{ macro_name }}" - - 'do show clock' - match: none - -- debug: msg="END cli/cli_macro.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/save.yaml b/test/integration/targets/ios_config/tests/cli/save.yaml deleted file mode 100644 index bd839615758..00000000000 --- a/test/integration/targets/ios_config/tests/cli/save.yaml +++ /dev/null @@ -1,49 +0,0 @@ ---- -- debug: msg="START cli/save.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - commands: - - no description - - no shutdown - parents: - - interface Loopback999 - match: none - save_when: modified - -- name: save should always run - ios_config: - save_when: always - register: result - -- assert: - that: - - "result.changed == true" - -- name: delete config (setup) - ios_config: - replace: line - lines: - - "no ip http server" - save_when: modified - register: result - -- name: save should run when changed - ios_config: - replace: line - lines: - - "ip http server" - save_when: modified - register: result - -- assert: - that: - - "result.changed == true" - -- name: teardown - ios_config: - lines: - - "no ip http server" - register: result - -- debug: msg="END cli/save.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/src_basic.yaml b/test/integration/targets/ios_config/tests/cli/src_basic.yaml deleted file mode 100644 index c9381aca868..00000000000 --- a/test/integration/targets/ios_config/tests/cli/src_basic.yaml +++ /dev/null @@ -1,70 +0,0 @@ ---- -- debug: msg="START cli/src_basic.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - commands: - - no description - - no shutdown - parents: - - interface Loopback999 - match: none - -- name: configure device with config - ios_config: - src: basic/config.j2 - register: result - -- name: debug, remove me - debug: - msg: "{{ result }}" -- assert: - that: - - "result.changed == true" -# https://github.com/ansible/ansible-modules-core/issues/4807 -# FIXME Bug https://github.com/ansible/ansible/issues/19382 -# - "result.updates is not defined" - -- name: check device with config - ios_config: - src: basic/config.j2 - register: result - -- assert: - that: - - "result.changed == false" -# https://github.com/ansible/ansible-modules-core/issues/4807 -# FIXME Bug https://github.com/ansible/ansible/issues/19382 -# - "result.updates is not defined" - -- name: check for empty diff - ios_config: - running_config: | - service timestamps debug datetime msec - service timestamps log datetime msec - lines: - - service timestamps debug datetime msec - - service timestamps log datetime msec - check_mode: True - register: result -- assert: - that: - - "result.updates is undefined" - -- name: check for diff with ignore lines for running config - ios_config: - running_config: | - service timestamps debug datetime msec - service timestamps log datetime msec - lines: - - service timestamps debug datetime msec - - service timestamps log datetime msec - diff_ignore_lines: service timestamps log datetime msec - check_mode: True - register: result - -- assert: - that: - - "'service timestamps log datetime msec' in result.updates" - -- debug: msg="END cli/src_basic.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/src_invalid.yaml b/test/integration/targets/ios_config/tests/cli/src_invalid.yaml deleted file mode 100644 index 07443240376..00000000000 --- a/test/integration/targets/ios_config/tests/cli/src_invalid.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- -- debug: msg="START cli/src_invalid.yaml on connection={{ ansible_connection }}" - - -# Defend https://github.com/ansible/ansible-modules-core/issues/4797 -- name: configure with invalid src - ios_config: - src: basic/foobar.j2 - register: result - ignore_errors: yes - -- assert: - that: - - "result.changed == false" - - "result.failed == true" - - "result.msg == 'path specified in src not found'" - -- debug: msg="END cli/src_invalid.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/src_match_none.yaml b/test/integration/targets/ios_config/tests/cli/src_match_none.yaml deleted file mode 100644 index 4300a37d286..00000000000 --- a/test/integration/targets/ios_config/tests/cli/src_match_none.yaml +++ /dev/null @@ -1,38 +0,0 @@ ---- -- debug: msg="START cli/src_match_none.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - commands: - - no description - - no shutdown - parents: - - interface Loopback999 - match: none - -- name: configure device with config - ios_config: - src: basic/config.j2 - match: none - register: result - -- assert: - that: - - "result.changed == true" -# https://github.com/ansible/ansible-modules-core/issues/4807 -# FIXME Bug https://github.com/ansible/ansible/issues/19382 -# - "result.updates is not defined" - -- name: check device with config - ios_config: - src: basic/config.j2 - register: result - -- assert: - that: - # Idempotent test -# https://github.com/ansible/ansible-modules-core/issues/4807 - - "result.changed == false" - - "result.updates is not defined" - -- debug: msg="END cli/src_match_none.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/sublevel.yaml b/test/integration/targets/ios_config/tests/cli/sublevel.yaml deleted file mode 100644 index 7442cd9c2bb..00000000000 --- a/test/integration/targets/ios_config/tests/cli/sublevel.yaml +++ /dev/null @@ -1,39 +0,0 @@ ---- -- debug: msg="START cli/sublevel.yaml on connection={{ ansible_connection }}" - -- name: setup test - ios_config: - lines: - - 'no ip access-list extended test' - - 'no ip access-list standard test' - match: none - -- name: configure sub level command - ios_config: - lines: ['permit ip any any log'] - parents: ['ip access-list extended test'] - register: result - -- assert: - that: - - "result.changed == true" - - "'ip access-list extended test' in result.updates" - - "'permit ip any any log' in result.updates" - -- name: configure sub level command idempotent check - ios_config: - lines: ['permit ip any any log'] - parents: ['ip access-list extended test'] - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - ios_config: - lines: - - 'no ip access-list extended test' - match: none - -- debug: msg="END cli/sublevel.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/sublevel_block.yaml b/test/integration/targets/ios_config/tests/cli/sublevel_block.yaml deleted file mode 100644 index 05d14ee77d2..00000000000 --- a/test/integration/targets/ios_config/tests/cli/sublevel_block.yaml +++ /dev/null @@ -1,58 +0,0 @@ ---- -- debug: msg="START cli/sublevel_block.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: - - permit ip host 192.0.2.1 any log - - permit ip host 192.0.2.2 any log - - permit ip host 192.0.2.3 any log - parents: ['ip access-list extended test'] - before: ['no ip access-list extended test'] - after: ['exit'] - match: none - -- name: configure sub level command using block resplace - ios_config: - lines: - - permit ip host 192.0.2.1 any log - - permit ip host 192.0.2.2 any log - - permit ip host 192.0.2.3 any log - - permit ip host 192.0.2.4 any log - parents: ['ip access-list extended test'] - replace: block - after: ['exit'] - register: result - -- assert: - that: - - "result.changed == true" - - "'ip access-list extended test' in result.updates" - - "'permit ip host 192.0.2.1 any log' in result.updates" - - "'permit ip host 192.0.2.2 any log' in result.updates" - - "'permit ip host 192.0.2.3 any log' in result.updates" - - "'permit ip host 192.0.2.4 any log' in result.updates" - -- name: check sub level command using block replace - ios_config: - lines: - - permit ip host 192.0.2.1 any log - - permit ip host 192.0.2.2 any log - - permit ip host 192.0.2.3 any log - - permit ip host 192.0.2.4 any log - parents: ['ip access-list extended test'] - replace: block - after: ['exit'] - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - ios_config: - lines: - - no ip access-list extended test - match: none - -- debug: msg="END cli/sublevel_block.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/sublevel_exact.yaml b/test/integration/targets/ios_config/tests/cli/sublevel_exact.yaml deleted file mode 100644 index 0feb3f99e51..00000000000 --- a/test/integration/targets/ios_config/tests/cli/sublevel_exact.yaml +++ /dev/null @@ -1,61 +0,0 @@ ---- -- debug: msg="START cli/sublevel_exact.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: - - permit ip host 192.0.2.1 any log - - permit ip host 192.0.2.2 any log - - permit ip host 192.0.2.3 any log - - permit ip host 192.0.2.4 any log - - permit ip host 192.0.2.5 any log - parents: ip access-list extended test - before: no ip access-list extended test - after: exit - match: none - -- name: configure sub level command using exact match - ios_config: - lines: - - permit ip host 192.0.2.1 any log - - permit ip host 192.0.2.2 any log - - permit ip host 192.0.2.3 any log - - permit ip host 192.0.2.4 any log - parents: ip access-list extended test - before: no ip access-list extended test - after: exit - match: exact - register: result - -- assert: - that: - - "result.changed == true" - - "'ip access-list extended test' in result.updates" - - "'permit ip host 192.0.2.1 any log' in result.updates" - - "'permit ip host 192.0.2.2 any log' in result.updates" - - "'permit ip host 192.0.2.3 any log' in result.updates" - - "'permit ip host 192.0.2.4 any log' in result.updates" - - "'permit ip host 192.0.2.5 any log' not in result.updates" - -- name: check sub level command using exact match - ios_config: - lines: - - permit ip host 192.0.2.1 any log - - permit ip host 192.0.2.2 any log - - permit ip host 192.0.2.3 any log - - permit ip host 192.0.2.4 any log - parents: ip access-list extended test - match: exact - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - ios_config: - lines: - - no ip access-list extended test - match: none - -- debug: msg="END cli/sublevel_exact.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/sublevel_strict.yaml b/test/integration/targets/ios_config/tests/cli/sublevel_strict.yaml deleted file mode 100644 index ea4cb11b3ee..00000000000 --- a/test/integration/targets/ios_config/tests/cli/sublevel_strict.yaml +++ /dev/null @@ -1,57 +0,0 @@ ---- -- debug: msg="START cli/sublevel_strict.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: - - permit ip host 192.0.2.1 any log - - permit ip host 192.0.2.2 any log - - permit ip host 192.0.2.3 any log - - permit ip host 192.0.2.4 any log - - permit ip host 192.0.2.5 any log - parents: ip access-list extended test - before: no ip access-list extended test - match: none - -- name: configure sub level command using strict match - ios_config: - lines: - - permit ip host 192.0.2.1 any log - - permit ip host 192.0.2.2 any log - - permit ip host 192.0.2.3 any log - - permit ip host 192.0.2.4 any log - parents: ip access-list extended test - match: strict - register: result - -- assert: - that: - - "result.changed == false" - -- name: check sub level command using strict match - ios_config: - lines: - - permit ip host 192.0.2.1 any log - - permit ip host 192.0.2.3 any log - - permit ip host 192.0.2.2 any log - parents: ip access-list extended test - after: exit - match: strict - register: result - -- assert: - that: - - "result.changed == true" - - "'ip access-list extended test' in result.updates" - - "'permit ip host 192.0.2.1 any log' not in result.updates" - - "'permit ip host 192.0.2.2 any log' in result.updates" - - "'permit ip host 192.0.2.3 any log' in result.updates" - - "'permit ip host 192.0.2.4 any log' not in result.updates" - - "'permit ip host 192.0.2.5 any log' not in result.updates" - -- name: teardown - ios_config: - lines: no ip access-list extended test - match: none - -- debug: msg="END cli/sublevel_strict.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/sublevel_strict_mul_parents.yaml b/test/integration/targets/ios_config/tests/cli/sublevel_strict_mul_parents.yaml deleted file mode 100644 index f99f77e3415..00000000000 --- a/test/integration/targets/ios_config/tests/cli/sublevel_strict_mul_parents.yaml +++ /dev/null @@ -1,66 +0,0 @@ ---- -- debug: msg="START cli/sublevel_strict_mul_parents.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: - - class-map c1 - - match precedence 7 - - policy-map p1 - - class c1 - before: ['no policy-map p1', 'no class-map c1'] - match: none - -- name: configure sub level command using strict match - ios_config: - lines: - - set ip precedence 5 - - police cir percent 10 - parents: ['policy-map p1', 'class c1'] - match: strict - register: result - -- assert: - that: - - "result.changed == true" - - "'set ip precedence 5' in result.updates" - - "'police cir percent 10' in result.updates" - -- name: change sub level command order and config with strict match - ios_config: - lines: - - police cir percent 10 - - set ip precedence 5 - parents: ['policy-map p1', 'class c1'] - match: strict - register: result - -- assert: - that: - - "result.changed == true" - - "'set ip precedence 5' in result.updates" - - "'police cir percent 10' in result.updates" - -- name: Config sub level command with strict match (Idempotency) - ios_config: - lines: -#IOS does not change orded of class action if reconfigured -#so we have to use old order for Idempoteny - - set ip precedence 5 - - police cir percent 10 - parents: ['policy-map p1', 'class c1'] - match: strict - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - ios_config: - lines: - - no policy-map p1 - - no class-map c1 - match: none - -- debug: msg="END cli/sublevel_strict_mul_parents.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/toplevel.yaml b/test/integration/targets/ios_config/tests/cli/toplevel.yaml deleted file mode 100644 index 0408c8202a6..00000000000 --- a/test/integration/targets/ios_config/tests/cli/toplevel.yaml +++ /dev/null @@ -1,33 +0,0 @@ ---- -- debug: msg="START cli/toplevel.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: ['hostname {{ shorter_hostname }}'] - match: none - -- name: configure top level command - ios_config: - lines: ['hostname foo'] - register: result - -- assert: - that: - - "result.changed == true" - - "'hostname foo' in result.updates" - -- name: configure top level command idempotent check - ios_config: - lines: ['hostname foo'] - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - ios_config: - lines: ['hostname {{ shorter_hostname }}'] - match: none - -- debug: msg="END cli/toplevel.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/toplevel_after.yaml b/test/integration/targets/ios_config/tests/cli/toplevel_after.yaml deleted file mode 100644 index 26039e06a34..00000000000 --- a/test/integration/targets/ios_config/tests/cli/toplevel_after.yaml +++ /dev/null @@ -1,40 +0,0 @@ ---- -- debug: msg="START cli/toplevel_after.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: - - "snmp-server contact ansible" - - "hostname {{ shorter_hostname }}" - match: none - -- name: configure top level command with before - ios_config: - lines: ['hostname foo'] - after: ['snmp-server contact bar'] - register: result - -- assert: - that: - - "result.changed == true" - - "'hostname foo' in result.updates" - - "'snmp-server contact bar' in result.updates" - -- name: configure top level command with before idempotent check - ios_config: - lines: ['hostname foo'] - after: ['snmp-server contact foo'] - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - ios_config: - lines: - - "no snmp-server contact" - - "hostname {{ shorter_hostname }}" - match: none - -- debug: msg="END cli/toplevel_after.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/toplevel_before.yaml b/test/integration/targets/ios_config/tests/cli/toplevel_before.yaml deleted file mode 100644 index ab210be8c8b..00000000000 --- a/test/integration/targets/ios_config/tests/cli/toplevel_before.yaml +++ /dev/null @@ -1,40 +0,0 @@ ---- -- debug: msg="START cli/toplevel_before.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: - - "snmp-server contact ansible" - - "hostname {{ shorter_hostname }}" - match: none - -- name: configure top level command with before - ios_config: - lines: ['hostname foo'] - before: ['snmp-server contact bar'] - register: result - -- assert: - that: - - "result.changed == true" - - "'hostname foo' in result.updates" - - "'snmp-server contact bar' in result.updates" - -- name: configure top level command with before idempotent check - ios_config: - lines: ['hostname foo'] - before: ['snmp-server contact foo'] - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - ios_config: - lines: - - "no snmp-server contact" - - "hostname {{ shorter_hostname }}" - match: none - -- debug: msg="END cli/toplevel_before.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli/toplevel_nonidempotent.yaml b/test/integration/targets/ios_config/tests/cli/toplevel_nonidempotent.yaml deleted file mode 100644 index 06aa8384813..00000000000 --- a/test/integration/targets/ios_config/tests/cli/toplevel_nonidempotent.yaml +++ /dev/null @@ -1,35 +0,0 @@ ---- -- debug: msg="START cli/toplevel_nonidempotent.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: ['hostname {{ shorter_hostname }}'] - match: none - -- name: configure top level command - ios_config: - lines: ['hostname foo'] - match: strict - register: result - -- assert: - that: - - "result.changed == true" - - "'hostname foo' in result.updates" - -- name: configure top level command idempotent check - ios_config: - lines: ['hostname foo'] - match: strict - register: result - -- assert: - that: - - "result.changed == true" - -- name: teardown - ios_config: - lines: ['hostname {{ shorter_hostname }}'] - match: none - -- debug: msg="END cli/toplevel_nonidempotent.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli_config/cli_backup.yaml b/test/integration/targets/ios_config/tests/cli_config/cli_backup.yaml deleted file mode 100644 index a431c01fdea..00000000000 --- a/test/integration/targets/ios_config/tests/cli_config/cli_backup.yaml +++ /dev/null @@ -1,113 +0,0 @@ -- debug: msg="END cli_config/backup.yaml on connection={{ ansible_connection }}" - -- name: delete configurable backup file path - file: - path: "{{ item }}" - state: absent - with_items: - - "{{ role_path }}/backup_test_dir/" - - "{{ role_path }}/backup/backup.cfg" - -- name: collect any backup files - find: - paths: "{{ role_path }}/backup" - pattern: "{{ inventory_hostname_short }}_config*" - register: backup_files - connection: local - -- name: delete backup files - file: - path: "{{ item.path }}" - state: absent - with_items: "{{backup_files.files|default([])}}" - -- name: take config backup - cli_config: - backup: yes - become: yes - register: result - -- assert: - that: - - "result.changed == true" - -- name: collect any backup files - find: - paths: "{{ role_path }}/backup" - pattern: "{{ inventory_hostname_short }}_config*" - register: backup_files - connection: local - -- assert: - that: - - "backup_files.files is defined" - -- name: take configuration backup in custom filename and directory path - cli_config: - backup: yes - backup_options: - filename: backup.cfg - dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - become: yes - register: result - -- assert: - that: - - "result.changed == true" - -- name: check if the backup file-1 exist - find: - paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup.cfg" - register: backup_file - connection: local - -- assert: - that: - - "backup_file.files is defined" - -- name: take configuration backup in custom filename - cli_config: - backup: yes - backup_options: - filename: backup.cfg - become: yes - register: result - -- assert: - that: - - "result.changed == true" - -- name: check if the backup file-2 exist - find: - paths: "{{ role_path }}/backup/backup.cfg" - register: backup_file - connection: local - -- assert: - that: - - "backup_file.files is defined" - -- name: take configuration backup in custom path and default filename - cli_config: - backup: yes - backup_options: - dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - become: yes - register: result - -- assert: - that: - - "result.changed == true" - -- name: check if the backup file-3 exist - find: - paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - pattern: "{{ inventory_hostname_short }}_config*" - register: backup_file - connection: local - -- assert: - that: - - "backup_file.files is defined" - -- debug: msg="END cli_config/backup.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli_config/cli_basic.yaml b/test/integration/targets/ios_config/tests/cli_config/cli_basic.yaml deleted file mode 100644 index 607b3df498b..00000000000 --- a/test/integration/targets/ios_config/tests/cli_config/cli_basic.yaml +++ /dev/null @@ -1,45 +0,0 @@ ---- -- debug: msg="START cli_config/cli_basic.yaml on connection={{ ansible_connection }}" - -- name: setup - cli_config: &rm - config: | - interface loopback999 - no description - shutdown - diff_match: none - -- name: configure device with config - cli_config: &conf - config: "{{ lookup('template', 'basic/config.j2') }}" - register: result - -- assert: - that: - - "result.changed == true" - -- name: Idempotence - cli_config: *conf - register: result - -- assert: - that: - - "result.changed == false" - -- name: remove config - cli_config: *rm - -- name: configure device with config - cli_config: - config: "{{ lookup('template', 'basic/config.j2') }}" - defaults: yes - register: result - -- assert: - that: - - "result.changed == true" - -- name: teardown - cli_config: *rm - -- debug: msg="END cli_config/cli_basic.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli_config/cli_block_replace.yaml b/test/integration/targets/ios_config/tests/cli_config/cli_block_replace.yaml deleted file mode 100644 index f66f83f96db..00000000000 --- a/test/integration/targets/ios_config/tests/cli_config/cli_block_replace.yaml +++ /dev/null @@ -1,32 +0,0 @@ ---- -- debug: msg="START cli_config/cli_block_replace.yaml on connection={{ ansible_connection }}" - -- name: setup - remove configuration - cli_config: - config: "{{ lookup('template', 'basic/setupblock.j2') }}" - diff_match: none - -- name: block replace - cli_config: &block - config: "{{ lookup('template', 'basic/configblock.j2') }}" - diff_replace: block - register: result - -- assert: - that: - - "result.changed == true" - -- name: block replace (Idempotence) - cli_config: *block - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - cli_config: - config: no ip access-list extended test - diff_match: none - -- debug: msg="END cli_config/cli_block_replace.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli_config/cli_exact_match.yaml b/test/integration/targets/ios_config/tests/cli_config/cli_exact_match.yaml deleted file mode 100644 index 597afa50994..00000000000 --- a/test/integration/targets/ios_config/tests/cli_config/cli_exact_match.yaml +++ /dev/null @@ -1,33 +0,0 @@ ---- -- debug: msg="START cli_config/cli_exact_match.yaml on connection={{ ansible_connection }}" - -- name: setup - remove configuration - cli_config: - config: "{{ lookup('template', 'basic/setupexact.j2') }}" - diff_match: none - -- name: configure using exact match - cli_config: - config: "{{ lookup('template', 'basic/configexact1.j2') }}" - diff_match: exact - register: result - -- assert: - that: - - "result.changed == true" - -- name: check using exact match - cli_config: - config: "{{ lookup('template', 'basic/configexact2.j2') }}" - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - cli_config: - config: no ip access-list extended test - diff_match: none - -- debug: msg="END cli_config/cli_exact_match.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_config/tests/cli_config/cli_strict_match.yaml b/test/integration/targets/ios_config/tests/cli_config/cli_strict_match.yaml deleted file mode 100644 index 45ba54f1ef3..00000000000 --- a/test/integration/targets/ios_config/tests/cli_config/cli_strict_match.yaml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- debug: msg="START cli_config/cli_strict_match.yaml on connection={{ ansible_connection }}" - -- name: setup - remove configuration - cli_config: - config: "{{ lookup('template', 'basic/setupstrict.j2') }}" - diff_match: none - -- name: configure using strict match - cli_config: - config: "{{ lookup('template', 'basic/configstrict1.j2') }}" - diff_match: strict - register: result - -- assert: - that: - - "result.changed == true" - -- name: teardown - cli_config: - config: no ip access-list extended test - diff_match: none - -- debug: msg="END cli_config/cli_strict_match.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_facts/defaults/main.yaml b/test/integration/targets/ios_facts/defaults/main.yaml deleted file mode 100644 index 9ef5ba51651..00000000000 --- a/test/integration/targets/ios_facts/defaults/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -testcase: "*" -test_items: [] diff --git a/test/integration/targets/ios_facts/meta/main.yml b/test/integration/targets/ios_facts/meta/main.yml deleted file mode 100644 index 159cea8d383..00000000000 --- a/test/integration/targets/ios_facts/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_ios_tests diff --git a/test/integration/targets/ios_facts/tasks/cli.yaml b/test/integration/targets/ios_facts/tasks/cli.yaml deleted file mode 100644 index 6b93fd5400e..00000000000 --- a/test/integration/targets/ios_facts/tasks/cli.yaml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- name: collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - register: test_cases - delegate_to: localhost - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=network_cli) - include: "{{ test_case_to_run }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli - -- name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_local diff --git a/test/integration/targets/ios_facts/tasks/main.yaml b/test/integration/targets/ios_facts/tasks/main.yaml deleted file mode 100644 index 415c99d8b12..00000000000 --- a/test/integration/targets/ios_facts/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/ios_facts/tests/cli/all_facts.yaml b/test/integration/targets/ios_facts/tests/cli/all_facts.yaml deleted file mode 100644 index 5f2a754487d..00000000000 --- a/test/integration/targets/ios_facts/tests/cli/all_facts.yaml +++ /dev/null @@ -1,35 +0,0 @@ ---- -- debug: msg="START cli/all_facts.yaml on connection={{ ansible_connection }}" - - -- name: test getting all facts - ios_facts: - gather_subset: - - all - provider: "{{ cli }}" - register: result - - - -- assert: - that: - # _facts modules should never report a change - - "result.changed == false" - - # Correct subsets are present - - "'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" - - # Items from those subsets are present - - "result.ansible_facts.ansible_net_filesystems is defined" - # Check that these facts not only are present, but are valid (positive integers) - - "result.ansible_facts.ansible_net_memfree_mb > 1" - - "result.ansible_facts.ansible_net_memtotal_mb > 1" - -- assert: - that: "{{ item.value.spacetotal_kb }} > {{ item.value.spacefree_kb }}" - loop: "{{ lookup('dict', result.ansible_facts.ansible_net_filesystems_info, wantlist=True) }}" - -- debug: msg="END cli/all_facts.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_facts/tests/cli/default_facts.yaml b/test/integration/targets/ios_facts/tests/cli/default_facts.yaml deleted file mode 100644 index 11cb9e518f7..00000000000 --- a/test/integration/targets/ios_facts/tests/cli/default_facts.yaml +++ /dev/null @@ -1,35 +0,0 @@ ---- -- debug: msg="START cli/default_facts.yaml on connection={{ ansible_connection }}" - - -- name: test getting default facts - ios_facts: - provider: "{{ cli }}" - register: result - -- assert: - that: - # _facts modules should never report a change - - "result.changed == false" - - # Correct subsets are present - - "'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_filesystems is defined" - # ... and not present - - "'config' not in result.ansible_facts.ansible_net_gather_subset" - - # Items from those subsets are present - - "result.ansible_facts.ansible_net_filesystems is defined" #hw - - "result.ansible_facts.ansible_net_memtotal_mb > 10" #hw - - "result.ansible_facts.ansible_net_interfaces | length > 1" # more than one interface returned - - # ... and not present - - "result.ansible_facts.ansible_net_config is not defined" # config - -- assert: - that: "{{ item.value.spacetotal_kb }} > {{ item.value.spacefree_kb }}" - loop: "{{ lookup('dict', result.ansible_facts.ansible_net_filesystems_info, wantlist=True) }}" - -- debug: msg="END cli/default.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_facts/tests/cli/invalid_subset.yaml b/test/integration/targets/ios_facts/tests/cli/invalid_subset.yaml deleted file mode 100644 index e7d4281f7db..00000000000 --- a/test/integration/targets/ios_facts/tests/cli/invalid_subset.yaml +++ /dev/null @@ -1,48 +0,0 @@ ---- -- debug: msg="START cli/invalid_subset.yaml on connection={{ ansible_connection }}" - - -- name: test invalid subset (foobar) - ios_facts: - gather_subset: - - "foobar" - provider: "{{ cli }}" - register: result - ignore_errors: true - - -- assert: - that: - # Failures shouldn't return changes - - "result.changed == false" - # It's a failure - - "result.failed == true" - # Sensible Failure message - - "result.msg == 'Subset must be one of [config, default, hardware, interfaces], got foobar'" - -############### -# FIXME Future -# We may in the future want to add a test for - -- name: test subset specified multiple times - ios_facts: - gather_subset: - - "!hardware" - - "hardware" - provider: "{{ cli }}" - register: result - ignore_errors: true - -- assert: - that: - # Failures shouldn't return changes - - "result.changed == false" - # It's a failure - - "result.failed == true" - # Sensible Failure message - - "result.msg == 'Bad subset'" - ignore_errors: true - - - -- debug: msg="END cli/invalid_subset.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_facts/tests/cli/not_hardware.yaml b/test/integration/targets/ios_facts/tests/cli/not_hardware.yaml deleted file mode 100644 index da46f2cd90b..00000000000 --- a/test/integration/targets/ios_facts/tests/cli/not_hardware.yaml +++ /dev/null @@ -1,31 +0,0 @@ ---- -- debug: msg="START cli/not_hardware_facts.yaml on connection={{ ansible_connection }}" - - -- name: test not hardware - ios_facts: - gather_subset: - - "!hardware" - provider: "{{ cli }}" - register: result - -- assert: - that: - # _facts modules should never report a change - - "result.changed == false" - - # Correct subsets are present - - "'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" - # ... and not present - - "'hardware' not in result.ansible_facts.ansible_net_gather_subset" - - # Items from those subsets are present - - "result.ansible_facts.ansible_net_interfaces | length > 1" # more than one interface returned - # ... and not present - - "result.ansible_facts.ansible_net_filesystems is not defined" - - "result.ansible_facts.ansible_net_filesystems_info is not defined" - -- debug: msg="END cli/not_hardware_facts.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_file/aliases b/test/integration/targets/ios_file/aliases deleted file mode 100644 index 6bb69158a7a..00000000000 --- a/test/integration/targets/ios_file/aliases +++ /dev/null @@ -1 +0,0 @@ -shippable/ios/group1 diff --git a/test/integration/targets/ios_file/defaults/main.yaml b/test/integration/targets/ios_file/defaults/main.yaml deleted file mode 100644 index 5f709c5aac1..00000000000 --- a/test/integration/targets/ios_file/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" diff --git a/test/integration/targets/ios_file/ios1.cfg b/test/integration/targets/ios_file/ios1.cfg deleted file mode 100644 index 120dd4cad75..00000000000 --- a/test/integration/targets/ios_file/ios1.cfg +++ /dev/null @@ -1,3 +0,0 @@ -vlan 3 - name ank_vlan3 -! diff --git a/test/integration/targets/ios_file/nonascii.bin b/test/integration/targets/ios_file/nonascii.bin deleted file mode 100644 index 14c6ddb1b89289430c975940232429e8cb77ec1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmV(pK=8j5`)WYd2Suhh`T0MIo74Xr@xV!=rwG*rhV}AHVt+m>kmxc$0KjsQ2|v*JI=woYQd!n80~s(9+qPA?B-oLN zz$~Pk!QR$F7c(5k_0W1!X(=T8fB%ln9CVItr2e&u4q0b7TL?$1p5P?$5vM)hMH+Tb z8sE*yteT+FGU{W?Xd?HgFp2tYa)E4gT=7-;-?B!=6st9YZ9y}(79eWPJ1xf=O%Z6u6;mXbB~J4?neYB@ zSiO^&F<&!BOt8SV3i#JVRV2TzPSRT8`Ye=Bjl`e@xeY6)v*I~$fY$3JQyq=p7(ZoN z{D~`$uIelY+~+q@MD=P5J~m8RsZ}2H=X(FYeBtICH-)zpW0qP*9fR={y6?EwbYGU0 zj9dkoViE?hW_VmS0Lpk$-SbZ(iZ*JXbvJGiZ)dh8hoParb@h?{pt99nPcS_n?tR#s z)V<0&zVl+Ea*zBhQ4jwjPh(AdVJ5P3UM2CS?3Emw3WVDU-j8pUSjpcJ*d(-%qxNIi zJd>;#L_6e2lvJ`{GD8lSk+!;>3(%;)T!GYPUrY*zP*%Ds`MToIk0#E%!dcL^?Vju6 zePml;CS=RC;A%+1=R$h1N<1?c>(ew#jN2U9>9+1sR|=pl9z1d7h4DAqT35dMQF0o; z*e1%JhgNZDC3Y>PzR&6zvTE(m>6Nh&73*WoDJ1+2K zl6f!_Mogghr`6-?%OEvr-qMkXQ*dg@$6FcTJ)5n7#nNX~HX8~!HZXhuIt59q1NWgq zvA$lI-%EpoJ_O_Ute%CB^e)lW_l;4N_%Ynl#JCI0#Nl*He@^~Z8HKz)Z>5wdd^JSz zS1{zhdY-6V6mjV)IaSZd`h+}1S1PF4G%b>+8wnzGpSK_Qc;mR2xOdlx)rb-QUy6DF zUHxJl(WLbBnwkf*ab+oai*kJ+hC3cHKATf232`)vNJ@-qY>r`%q0{jyZbD!}OwfUs z6yJICGI_CnYc$`d!s>bJ)28M{^#qDCI_NM?*>KAQCuV)LJv|{i-5vETdLy<5n%ia6 zkw1Y-WBD>55z+Gm1}Xw=Ur}yH-0dri;&l#!cD|!N@ECfGw?1Fd-ROM+4hO~@;PO7e9e4;f z-Dv*5LYte$1j#sU;?W$-$FY9*8o9e+9}lWgjfbyOYKQU7_OM;o0whY3fwC+ z3zHZ0f&1g0Yl6|&L!ytx;QGUsfw~5uPU(DN)? zMbU>-dB+v|qq8OwBwnEUn9Syov?Fgn%q_N$uk9U)y)68)k*pa&z1KOK5n7~NHNt_` z8YGb*!Kc*Ga^#d7fHk0WQ8`SV)Xl%EwT5tGcUlG6D zKpHXvC}Za)*&D8CHB>b}wYphk<&bcq9viGMK;60!mCX|pU6kR?4XMXqj_x^8^jyM& zz#;FR61W}U^Z}i2aET4)CKZ3(HR+`21WliPUmsIx8TOuI{M-qXP&w+LJ}~QtW^Jeu zodRwXgp9v;{5xC2)Dn4#dH$1~pUp+GD3t8=8s_yA zv@K*)PkJCzcwhiDmRc`keOTQ5+k4%gG{ky}0h@)i#zogKK2JHHZXP8l90skboa5wk zH%-RmfFAvW!}$^hb7Jp9P)y3G-zg__G;#%sRtdcAmEC!(r1AETLlxuVj05H;TI>1E zq4km9FyzQMXbw@*t|N;1?vHJ!c%~JF`&T2rf;qTaMq76;6m@uB;#O?st6*3za^e?^ zx{~kTPNqs34{v+vJIFRL8%Wc>GW{$3u^Wj{j;fK+J*Lz`^7KRTgpaPS!sT=yk$=gi zbHO8j7Fu^5_PY2lRZSoL7J2`mu({<%YoULng{S4X^i?N#`HNPQ%nGYdhD>4X#M0I( zn30)ON)dYIFGm$nVMH=1%V2j^f)M*cd?Pw%#Ns}<#9N_)3kN?0<_;k|gSAm!tMB!M zJ^QZYPw=RvMzk+1sB#n}7t+l@Hr}55Y*c3o%R9W0b^?lreRq}v`;D8`Parmk!DDz5 z*G2bx_)3W?va6ry^V=Ke0TAmQ`#4DUSLIqHS zfAvmTZ@JK3_zLbRE}yH%Je>*hmfNTB7moXR+TSA{T^u^7l-zZ@EdGIzbOLv05Le*T z4>OZS26(u;fP0;F#A=(kT*7-`{DaOVvPJ6Va(Txt8n73~b&?l`6NYHCw@yf?|=5RF}9&M zAj6&aa31dL<=Cy6u8e`yaIH9>HVDPIAO(P z-+VMiY@vVac7=e4qxJ~7rOTfZi3Sf0zAvWojju#-3vQx3;`eSqWdffgo{Tc4ya1inJc~@D5#1M)A z#AI<8dcfp=Uw$Vd{3cs=6m4%3328|8CiA*F#i6fcJn+;p5u}xu%mlZ<_ z`h9rNNMB^U{e%O?HNIUwROHFYaCNQ9GD9CT=}u`laLK?k>wF~>$Np@LSU(5`xlWZ6 z@>-bnPNBK>grj4@z{sN@iA6ulVsEzCwyYp^ilP(6YrKxNBLN1#y|u0}dbc{ZwOm<( z#X0K}IvZpE(v$M8*JNO?+HiW^NlsA!HM7*i5{}2#1!xM2C&Ue>5*x-xac@L^5?;`i z=o9c;pu>TC=C0IKw$Ix)AXbhC3C5c|ij__wTTtYW%Th5z0|o6SDBqepj4);oFpBFi zUpr_dfH!hD{sX>CSWPR4Z^kP1g;95CwL_IS=THyFotQI=6N+WMiWgaC5!>F%Ulo#z zagzZIK1inqn}{kP4melQN53Xvfg?S3=D(DkA=}7M3M+x7_JBecM}2=6&Jax3ct%}Z zBo*P|c-X*DRbR@hZaM;m@m{^jj+zX|B!%fZlctfWKnR?=QAx_hNW)}uS{En$aq#zY zOnIF0TBf7^!j*y@Zj(gsr+cnO6GxweI-6#QFo0XcM5c37T1-)PObW}X7<3C~hAz4i zlB#VnYhL2;$oh;Y{U6vt{LtJQ+`$$h(9QR*#f?XgEWVkeyypR0@#Ivw+qg+)%Axup z$g>e(8vPwP_U4^V{%hwBohUZD&B0_zDHe{p*%FnM=I6cja!YEhRHbUh?mS+-d@td~ zE=m{lAdqOfui-Vsm^|v;80^`Wa}`>UnBb>F#<(FE=LFzPNw3tbk5Ve$=kkpC+c1{B ztu)q88?$nofnUM*rF}|9VCY`Qbw{Ie`4F^bsX_iY&KG0}lkL1ogY$c=L`N2vW<=P`v)1s6P0gy5 z0t!n1Go%-`TQ(bSQfIev+A}VtqL3FO|LzsFO+-tIZ=-q?&l2x*lHfw0ka{gmW(*z5 z;yY{8F0OtZ0379?&Yh)QdXS}Ts3#3uRxU>)lIQADcK%8K><0w!-eICAa;Wr67W0IT8F)-7q1kg8?;nnov z@Sd+G%CI~RR}$Y$TNaVd%717PbAli`+xhu06m2K>nI7oH1r=4)_w7eX^E51NKE7z z9UBnUJ+@Tqp7;n>;ilq5vdzNp9qm75a|6zZ<)+wWjKL`Z7O6d$YqS@KaLeArGM13_ z00uOVO(r`!11EI=@&o+G9U)%3{)%Zl!>+Q5j2*bWnotKz8xLq?>QUx{Fl(X`Ut+Hycz~!V;I3w&^_GX#1Bp zTC*C|_z3riW_*A;k*F6I5B{+XHa@Eh7Ug<1+p% z{_7ANbxfS*M8HI*N|4t-n|&&}{l~5f+>@w~<(bDD5sIe`yjJ@*YDvjiBy40QOhj9| zVQIC|@IKHF$QY4+d;nCOF#oe8_X6%SyF!^+R-NtZBip5+XrBnAbE&wqyIA$jV~I%s55CBwB+*&DP|%!wzT zY;&>WkJ8NUKshN~x%(Z9$xa>3@z2YeB+9^9=&rT)xfME$h?&3Jgsz^sO&}m#zL0f- z0(Rlyb!yp8={Wk{g)GLvcqkT+wR}0ovl&wiS0G9)*nvH>@HB@lk~Jf9?fpL6d>TN~ z?kqx0fMGo!yUM6rgWV1*uAI`5Meh0)a4q_itex}#4=}eO2MDt9 z*IMBJnSMQYhc(WO(%|y5@Q_Pd`a-Jzk1hYsAj5h*$&Nil3<Yc89v7=F2ju_Srt>0_hG~ zd+i}&x6T>K0S5`}y3r8M*?J4lSW+hUT?Q=~6s22h(a@P)ke-HpTlVrE#!Fzg2eSFL zZ0YDIywry%6543G)Zvnvi%9$7+wDmXqU`mxu1Qyt8ncb3;37|Uz{hIBcWki|NW#P< z1jg*Ei~D+5Jd1RuaxYpI#Mj);dDs#ObhfT0?%W!RRKH)7E2FUNep~M0TXc_ddgbT4 zmq=SpPh}u6nN%mI_A!NFYgk~JE2f;GrakU1)RHP;wOWs^^g{YmZ}?>5~UoXZ$>C#lp%3g9EVtJ3LZhmixbab|RAx<%m`O(@cD zMZg$|t-N>TVG1j=9GiyD?W;r&qTqhdFs#zmS#zR*fGLr&s2&Ch)c?v19l>tY6QD;2 zXo!Mtajk)c7WQI25#~|Zxg=6%3N_J}-|@E8EZ14|q8YcM!FbMtx_&=S$kHdu0v05o zxCC2U3IyYHN2C}8(0g|mA)`i(N|X~?lqYcy1^-8yxQ1Tpuu3mK!Gi$greq-52}2x% z3CQTcrfDon4y(?{)|H{gmYApOYemF=$3}yfuI&#&?-t{!j-|Kfu1m$Q)?>@}=`%>n zfzq@3$N%QoQgKfju#KFI%BYgX5vRK7HhUp>#v{HU^?^V?eD2kfXSNqD<}r=0gvGv< znK6^Cj8XckRqetrZ<)R)>sd!P#7vJ9OAE0!?2!*zzCSw zE(+UfGnTm*%t$ox6gUd%1^+-4gany`sx!yAIp?(VF5*Vss_6iB{?G=>XNs_L0V)-} z=->hqSt#-Stz8_374TT_Xo;Q=99hLuE`BmS{C|^HXgY6&9lYIWUU0JC$VEi^$Hx)An7gALr3p$gocS?*pT!K zXAGjE#M(9U0W7i7%iO9G02r`cKRE946xeWN7wm5I5FhwDmd5LuWu6O$UqOhUp)ZmJ z7O^cqf4)ilu0wt;Z_$mHG3fHf^| zCqYPJbp)YXKNb8Z>!%7@U1&xgONGGOnz-O8+eT<1-GhZLQ*bWSmX{mb6j*rmm6$ z28?v)k+W3(h{o{Rl21JGdrxqCt^UJNshriE>$%N@r#IVI2soF8gz5k-3CrpqE)tyN zpsMsi9=6Y;28RxsqjtJn<@x?qg566l&tQQW1`hFx*(JNkX$UT-p#1RUW+twUyRE(s zf6Tz0atnTY{9(>&&lHbX4&Vb>ycic)!l@!9iPKTeP!x$eX;{Y&{{x`{vY86B#a?wS zoRHr(cR|^#bhMZ-iTr2*j#2KJ#nam;S>g9M+J*br2lFU{Hg%6qzK zdz)rwbBgQ<{`cc%jH8V1&C&a`5@d6R2k-HpOl~%UW~3?jO5o|_hpXYVpKY-{wH8C- zVKT`0!qTwxGl9*2V$fm{=*^NL!o)cGXFC)OIOfgyHY6%{k=gFLe7W<_rctQY|9 zyVK{CnjfV8Bdq6o7@2#8rw*(8t7Tb%CK+$KHR=Q}XNoGA^`5E~Ncpuen(GG%VZjSS9D5;V`5}moei2HmAnIoJqqNR+TzJYG#mx3 z#pw|NBmhiA@AyXzgK)d?Z+mU<84J;aSci#=){0dJ!P0grrRKBsT3jUJDFKhWSvn&D zyEU{pXEq0vd_ ztUCEH9q@IVeIQ`F3RtgP>KZhgK4lmMT7IHyZx#$SW6(=EI(LpE66ZWB@ZOYSZ9mFN zyD}gn9X6ZVoBOol1RE#Hr0v+p9Op-bhrrdubA*TrF(R1zCa(j-M5>1!PNCvlczV{- z9Csb`0kurE&dL}N>nB#9+=%9?NW@{Fv;7;VQ8ZS5rhDq)VxDN>+<2q%LHS2Un`fgJ zn_Ht^aRLBseadnI)NJfR$E$VuG8jN0s-xCrS>^vLY$r@2F0tq9^@YH98##s@Il|DC zdyqSB$F?jrDK1y*r`-W*tm|zW2r)4~fQ9_gJiqWVGv45|yqf>PnlyUp8jdR~RF9(_-M(#OcSpxFq8qEwK47H=6KVu`jf z=c@zF?mLYsc=?GRs?gL759SNE^6hMe<;CGl6z1yyv>Md_A>R&B=nrV~l^*HLBDPAKY{NUiy= z9_O=@j~Dz{fyxKHF>ca1dsN3flVUji+J66XbAf-QEoK!kIdP4;>MFVH8m;Vqy!hmn zs?+zAg5l*$=Hl2<6pAuy7_9Op{b80tMqjk3$Lx*Al%zm{p6gj@Z7% zIudUQo0I!Gz3DJjnrBsTv|Ry~yv%y#@C$yp$L7tsB(ALF7)#Uhdlh?ax_m)VMCZ6j zc|~Voog(a!JDlUJxk|NAZnHR+e`aT2Z`(*lLx0oIXHs>;RKv`b%|%S;7DeEPafiW5_ZQqW4fXeeTq2lC{52=JfeVA$Z%W}J zee6}_Taj4TujZwiGb3VTaBM5#3&xV#+b+4Co1IkR>(mO{2ke54)G`NzD`kB$_y3!J zx6s&TDhxv^^{vN9`7yO=_L1GT&D188O#kPmRC>Q1+6f8f&UKvJ06OUvGf#(rZ_}Oq zr}TCz*Pjsghp!W$1L(2oTe~hSOSqtsEJd2#K=CXQ+j?_TJqCuDf~_`$n?>nEw5gw8 zHd;tSS!)1{tG=#z1OBz{EEwZd<@f_uv{vgyD{@kM*9T0x3xPHe>j%BUnaWw%1g6S? z3akx_mPh6yfQod!DOyC&^h8bWGkS2MM+L^Zh^h`^FrAcWTg|-5JaYy9pd6J_Ay1bW zOQFCaj`_V3{VzGR^WaxJ+px@!ygx42z!O5~#hbi75QCjDU7mDhQVi1wi71C7pW20m zw%TrKnF*MXmIhQ#btJpQP%g&91%avk-p=*c>bY9bLf;)uSC$G*vSC@0-b@Cgy`POr z6q{LCHQ`O@hICiXLueWL3^3T^_P~>A*?k76h|+xmnlce`^>EuaJ2BEcN^&eAu`5Lc zllS!-bmG^i+~@;W$`Ljc$EnOre#GJRg-+kARcog>UPxhuuVm>>XHyBgF^ z8%CIK!E84u8KqBj`j(mbk`>F{;@J>L4E7!iP=AjXgSLsE#ozFQebv8nMovw%g*U$k zZ>zJeZfig;(dn^EYDKHeetC)^yB|hiAP#kMj~n~#ej(FV$~_W!2B(K0%}cJ|qDV*Z zKhQ&w1c88B6udyl>9BB(CJBif=@g;KE3kwW@+F)7{jotILTP6^*@8Kp-?5XsPD80A zuuXN3THT!3ez>ap{noKG8CYaW6)HbhKdQ*lh~hBtNs`jU5Rwn37-sODzr1E9^F)~M z-DM1kze;-_212-bBn_i#1grFhJzzQEa9PTW$b;b@VKl;;-Whk$t{Qvou`Q`VOG5T) z1$C8I!4Hc;xVU@(bGd4vA`{G!A=45Ky4_hP?6zqV$`gLP4kK@o41fofpl3jw#L@xbu#O}i8)k2wq$T(AG^-GY2pe+w_ICGGss%o$}%r-(L%GD$d3 zZ{9NhkBPK)FYU9E-n^*sBNsF5jSbSUl3Z4r3aAHE{`T{yU#SoTnkgTW<>J$A?&{)( z&;>;y=@wOv%6i-?IovY8VLBdII%JcSGoD2kF-A0@0XbocWDR>&iwcSrpMtr*O_jhc z&KNYW#uhdcL(TkmtUUR~I`$pxsyuW2L!Npm$j-yaJNl}i_YXi?EvhbxQC^D%tv-V= zL*v@iB{^C(5is`V$5OJee!449mKrJB4e5B{qAj}&XKv~58KZ@ihOQ}?k_b{YsrA?e zc0O=ovgAzSv|2JgtuCN-DiVC;(H)&W`{B0c-$I?mqW&8RwIrj#~busOv` z0tgFU&!7XRbNK|Z=_vNuGD4QtJz3?&ao-fL&k|SF9&q11$a#bOPz|~xmVrV>Ox-Ox z(!=y@AJw!Dx9YWauyT2|iP5vCx;dxj50zx9JC_npo1Fm;I9WMI_x>oN%bj00bUT9t z>1!5X{LJDtm6Qg$T|GxXrR7j8QPb~m4HBl|c$h357wmaA4yrVNW=6HsWU{%gi^ntfV1o%ZSm z#L}u>qw0?Mpa;DP;~hz;tMyJULklBM@`nh3Hsc%Fo2-KVhdj!0LZB7umQbL8s!*I) zl#CYZ3~iJa8FkPX5JLF?Wg5!CyxZLX!grWLJZJ;vfrIOZaudlGcyz51!O0pxu|=u0 zS8ziek};z_TH<(rp4VQHXX9b++mhxgEp?5a-Y2TW{Kh^{dlm=gAK#3qM0>g!iHAAg zYDgrAkf+tI@)-II-39alun#eiefv&-dbH5%3N_TE`3jSk_9S48YXK{Sy*DX2{F9P) zIsWCRH&q&dUeCJzJx-IF*qH%bdpD-dg!hP}*}Y0Q9~!E~``p8$rH9P4Y~EvNk6v_I+*6|YE%ag*Nk-X!J!GO{nmOHvR{kY2pJ@}f!5>4yYzPx zzGR1&6j%d4$wR=-93-dqYKA;nt?k|pCfZ5{BJn1V9pn4 zFEw;J(0?^tr%hGo{ZyH9xovMAgKB|}*hpFN7bSef8C+bIo`%K z`y!@pmFp`RB$*C|DEs8dCB!NV)s)a!z4jdx5-3d9 zvZ4~<_m5nnvgntw2mXaV-#{zj&+$#K_Qe5Q3`oo6*zFY}d7J!#m78*^McnVCEpe>%1 z4c~GUL3uk*#rLg4PCaF_r^;m%1g*Q-vVih*-N%7jDl;?+8F|a*K%D%s$XCKa!C^=Y zwP_g;CGEjpv?%iZ zJGi>c>e`F=c%4sO@e217kXmIJM>dC%s2oi~(|Bf&6T4%r&2z0IG7l4yn&6=>H$ zQEgxa@aqg;*(=?)#3e7jiAfj1Uv_OH)dgW_&Q`##Iog*fcK$AxAR~>s#_n{;@V(H_ zW_NZOP~uYAa#W#X({eSK<1`y|R=i5)TdV;cdM3a6jYk2J6Qjy>KPl6Wr8tEIZYNAX z(#EvCx&Y~0TrE1r1r9kUWFbNRqddy+fx}!g5*MltUqCzxHn0|?NLeoEHH%gm&QRG5rq32 zm1x|W>vE|`ymI>bKUz~0)-uI+PiCrC;TD4zfFfK7N&Z)nU(wLawPn08=D>Wki4>SIw~lp!o>(dZSyzHE5)xE?zrVV(C+k;x(TM)N;iPkM*1;_<_PcWxVTc${ zV|==iL_#9trBn-;IY!CsQEr-~?nYvMBcn;9%|ON_x=YYsUb{t5?cLCdRQNV~0j#7y zv0}7mDe%1FBID@uRucbwC~}BRcT@B|5#YYNour9Luh52vKrjUX3QjH&S3}u~C>|8$;4T(3=h9CPKso zpwEgfLtCVEWnMvS)XR1LX6dS2hkOr35C*8OSkQXb&)ToKwM&3vj2oWXkJ{sU@IdCemIGdGK-z)dA>S?w`WR_L?sp*=%Eqr&GQ8OMiOpwTkCWzMTV%U6F4)h*D zDALxX!oz+sFO1xyY}w+X=Vv>1r68sWT=UB}=I?Sm zrD*DGLGWo>d+Ev;9uYrL!qM06EE`!2v-h()lh{{IH)H>|Qi$jEh8*cTKF{8bk&Z5> z$(;g8;96q-f2y^uY16#J=(?jx)^i`3&d7nZr682Xv~ni#&3JjfwEMlJw(LWnV@GWd zN~pCK-cntk$G|r7o|xvY+RGI#4IlwS)}CFvSqQ&aAUz$%O#)!!4VOiiXsaf6fr!dJ zf^*`+cCqk^zEx>p53>-XpW$P24y7L+&BSG>ALp4NL#-dF$gMA_FLZnYZw`jv+Kte| zc@w09EmXov+MtKoQak#y*CHIC`GPTydLHH8Fv60g5rG>OLAB*$QzIF#N~TQ5gZ<{0 z4ukvyeSuT|j3dwwbW$COU)^T=@;%A_Cjv7$5WKJ~iK8!I~q(a0|;w0_* zWBO{4c}wb;4zX-p@ZTR2+A^I;`?0bZuHPIb0zcfH;~3iPW)*XqA5a?~i8&32XucqKQO!V?G4y=fqw`h}Ov@7ecbQU1OE`=WO?OrvS zmxMEvdWZ`PYV7zKd415I5CJRYz|^7F&~!^v$ruJa)P*FwM%flseaNlt*WKL+OxYWk z5bsFy7|jhRWg|3wzZ9usvqN!>g-7CxkoIP!`(wE;K`%8SSF=(hEL8?^WnWKDzSEPx zBfj%;(@leQAFW6fO+!9>r(8=JEWpI-(swCv*ADV+|;a;>3`1hIj#lZQ=*C2(W8fPZ*}>&d^4f9{EyPtWpauJPxa z@Pi+o^IEC;=_1>b1D-BaBpil2o}y&UpzQ*J$srnl`Dm#2#E17@N(*})&Q)%Q)Yu+q z`n#v(*DDF(B-5V$oO0h9zsSOWLY|!q6Mu}rq>eUT7k9zNZi3oT^o7D;`lw^Ai!J*7 zgZ1^5c7H>ZG0gg1sm?l1u5%%UEsxRrJbWY6VbWFc?cWJ`Z-4q4iC7r*0Hpnwb+hTs z`dE*@Agi0xuHPj&uLj2$k+X zWqn8l_-rGBygTJG(%d~w5P@i;UU*tNV9Mb(mNBI(t0J}4k-`^lTN>YI6)-qSx^X5* zpP0(vAcd1e?rtVk3%~>pLQ^@T2mbTcjnWKqZUdd|{NcXOJm%3`lh-uw-3{Lgz4?}n zBCvW1gsNypjgjYIMpsI>`>fDKp>N6+y%`noIeFc?oN>un6(%)QAo> zxPDG^iDIN~dA*mT`G5ND7NxQUEo^EAsy<~R5n;m}42}nHrDJ;t!9_cU)W1_J4$>6% z(bVasKDzw06=P@bp$uLt2B=-e+C&}h9J6al%5D|Si5brM=z8Y2q&kyaxLgl5CfQ76 zBF5@iqdNO}^SYo8a5A9)5>wE2X2D!f^mDjiPs&&k7FzRZsA!oWJh^Q&T&}x>b?{_!@D#e_;@MFA8Mq61;7FYZ?=keN8vCHXrwnHS^$2CE}5}hLyFTVY; zGS@tn3e`F)|1WH))2N2aKsGhx`V5Eb&Uc;)KZhsI;y96jJx$*4WUtf!LP$xC1U}D} z1w^C3TIx1|`#S*Ps7G``xBVT95c5rcB%edkD^CjUlCjWFLdM$$5cQ{;AZ033%ZYiS zG!y_fk9YQd4U4zu7DS+bdf*;yLT&3hvJ+pshozj+wXxp=lm|0uby<%e*u$waN9Ls|=AEY(c=A0B5w+Z_#Uz zrS{SkrPc$cHovWqM-rl4_I9|COLDe&Cif<3>Iv1dRaG{5|vfVf8N`(rI1g*m|7XqUy3g^K)tg?5Pv zU(%zAaiu0(;r@5V0WI2dz%->1U+T=GAYI57rHNPxLVlYCmw~#*LOsW=?jwrbHB*e% zYS{`f{(?Tbv1CVZ-<_l0>pU1+4ZA0>=gF`~XPM{sFpRGx*nERYwg}k0O49E9Ex2s$ zU@~FfhUt#f&xKzdQ#tU@5$ke>Jvx~A)q*G@?NI?K+(tMpLJ{RJc47sXhP|JxejrwB z1{$-cZ>GT2=dFws?zqDuFS5CFIwNx~(Ttcjy@4b$U1rbqxW^@Ofs+@9fwW4i3q~W4oQIeq~RKN3rIaG7WAJ zjc0@wh{d1p9ikHzE~mszgh){oC4moVy{{g*ETsM3`D8v7Vr3<0O{O(gOV73H@cJuj zTuiQKlSMsZcY5YA=K<%t!IvT3O}jl*qcSmB4be_&?{al2Gt^#&y(-EsHUG*+>X*|! zAec+M6CKiEaBdzXi+jj~#L4wDiASGcT0@o@qQY^bLJWpn@JNp3u}6j8V?)}#Mfrw{ zu>2mqd*r|BA!*tz=J*OkAEVaQs4*)X;7Kju)`O8Gt89JCr7BrZfB5 zB5#u6;G_dV*eZY`Sog1Sj`6Kz0IAKR#jD)`pY>u6-#MqV#^?Oq@;1Bxb`twv^U|d| z)lc$w{Xm`eDwl{cRP8V8^jXn-86ke@*#Oa5wkZTeTqaBpfi%(h zc1|Am4Er?sGk=0j;sq5}rsrDO7wqc7fsfU^X;aW+2B_IkA*|N4y-* zQ7nM`2NNes`~bc^X_lU*Cwu2jFq$<~66jfG)0w5wPIsU`&RLouuelBJuR+XYFJIc% zQQ5N+vy`PnPK0-IbR9>8X*{Ejz6PCU%w!Df%GDF#xxtWX8xjoStF|~mOFqFHCtb3z5u0`@^JR%I&EAl7$9`5H(V)B3n{XviOjq@q z;shyLKGNm(T5qv@g(RIW=0%3x_UVD_x0seq7;g(0sjd<} zz<6@^39XkT7T8}8Fd|h5@X;k!uOwwwwI zZo3ot=MryEB6CQ0q(e=;Qep^2bDBAv&UPyk4*!!oeHZMWf!BNqr_tsoqwf!Pt3yjG z=K^xS;0e4Kia7bbJrLEPz~tNFaRuB6Wbv@mqM9b|m)ga9cHV)~rEE%shS+Zs9INla zKWZO%Ae^ky4NQbjNRpkfCijuV^AaA1mUz0;(ckGn>Z=ouNplQA>Aasi%TzMZqi?(x z&=o($-wln`Fh*BH618q^m73#nVcdHi)0RfhmUt13!LXXp@~?bh>>!X2Xu+k@tcx*Y zPe^k?x&^}}suY>uiagY-i^SXPV=zm9tw>wde=h2&Q&47uJAVKV=I&oi%4au*ahPi| z_48;+tBOu=T+j9BV1B1%gn#(M=}M>x@C#Z{~ET&qYebE);P37PN{+ zH{8zWf#na~S3qwSj?)-IdzP|WuN+BdlbOC$!2}=FK+2!~UA5EcVku8`z)K~Zgcypl zhm#>%OOHyW(c|*_esjvA5yQ*5|7w<|Szm!X zify3tq6eKju-`xY;2U!vm0ULc{Hr$B)Xr^g zo&(b0?l69I2qS6C6J4kwUw zjWcrm&xpvFte4sT@`?mHxpp1EB-Mkf#oQ4?L==bfSAX?mTPC7{4Q@QPR+x*qe{LFG zY}8z!G@4gZeXURy8lbZEOie6dP4_7?#BQA5@MhGIEyPZ+K`{_x&q3fo*j?H&RkXuI zPr~}M=Fx4uzI2nohV}}S^4dadw_sFP0Z|r))|~_@)Nlv*x{M(2Qq{3f zm>=4SY6a2z%{F~OCK6~CNP4y#U6sizUG{=UVh3F+2%Jf=-Dzq|E1RrKHTaKUPAswc zjA2(8bLK}hDPNJQ3=VGNSawWPM<<)|Ff}5(I5sWj=2X_b<=yiv?K3z_Z7OIOAVG1H zOa<4n_+u_c9E6dT9Dj>Y1$Dpd{1VMv34HdV_TCl3K80>5!2z z;>Tp(y|B#zr<#00I?c@Gfd-(@z+N&VBhITeVt^Frh+$`mfs#Zz2FG^WTRzn5;!m3v z6S8r3Av^h^uyHO0nNwwD&C&?Yr>fG(fQz2^HL>AFA19dnevkyA(J$t9>p5;;{h%gg6?kYscrt~v5tMwmX($SV} z|AUzv4^29yS@UkogQix4l{YGo_^)AcLE)9^o3y{|*g}2dWqDZrY}YvVQq-=%cJ=6W zkvs+79#{jI*KcqJOe*jb|4X)fIF9c^JQ8qiOrS-O3s*4a`WdeSjtOIifi20@=Dwsl zIQkxW{%lUdg!R1ks}etyiX|gf#zE1Hm{8L@Ip!;GBk@T_qQ2#~y%f5t{8>6#fa@#C zR=~1)x(jGW%it+z>>XaQAmqW|<{4w^J$<-Lv0IBX=3J8O%v=6IRMA};uH>&SO05}9 zDHj+Io99xpMie-lCdF6Mjp_uaL%D{9SzywzTgLe|F?VkCRt}JVX4(b%isoDj6BjJ1 z$xC3=7s_IgxS>N~NDPJw@EN@wo815N7lJ77p<$I6DRpU%2`2A!Pe&^rX;vobR8@`Y zoy&ewJ$RmjDmF1UpVaP!6+h_GU)Razqv0g?BMH z=S==zRS;ZcR)WWE=%NAW@vAYQOBSf>fyNT55z5SYNs#Uf!{GOI56sapJ6si)ozwXN zPok;|1c)mzs%2YpMuWNW;T#j9ehE+=z~KS$KMuf=$*Btu1mJp*?{t*H*c~Amt((=< zeD|v(9Y!>uW6BO4o-(m} z8!J+15oKYkS4 z?ZX19upBKZXS;f=OgT72ytE`qXL&WqAV9%WXEcv?;{Id@O=@!8_mGQY6mw_iO;EI8 zkV>KuI3CR8veRMU#1A zqRO{8iB=3SUrIz-44BMVvJh9?8h_=G8XPxtlbq%OUjz#A5*B-I$(Fba(tb$=mQPM0>V-QiE^X5>v}m5`duJum zGvu_~$V3`pz$<**ii9Q;WRiC4hSu zCqX`BH>qzvI!%ds`x zW^0!gf?6lGBx~Iry3Z5kJNu6fvSrO@7(*%RDf2lmq%c`hQCNz;j*u0PkcK<+XRw;( z@k-7DR5<*DZe(pekWHALH;zIw75)3mmh|=)q;&E;Mr-{X@1)TuSX&o<(fu@DOs5jl}?mEE+r2 zsZKe87;+-}(Ahw%Z>7L(; zq}!}_WvR2L{p<{#@wH>NNc~~trwb!?THHs;#TxFl|5pwtse$mjxd&0(T$afVj;(?S zfY5WX+6nSF~USxU!9hGn^@3-*4RDGp;^M(t|qCLpDrHjzv zuV8AsraiSfP}CS15_0_?Wji{xMT|0CF+)}EA|I%I)SZ570WNX<=ccxtiHC%a=#rbv z1J9PiX)p=+fQ+E0)Yj~`^}hEDX`OHWLlzS?@(;7Ii=6Zkoxglz-qP7Q?It0#8^I-_ zxU+Qv(G8_l!v)9|T+wH0?y_nuKAefXeaUWJZhmRWoKJ-Rd+Rl=*?yCq1JU?|S`q1> zEG4)-eQy})C3mg^@D2gDlHm=$#7^b@IpPbrfQi2xDXa{(&pr|IgWwe%x%Yxv>V<%I zA)$xG`;#P^^&;`Ti3KGSK3q-Q73;rmFc0qT-+rOxRm#JLI4J_H&tUkhE~=$i^ds*~ zT>~arB`GY9%ob2BjEJh?T*>X*keS`-!!j)x3WvYvBbNa0pGfqfzp{tj%96(b7`Sya z-euW<4?RxokL1*W6#}?#YF#Z*rUN(!31tWN^YZ7S(-+RmHYF(5Z|HbBeh$}ewNRR) zcmogU!9^@$)}G*A=5GrBtW*17;9%c9C)C&`klC)2?4Ox1lj5}*v=UNDAL7sF6hpwT zET{LBZ0a7_AAl!4darl^QB^VtlD=o%@bS;f04R$pp@O>Zf-UYKZlZRoHhP&}wbjs< z53OJzU+H5V7*74F4*mb%lPI-kebegwpO*&|*JDbralKp7Hp90#|{eMz$W>ZgsvGyXB zr8)MGu9)UvF91>6^SRUsn80ELQB5BsnqnrR6at58+(`#&qV@{2vi8G~C)U$`v=)zy zgmA}*Kq$Ij8ZqXPjO3;i!!}DYCupESdse}J{@Dj2582eCdlN*~m9_{|l9JS2q!88R zsWQaJZND5Vk|CQA89?nTbdiPtpQjT~`$C1;E4Ah@IO*WdzuKHrj3J@_Q_8Cj}DhQcK@wQ*^hx{mN#q(T%Ko@N*KUqb(U#3%NwJMepp zTPcHMUW#jUIWC<1QAPAMHO%+%SCtoD;XMUDG6eToadM%o1gdJse+7fUto_hu$h<1F_9r zSreS4xEgySikDx;q`Zo|?~1m_F>)hOPn~jt+J(nizOTzFj&;gj&b}zvEWtvN%1XiJp*4ul1Ps~Q2FDdn_;ES&J=s8A%u z05;37x;JVbk{*^Et6DPheRWU3`?5Zyu5)?6b6SroXo-p$>*fX`x2%>!>#Xos>5})J znocYk$TLXBC+I`p*#|PaO=hi9JU<@r%lVkSx`RF^Fu#dW`ya~TD@9HUGChiX6ccxu zsRUd5bJR~4y???92ic+{F`$IaB!6<9?kr{vm;yA+LtyNzuC1*}?6&Rl@tJAVl4`9< ztP8vyUW$pNohms0Nx|!XktUW&D~q*rK*@QOIgF_-Ol8 zU(CRtUw=KAbMcpO(-bvnAx_hkg;E$q5;tuGg=UbHliTd7$`L!;;dS>pPR@ja{d5}w zfG#PP%gCIiX~nQjb=)V(ESDAa99AqrI;dOSK87Yv?cD#%vqCJ!|K$0+-nG&6I+-pfWF{*sE zUpcMjSx$~kI$_$0b;s<1ol9)kk_}R`E*33M%XR;C^#rwfyssSAhsnADJz(tX#zdj_ zRAgR7l0zG&IkqQoY@$?K#XK&LvJzxC*iLe^By)`2?gwJL+kdYI2;p3VJRuYj^wztM ziHiC|*Qq~IJ?Abcm*5SbI&k`T)^gEvFNNCaZ1vPD2>ceR{||UI*X<>iSEPJUwu3Os z|AFTWZtE*NvEbF@T`nKt@GH~19cUJyz)j=R`X*vp`isckoTit60^(o$gYh~TLbOQg zH>72@VhuZ{gRlZ8Ksot3WIWpE`GOD27cKTt0hxTks#A&oAq+|c**AQ!f6iE{ceT6P z6_ptZSXU`E)QX20xTOK11r+_pPOUgA;O9~3V4B&gYaO8tK6bGqkJ%!1)6^2Jxj56K zIkbScdz{f2o;O$PVpRuMh|UxmyKdw&gml67gaTY|&NGk>=U!KD0LUn?)!lJL`5 zvfx4k*`vDE>8dx6s?zM(SlGuTBkBphc-8s?=1z+X<%l4eueTDrYTmfoYPm zMp3QZ-f&LEeC|Idp9+f283=Gyb!)d$)!mkOIBQX{US$9w`VIh!**PB-5R^<}D5x7X zEsy}H?zl=q7`LiH;kULuIK=EOuY2$U3}~0Guy}d{yMqk-54a$?OwMoNo+C?l*|_#_ zLdRIl$Je^BS&w}gdnk_$tmEXgEA2l_?-TkW))|q55mtDSiRXfSM!H{+2x|cVa+*F< zbY(UkrhemV&FNd?Kfvypw_@A~E6InRnRLGSCqMxfx75=?FY6j)gJli+H)1Q))3L1) z3*iHIFIW0YL0dXg!QNr*cgTb^5zu9 z!oE)GwfjA$m;$<+*`ny&OJaeAyh5D4ASm+)mkMdQ&lfENVUAi(G+LBQjNKP>G~$cD zea@`Wu>g+m*0H{n{~ybWvwtn2PzR`mlFVz?2|Xq|ja(de~qR8vBMbP?#r|M6xJH8hWndNM1zykTYFh!I^ z2GRUnM4Q6m=*#r&p1<`qg9Xe+LUrC$1+Q|X$W*36qJ-eTcG!dSM z_s;4KA`?8?rS=Pt>i3(<~_4J@{mpTmQ#>ApwNt_#w7~!~qXRYx_`reeyL8kz7sa3#E54o)W zJ~AE@Q;ZsMNiwY$x#Xavj5-d&h`E2T=ph3w@xtJ}-CpruOCR1O8d2(CtOh0CqUjnW!9qPQ+{ zj8Ydv-?)^h05$fC`ea~$ztTx$SV_;e_bx4~X@}%-NV%g3C2DyqUCHASuTCshjqW(w z(KICTQ&Du_N9yQ(Oqb1Q^h_f*GoA056j2$mVti|aO1d-G*-8c-&Dt^8nBn2u&H;Z) z6*b(EWZ~lYWO*=cx8?oNsKRA35MdMcT?UMDVORl3VVu;?fn{E7>uMneUn`76IIn~o zY|mz2=A1r3I+_##*kJ|L_-{PPX8CBsav9EN%#nfLk{hgZ6Q{o)^-`hR)fKEoT}CS! z0C|7M$Ccs#KL{bB3X2W`Y^a1$$F39dKBs{_JLSatei(Fv7g)stm?SZ8)%@2X7bfP# zk0BBHz54^TIC~);d%g8}rh5%oaTHF2#=1k&wpy(>`b@DOHU2Tpy$m8I=`)U zOpeMLi4tjW51rtJW8Kx%pFqiE(TN2Ig~|NgQ?1L&1hGEDbp-Li2|f7FK^HP`aFG}M zK&=(-PiFggYt}=$);?(eiZMUJ0@oZd|I-0BF4RBwQSnHLlbMxHkwrL5;Kd%foF2sW z!?8GL%j#8g4E0hg<4IfP{aiy}Zog97+7|8T(9>Jp487Hayk;|)Y9(YNG~G`enAP33 zWDFpaN2_^h-FoPv3+^cSw>)xR;TV}@Z^XDb1qlea0w%1K3sfrBE93=68Wc~~kGMVG z%%*#8b8`Lz<1nSs%24QIkMOjj~FK12h8{KU|g5&HPWtrGycDz0G6R4XDscYMQ0L9Co2*)wfHx`iV2cI z5tP)wcNwxwe;LyvVDD!GB-i@W`JkKCc$9El45|s;| zJfry3c2<(n0IR4qLbz8;N;@5hQJI;(M|caw@4sVT-;C*m;ZC(sVzF|QHc;YgrU`fU zy{`9USjw0xaa6T5F>dXmlFi|KlkXsK7@g62N?HX%Oc+#nI+5A{=)GIa-z25Tn0Z; z*q7IcT!0D{rp(chxmA!IOaTUp>)8^U0hg~Eh|NkPQSh6%7aOpR_wTOe?wEZDY^(-> z*ZXs~ZnPmLlvUx=WA4if3?&&b(uSc614@X5M_a5)=r)(qr^Bi&CYB%D+N=5}IYKpe zXS~cusBa_1W4n0EV)C^eE=c-gxZTQWdc5H zlsgrnACMiq{rlQ^v(Y3ifa?;rEzEA01Lp57%z%{yN4|=HC*86bVe@o_!`m$cVY|hp z%m6d~Q*%||I3$C4JOrZpIH@(C=q$T3AlQ(g)R)FG-y6K$)W+4LWq5e5Xlc>gJZ1f} z5)syJjRNB~98IBsRSYc}JXKD~GPs_6jcZU5A6}2ndxV0rKbA}+Kk9hpN3EQv;lrAM zQ`kJ-cMo<4z1<}a2+O_k$RP+)aHj&k>`r65JJ}n3P1IK#@K>l9VPQF<)%=2=v5iLQ zqJ3qfZuJ`F78~&D^-;uv5TZ$c;OB=7n5{ALY-MnV_i|xQvh6vY zaBRht*9(`0iauW2Bk=B=aCUbIet|| z7~W(%PrF(h6i@Os2bPjNj}J@wc#0inx<$iK;dHqBv}~unp@aEnMyf>>0i2evshV*6 zh7DLaHd@g+5@ntEZ@T$$?56$zcFl(%mKY4#m-;fZ%YK!PFTY>YnaJ=7a_wEawrmPU z#sw|RsD}=<^AOsMcI2B#dPRNW?sO5P ziu*VF(veh1eay5drxYzk21_ZZ{IkEFN}`9o>;B=~u}LzE>Lr?`N=^bz1Uj6vuSYRY zN=IJyFxXY3jt|vw9=4Wmkrt^Tha^Zf&?vejWdwcnOu+mq2|CdU1)r`TWS7{z7xq)7 zocvVB1gYcs$zvu*dsYQdMMwmtVs=e?C+Anq<10Q5mm~j;0R`eU047h}kV9SjoX=}w z#NrYr_1g7Zqg416yJ^y$`uiFqg{*!1r4dvFJ~W}}BKY-Ny<;g&doH7fLeyHLmX_3@ z)h8Y3xq?pw{F6-gh0^ZgJnxlSTp6SL6dTFV5JvYFe|Z;HJuJb3Nf?R`jo|(>p~noX zbzwf+0$Z7W5GccgM;S~uJ6TucTi|6ox%Cl*QVBDL2iHDY>m>PWJ5&9!iL^&iZIQ}n z%u-s_(di72GHX6{E6SBBKo)QJ{W=(_ONq1@2Q!0+bKFAu!d`4<Z=b5Cn;3xf}$q*5}mjMa$nrk@S1n{T$w>}j;2zP31~KdI&K!Kf(|Q7={B&vWW*uS||1 z?pO!z*l}^mJ*%DKcI4;Ob6)Fv>_?_pf^aU0192fARkr-8QlfM7yOOZCg{W$VC5H;z z?wZGW%JlG3s9&SAcvyLxBRF`&v6R&H>dy<6kFU?d7{z@Bb~**8ISwuxpU$}NMa~eO zMFuC?duvy;Gko?DgHn#we|ym@TYMOu!LtY!)~Qo9Nr=r}1=jcu#zmBRIq&PQ*>hdN zFv~2EPh>$LId47)eQ~VwQ~*tju-8h=Nj_GO1*5~NR2eam^_db?Ox|ygL&QQRTfGX zV_Qs^IW@RlAWwS;wgT9mRry<4L!eoqrQKOfdzQ!t8Qu0CbACf$d$>GSt_vU-ds?sh zmlYE2J&x0Bya56 z(yf<^!r?Nt1dWS{Ha_e3@1#dgHxG1qG_WvjUzsn2netv$5kXPyj5|XPptY-RPd^QO zEru);tR#fuw505OR!N&8LAhZ4AmeWP(JeY@cL1y~Q?b#WQgnMuSj->qZC&(V zCs4^G3EHPZ5ossLX&FCsz7mJne@K5 zt|ENnH1To-==Vc!NnXOR9o`8WqrbT*b1q2khGP-XY%UP_pKfVw;=BwA|+ z$`S|G59e8ISEC5xOC|+_WEug2AWcR(OR4pGuO$h8xp+!>rBOlC?Or^U?p0py5Qo9s z4siRn?qtW&9ZUJ`N!!+dGus0HGJXICsMXJ*d<2a?r2Z9&OUMZ6^+OXh5?y0-* z&`U^Nx`@wgRmDTUy`K6yj`*IH9%I@yoVmzETp*DJ;x$hK_3zR>IUmlVr|;wX~MS_h|b8 zdV~rcqB>^>BW}>MFzZ6Akq6sUjMq8<0@kwm42p%JG99qU6^QCmeoVM%Xq86hVM}Bg zeIKx6xD?NYb&LOJpkg(b&Whq*p4g5W{_7f4cJ-yaP`8%TqjYKrHlo1H938YzimyBc z#upm^D^jX@@VsrcAuInOCkRYXCDZaMXkb5$r`d9UATG0IzN@O{Y8Y|Y5hvHhFTs_GrT?O=z zep6C9C(W!f^+X1dX3rm<6c4sV9jA4x$`E)Iq;Xjub1!j7l7@RIAUkPa-8YKt>d_o= zJ=;!92syA%=d=pB-rnWs@H4hBDvx?To!y<1oBUGET5eY; z)kEm%_7^dPGqnS{c*|Z=)-A>FpqvvK*}(%$f@6LD|JzxT1^Qg~1pb%|96kkF>_#k; z5P2*h!bVIA*G*D)*B@Twx`dy~jT71=z3XwiuL$2BgNya9yiY3^CTy*h3CsIdxCVs$ zWW6Z)oMAF8Br_2IUs5~yw{FVrL$(?NSBSr-_SKi8DZ8JWqaO}|eZi$$lxC2n>ef@~w~ zCce9X-^%R<-$uy7UygjifHIcdB)&q|@CV3nIg_GErfW-GG&K3cn6fn36Ko0O)o9}Py{zH?o3o{!h?H^dq zPAR|sucs<7y^f)QzWUw{2Sc9urE~D(xLwW9V`wn=Pylxs=!c(q^N6Aw{}Gb+$@K7X zP;LbT^V%5?cwgt&ER$2ZYPt?z)VHb2-H~6Y{DR=$5gN6%HrmN*2Ksj{ge35InkPQs zx@Fpd!$fsMrT1c39=Ogt*`;`lR(24w@UkJ78+2qs_^DM&oEz2*%L+S>qv!5ygvt?+ zCLPwpHxwp)%($?A0Xc{TH8RFR`bgGz!rpNnP8Ut!WjFMqs1e-?HtVEPfZesBgbwQh zjV35an|vT{WDbEbQ3~elAZ9ky#5d>^+q~$~cXN%K#2;uIa9?L7-fhf(8*8fe*WZcS zu&2&#AK83|T%5vMpZsM-u$~v>&NgxF(8!kL!yDRIY?ZJk2cBXRGTpn34 zvr^b3Pz2_Z6Ti{Ws7-OxgZqW}rzRoWjH`C{H@hCqNc#p}#@Kkl05 zc^!iPas>}rAXLj(`_}n?&-7N0-`DJsO^)_=vO);!HN4zoBmTD>!xEg6@GXO#`at}&k2P}#=!V2}S$WdF-Ua#Ao-& z!oKpW`Td1#f7o06{~*to6r3?Ko4HO;*J5~PlaO`adTk-soeDp)(UJob_)ZzwFvsDf z>VGc%d(|oGC@9m;g%tA_q`Auer%*^e9rIOr9;ME#*Ul1C>XiElzQBYCM500o9vgi9 z93(fy0yG+pFASI@gJCx~JWpK`3QLAoHNciwmd?6r?I0t=`8)a_} z3!IZ=fqrI5Y%9c@)WHVCO3szMFyB=of>+```*m|dgzzjL;f}f{WT&L{Y`=de7r5U9 zlzAME;&z>v(Ipr;oJl_b|KOG8UO2a#-~Wf|hlCf>W=#$ysKCiN*yH0BXi9)j;jBZL zKqJ*bt2+wGy3bxm{DnMp%NLjMZsydY^*`qXWwTA-?%=u@{*YyVdcugN+s0ZywaIrG zf&eaAOhMez0NR{zO>PTr#&dq znb`L}O=8CrGZ~Oaj55WS)QGH$z~UHdf7at}JzzhbXVaU;2!*mFxros0h=edgrB0vI z%HJ_#`3>q5gJ4zsl4D}Jr0>fnLN4MZO9Mflne9DnRQD_oXEivWJH}CsAsz^HTW|zE z)kJl^!ZeNeKD|f@L({lJ+a}5~Eb`-oeIAkV8%y(lUTG1P&lD zUM}YuSVM1t+``s?pM9~y%>TgWwYPu-sk*_H=VbaqprC+8Mu^cbb;~+#kMUZDH!~4G zdAR4OEMrnK|K34HYXpp*T< z&*K7ncfNwczOv|D;y>opm#UbMICmEm44#(SaQ04(Y45yRu_-szK=gaPl|=s@d{tno zAHG7*8RU${#szqv#KcJus49ogO;MWMfWL49tSuv8wW+= zy1I4Vig5Bi`mS!#s2ur9qZy;Jo7MA4H`qG^W^?;~t5#$OR1FzCl-ODb{BgP&TDhk@-n_X_N=m6hqd@DUY_PNSbF0y+<0JR9W2-tD=D}Ceo zSXj>3a4zA85U_@Fc2m@O*ZX=n53J76!=7vorn@~E%4Q7ZXhlB6SXNDmvLy3hN$e29b2HB zUz>gN#{9<+Nsr49fJtBFgO+gNo9;Pr?G1`62LK@b%cm(p=?qIhBJenBnW*)`%9o=_ zvTTW{dWl~ZpkEX^<*m4^!zzoIa&{a4L1}cq!0>cW+*odK31broRT@EQ+RZlCT^|w@ z7Lg}*R7{Ca7=DVRz;|g)Wm?XX{_VpWaJrg3cG()nfI0`u$>H3K?4;@~#8W}fiiZ-> zg!6eKc(Tc9fn^unKd_}dc_yu45 zV{TeEdOric>!@u^-)JUmER1Ek2K+Cbmuo$(AhTP4_{k3a&KNa93Cr?G9xA3j(grh= zg`Ar~p0o#LaTM=os*5;upLAgK)-i1S2r*uzV{Fo-;gr)k zba-oRP~oq@zcpvol8!gH|9jVbg?n=2I)$`S9jS=SDdL%t06Cq>0t^YBxhux-mK6Ed z3zL+Yp%et^42#fy1SJ+#E>tY&Xf5Odbs}|-I(*`461@L`MA!mwY~HrJ0Mt$eb%rb_ z@}l*Dj6`SsQLfgcNu473>-0K9lTDI5Nk_q|;sGKM$s7U#3USoliPT>k#tq*i0ob=` z*em*P-QF`K1cma}K~Wmbj*dB>8Qwq)d3hko4{PE0XjBI}ouUtb)L}ay0C)e0F1lNs zh(6u}RYg||?_LP1WJh-`i)=byaj~D3sbS0++}Ra;c5V|~MJ<+P4!0g8v9`ipG|32o zY@-35%Hd+~th~e5&xd+`Fv4@-n6^`~-cTSwy9{{?h+adyk^Sbpcb6M~vEdo*x8x(- zS(q#&!d@}da~xx(JbqmMd?%)0Fr}qgrVMSt>l#Hl4{o@?sgovs6HiF6JUa^tR-G}> z16M*ERe9sisaaUzXqK5!B8KVWc5{i`OuQ`jGA+Ln#HtlVlt0MJqwjJSsjek(i%~y; zg9vuZflE|w8%;M$pFWfbd&uzcTRPvvzOM%{Q!)5hgU|1Tcf}M_z>DGV9w-}?Z!B@n+}nnKo&~@}sdvNV*Q2t^IJ~Y;nLfkk zWq4A-a?aaP6n();`j)w?sBdKcWdNxdK1~Op4e$lyCkOzLL<3WYmRr`?g_EHAy!-(m zvJ=Dpzfzb|HN9S&S&=^XS-HnSaMK@$hqP7It$=W`4xq?<+}EU}OA(|L3CZ@>gPe#l z5n1&8C^!NSM-`h8)AU>=oR(proMwOn$kuWDL5mI!t z&j>k)dHx3m*IU3ObOL4m@-fZraIK8J=h^CuNRP&E_#3)D-A6@6=iKttj*B90`6yJf z{T(}BSs^M6nw;LwZqcJH8yN(k{2=}C4G>T_l}M=OgUrE=T*}@+Jg9sd#@qwAs z!B^H4fjEX$#zniCJ?_GtF)XI>asI~P@UR3Cg2=)=RZAAT)%y~7C7OA z=TDKnYg1H5P64NB1I~#}9QBp)C!jF{)ld9M_>i}0sDNk*x?bdOCv_gOkd>{B$bsMI zZc5R@ZVG^Sd^TEEImAe{J7378Y2958VhEayuM0B+u765QIdb`04+EO*v<=WR+?^QN z1u35XC?IW!QZtKjt0p_WIvCB)-AsFk^hvYcFpjIK!)&k4ze|c_u@JQosvLI`|vL$Ya(O8E$jzl71g;{wyiTQm^Ty+x^G}a zOs7h5q9kRVC58#z(e}Jbs~|xx9W$3e4w>-W!HMGyMkj}p`LSdc%BeC**m(S-zF`mE zqU?NZ)=a;{%SWk>zn6+S78qr6E|7(NX$lX*xkL^1>-uff+@L)w(s=EjLvHadgd>B4 z$aEt;;;g-U(@5a+u-%l{7XRL0#9_{?8D<})Wv#?@D7%Gl|qeZDV&spy!eM1D227+byM!JVATPIRNhGl*S*Z$ zN}xXM*m2L0a7Y!9?yR)KX?AbDvti60F+D3HZ9zO%;o}ZDDaUuv5;jDhWAkd`cx@<@#5A zQt(6-R*6^{QokvdIZS@X94cjm&4j+#{HH_NR6!eA z65DfS<|-5ebg3Zq!b*vL|18OjXYt=k1Had1fvn;+d=nw}ZtIdA{f%A}0-rrN0l}F^ z@m^sIA81$uP>0MsAT^g5Y*Bt`n~YLm=-yk}9Z7QemqdSeXLzU30ZoGPI)yBP#RK<+ zSFxS}{oLVMPwi^-jUH<2vV>QLS0S*lBa%&~Z&>iMaRpfB*ls*dc5^`RY&Lgr@oOoD z!XM7KjG_t)ZU|=Hih^sL!i!{h+x$>>+d7M;KT3!$!0tku1+4Xuh$>T_QORIK5cl6-#l2 zrC90?I-+dm+3~Tt-LQkyUjQ!i+*OMZFE9YLBP1MaOZ9XhDE8FCQU*3NvE7AhMnq25 z$O@LK32*Mf3NcJjFBKrc6ozIUMYaokL1SPOVmwFa!1Rq#Qtx0E2yi;R1jISf;{}*n4s!yZwQnTSJ2y`#jPiu&B$}^c%Y%cBlh~oOHbxc8!0DXYn(j= z!#5ZK6(ZFGGD{>lA2icZ15u5k)k7U%` zN;iRb(o-_vP357}w>q=1bQVd~eR){42zHwMw0McNlX!5^u`?PKYg!9oi`|qGj1Vxp?l}V z!=aWeJ=XHA9x2CIASN`0vcirjL0k~+_o6338TIdK(F4Ab zeEKQ0!$?1o_wAI%O=_Y1K?`)j!x#?%m25@eo1B-iFg(=z-rBwc^2xh~3mDx2ofHIx z>1l4nRry{E$%ipVI>O4cN=CRGgMGv5f}1L5_aN*g+e(Puux<66T}}O5oq4zh`WFf15_`}Cl^S?`Ggko8qU zVhFH`NU(+Ad9Zynf8BC7foXUNO7s%8vbkdZ`oFhpiOg9&9ZD{b+whd~QSwo*474QO z{PB7Z06{gxoKJaYs??QeRI-_{Cu5rk=5fOXOBn(Z9;ykGD$N<#8h>K|Q7R(NXCZ@( z7Yq@N0^*2in17s_;q%%7=$-Y)i7jM!olR z1_la)3qYGFzHMX#b8-Kh=X%e4%@dB^;}IQJ|@u0 zj985m5!mXX<|27$&r&qYPLnFjF2gG&r&~D z!SHsAyYPwS6D`Z77itKQ>_cK`VV4A0yN8G^39tx2IMED>`LSHb0|1m?>Q72zbOlPo z0t;fwoHJYb8HE*-E-quj>XCI0)dpztF21!=m`@HrMhoy$6{gqb<1`fr*c_hYF?ltP zC*{pw#7^@{1@No6ddJ{FtzWVZ?}7F{y01XThnUPS=gO*Fxr5KvRYyo31?=Rg3^(mA z7rx89E=3oxP=7Axysxnvh`@gJ2^v7nT78@W%#QyjLs-*_NM5<6F1%-il+v0?~U0dnP%v$l(8^G z5dr8`ToBqteZR8D67a9{R*AJcpU<0S**!Qy>ABfYQl+R*1loT` zt#M%8ON6ecWo)C481^s5!b>~4QP#6i(0Lv4Oty-tp2|bg2N*1OId-|zE*-PiJV`=PLJ~#aVG>hnQxi(;CES)=_IA3D2KJ5-Z}_M)Z;Qr&&ez;TaW z)FGq=t4i1L*nmVlLMtsl@gBH?f$5#y>=LZyjtZHFV)HvkXQ ze+U?TXOo)m<15DlXCGJ*K-Y>I(l>Rujs+z1WZRr+dEP zqUmElXrkh(>DOBd;~W_ct-4V>%!0FDESQCBkKrlpQTt|_v;eo{2$^gJ{tkLL)SW2GI2BW|zh9POM%1D694Zm;Cn z4x7GS$;pC=;{h|?Hc?W73r9qB+LpyVGv7kpeC>*Vz$ha-DBtC~Do7ZBmLz3fH-6^& zt4&SN$fbhuCFXi~+*}LroVOkGkXO=zn4pQD(gSIb49H?!3$~XiU;n!`5o>&h-(gFsml4? CustomNetworkConfig -# ios_config -> dumps, NetworkConfig - -- debug: msg="START cli/common_config.yaml on connection={{ ansible_connection }}" - -# Hit NetworkConfig -- name: set hostname - ios_config: - lines: ['hostname ios-smoke'] - match: none - provider: "{{ cli }}" - -- name: hit diff_ignore_lines - ios_config: - lines: ['hostname ios-smoke-diff'] - diff_ignore_lines: - - hostname ios-smoke - save_when: modified - provider: "{{ cli }}" - -- name: return hostname - ios_config: - lines: ['hostname {{ shorter_hostname }}'] - match: none - provider: "{{ cli }}" - -- name: hit items with parents - ios_config: - lines: ['permit ip any any log'] - parents: ['ip access-list extended test'] - provider: "{{ cli }}" - match: exact - register: result - -- name: teardown - ios_config: - lines: - - 'no ip access-list extended test' - match: none - provider: "{{ cli }}" - -- name: setup test NetworkConfig.difference, replace=block - ios_config: - lines: - - permit ip host 192.0.2.1 any log - - permit ip host 192.0.2.2 any log - - permit ip host 192.0.2.3 any log - parents: ['ip access-list extended test'] - before: ['no ip access-list extended test'] - after: ['exit'] - provider: "{{ cli }}" - match: none - -- name: test NetworkConfig.difference, replace=block - ios_config: - lines: - - permit ip host 192.0.2.1 any log - - permit ip host 192.0.2.2 any log - - permit ip host 192.0.2.3 any log - - permit ip host 192.0.2.4 any log - parents: ['ip access-list extended test'] - replace: block - after: ['exit'] - provider: "{{ cli }}" - register: result - -- assert: - that: - - "result.changed == true" - - "'ip access-list extended test' in result.updates" - - "'permit ip host 192.0.2.1 any log' in result.updates" - - "'permit ip host 192.0.2.2 any log' in result.updates" - - "'permit ip host 192.0.2.3 any log' in result.updates" - - "'permit ip host 192.0.2.4 any log' in result.updates" - -- name: teardown- NetworkConfig.difference, replace=block - ios_config: - lines: - - no ip access-list extended test - match: none - provider: "{{ cli }}" - -# CustomNetworkConfig -# currently gets skipped because switch_type != 'L2' -- set_fact: switch_type="{{ switch_type }}" - -- block: - - - name: setup - remove config used in test(part1) - ios_config: - lines: - - no interface port-channel 20 - provider: "{{ cli }}" - ignore_errors: yes - - - name: setup - remove config used in test(part2) - ios_config: - lines: - - no interface port-channel 5 - provider: "{{ cli }}" - ignore_errors: yes - - - name: setup - remove config used in test(part3) - ios_config: - lines: - - no channel-group 20 mode active - provider: "{{ cli }}" - parents: "{{ item }}" - loop: - - interface GigabitEthernet0/1 - - interface GigabitEthernet0/2 - - - name: create linkagg - ios_linkagg: &create - group: 20 - state: present - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.changed == true" - - "'interface port-channel 20' in result.commands" - - - name: set link aggregation group to members - ios_linkagg: &configure_member - group: 20 - mode: active - members: - - GigabitEthernet0/1 - - GigabitEthernet0/2 - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.changed == true" - - "'interface GigabitEthernet0/1' in result.commands" - - "'channel-group 20 mode active' in result.commands" - - "'interface GigabitEthernet0/2' in result.commands" - - "'channel-group 20 mode active' in result.commands" - - - name: remove link aggregation group from member - ios_linkagg: &remove_member - group: 20 - mode: active - members: - - GigabitEthernet0/2 - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.changed == true" - - "'interface GigabitEthernet0/1' in result.commands" - - "'no channel-group 20 mode active' in result.commands" - - - name: remove linkagg - ios_linkagg: &remove - group: 20 - state: absent - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.changed == true" - - "'no interface port-channel 20' in result.commands" - - - name: create aggregate of linkagg definitions - ios_linkagg: &create_agg - aggregate: - - { group: 5 } - - { group: 20, mode: active, members: ['GigabitEthernet0/1'] } - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.changed == true" - - "'interface port-channel 5' in result.commands" - - "'interface port-channel 20' in result.commands" - - "'interface GigabitEthernet0/1' in result.commands" - - "'channel-group 20 mode active' in result.commands" - - - name: teardown(part1) - ios_config: - lines: - - no interface port-channel 20 - provider: "{{ cli }}" - ignore_errors: yes - - - name: teardown(part2) - ios_config: - lines: - - no interface port-channel 5 - provider: "{{ cli }}" - ignore_errors: yes - - - name: teardown(part3) - ios_config: - lines: - - no channel-group 20 mode active - provider: "{{ cli }}" - parents: "{{ item }}" - loop: - - interface GigabitEthernet0/1 - - interface GigabitEthernet0/2 - - when: switch_type == 'L2' - -- debug: msg="END cli/common_config.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_smoke/tests/cli/common_utils.yaml b/test/integration/targets/ios_smoke/tests/cli/common_utils.yaml deleted file mode 100644 index 6b1f6b4e9de..00000000000 --- a/test/integration/targets/ios_smoke/tests/cli/common_utils.yaml +++ /dev/null @@ -1,152 +0,0 @@ ---- -# ios_command -> ComplexList -# ios_interface -> conditional, remove_default_spec -# ios_logging -> validate_ip_address -# ios_l3_interface -> is_netmask, is_masklen, to_subnet, to_netmask, to_masklen - -#ComplexList already covered - -- debug: msg="START ios_smoke cli/common_utils.yaml on connection={{ ansible_connection }}" - -# hit is_netmask(), is_masklen(), to_netmask(), to_masklen() -- name: Delete interface ipv4 and ipv6 address(setup) - ios_l3_interface: - name: "{{ test_interface }}" - state: absent - provider: "{{ cli }}" - register: result - -- name: Setup - Ensure interfaces are switchport - ios_config: - lines: - - no shutdown - parents: - - "interface {{ item }}" - provider: "{{ cli }}" - loop: - - "{{ test_interface }}" - - "{{ test_interface2 }}" - -- name: Configure interface ipv4 address - ios_l3_interface: - name: "{{ test_interface }}" - ipv4: 192.168.20.1/24 - state: present - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == true' - - '"interface {{ test_interface }}" in result.commands' - - '"ip address 192.168.20.1 255.255.255.0" in result.commands' - -- name: test invalid subnet - ios_l3_interface: - name: "{{ test_interface }}" - ipv4: 192.168.20.1/45 - state: present - provider: "{{ cli }}" - register: result - ignore_errors: yes - -- debug: var=result - -- assert: - that: - - 'result.failed == true' - -- name: Change ipv4 and ipv6 address using aggregate - ios_l3_interface: - aggregate: - - { name: "{{ test_interface }}", ipv4: 193.167.1.1/8, ipv6: "fd5a:12c9:2201:4::4/32" } - - { name: "{{ test_interface2 }}", ipv4: 192.169.2.2/24, ipv6: "fd5b:12c9:2201:5::5/90" } - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == true' - - '"interface {{ test_interface }}" in result.commands' - - '"ip address 193.167.1.1 255.0.0.0" in result.commands' - - '"ipv6 address fd5a:12c9:2201:4::4/32" in result.commands' - - '"interface {{ test_interface2 }}" in result.commands' - - '"ip address 192.169.2.2 255.255.255.0" in result.commands' - - '"ipv6 address fd5b:12c9:2201:5::5/90" in result.commands' - -- name: Delete ipv4 and ipv6 address using aggregate - ios_l3_interface: - aggregate: - - { name: "{{ test_interface }}" } - - { name: "{{ test_interface2 }}" } - state: absent - provider: "{{ cli }}" - register: result - -# hit validate_ip_address() -- name: Remove host logging - setup - net_logging: - dest: host - name: 172.16.0.1 - state: absent - provider: "{{ cli }}" - -- name: Remove host logging - teardown - net_logging: - dest: host - name: 172.16.0.1 - state: absent - provider: "{{ cli }}" - -# hit conditional(), remove_default_spec() -- name: Check intent arguments - ios_interface: - name: "{{ test_interface }}" - state: up - provider: "{{ cli }}" - register: result - -- assert: - that: - - "result.failed == false" - -- name: Check intent arguments (failed condition) - ios_interface: - name: "{{ test_interface }}" - state: down - provider: "{{ cli }}" - ignore_errors: yes - register: result - -- assert: - that: - - "result.failed == true" - - "'state eq(down)' in result.failed_conditions" - -- name: Config + intent - ios_interface: - name: "{{ test_interface }}" - enabled: False - state: down - provider: "{{ cli }}" - register: result - -- assert: - that: - - "result.failed == false" - -- name: Config + intent (fail) - ios_interface: - name: "{{ test_interface }}" - enabled: False - provider: "{{ cli }}" - state: up - ignore_errors: yes - register: result - -- assert: - that: - - "result.failed == true" - - "'state eq(up)' in result.failed_conditions" - -- debug: msg="END ios_smoke cli/common_utils.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_smoke/tests/cli/misc_tests.yaml b/test/integration/targets/ios_smoke/tests/cli/misc_tests.yaml deleted file mode 100644 index dfe513eac4b..00000000000 --- a/test/integration/targets/ios_smoke/tests/cli/misc_tests.yaml +++ /dev/null @@ -1,41 +0,0 @@ ---- -- debug: msg="START ios_smoke cli/misc_tests.yaml on connection={{ ansible_connection }}" - -# hit network.ios.ios- get_defaults_flag() -- name: setup - ios_config: - commands: - - no description - - shutdown - parents: - - interface Loopback999 - match: none - provider: "{{ cli }}" - -- name: configure device with defaults included - ios_config: - src: defaults/config.j2 - defaults: yes - provider: "{{ cli }}" - register: result - -- name: run ios commands to test command_timeout - ios_command: - commands: - - show running-config all - - show interfaces - - show running-config all - vars: - ansible_command_timeout: 1 - ansible_buffer_read_timeout: 2 - ignore_errors: True - register: result - when: ansible_connection == 'network_cli' - -- assert: - that: - - 'result.failed == true' - - "'timeout value 1 seconds reached' in result.msg" - when: ansible_connection == 'network_cli' - -- debug: msg="END ios_smoke cli/misc_tests.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_smoke/tests/cli/reboot.yaml b/test/integration/targets/ios_smoke/tests/cli/reboot.yaml deleted file mode 100644 index 6f9a77b255c..00000000000 --- a/test/integration/targets/ios_smoke/tests/cli/reboot.yaml +++ /dev/null @@ -1,19 +0,0 @@ ---- -- block: - - cli_command: - command: reload - prompt: - - "yes/no" - - "confirm" - answer: - - "no" - - "y" - check_all: yes - - - wait_for_connection: - delay: 20 - sleep: 10 - - - cli_command: - command: show version - when: ansible_connection.endswith("network_cli") diff --git a/test/integration/targets/ios_static_route/defaults/main.yaml b/test/integration/targets/ios_static_route/defaults/main.yaml deleted file mode 100644 index 5f709c5aac1..00000000000 --- a/test/integration/targets/ios_static_route/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" diff --git a/test/integration/targets/ios_static_route/meta/main.yaml b/test/integration/targets/ios_static_route/meta/main.yaml deleted file mode 100644 index 159cea8d383..00000000000 --- a/test/integration/targets/ios_static_route/meta/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_ios_tests diff --git a/test/integration/targets/ios_static_route/tasks/cli.yaml b/test/integration/targets/ios_static_route/tasks/cli.yaml deleted file mode 100644 index 6b93fd5400e..00000000000 --- a/test/integration/targets/ios_static_route/tasks/cli.yaml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- name: collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - register: test_cases - delegate_to: localhost - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=network_cli) - include: "{{ test_case_to_run }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli - -- name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_local diff --git a/test/integration/targets/ios_static_route/tasks/main.yaml b/test/integration/targets/ios_static_route/tasks/main.yaml deleted file mode 100644 index 415c99d8b12..00000000000 --- a/test/integration/targets/ios_static_route/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/ios_static_route/tests/cli/basic.yaml b/test/integration/targets/ios_static_route/tests/cli/basic.yaml deleted file mode 100644 index c58a0e3408d..00000000000 --- a/test/integration/targets/ios_static_route/tests/cli/basic.yaml +++ /dev/null @@ -1,144 +0,0 @@ ---- -- debug: msg="START ios cli/ios_static_route.yaml on connection={{ ansible_connection }}" - -- name: Clear all static routes - ios_static_route: &delete_all - aggregate: - - { prefix: 172.16.31.0 } - - { prefix: 172.16.32.0 } - - { prefix: 172.16.33.0 } - - { prefix: 172.16.34.0 } - mask: 255.255.255.0 - next_hop: 10.0.0.8 - state: absent - provider: "{{ cli }}" - -- name: create static route - ios_static_route: - prefix: 172.16.31.0 - mask: 255.255.255.0 - next_hop: 10.0.0.8 - state: present - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.commands == ["ip route 172.16.31.0 255.255.255.0 10.0.0.8"]' - -- name: Verify idempotence with default admin_distance - ios_static_route: - prefix: 172.16.31.0 - mask: 255.255.255.0 - next_hop: 10.0.0.8 - admin_distance: 1 - state: present - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == false' - -- name: modify admin distance of static route - ios_static_route: &admin2 - prefix: 172.16.31.0 - mask: 255.255.255.0 - next_hop: 10.0.0.8 - admin_distance: 2 - state: present - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.commands == ["ip route 172.16.31.0 255.255.255.0 10.0.0.8 2"]' - -- name: modify admin distance of static route again (idempotent) - ios_static_route: *admin2 - register: result - -- assert: - that: - - 'result.changed == false' - -- name: Verify idempotence with unspecified admin_distance - ios_static_route: - prefix: 172.16.31.0 - mask: 255.255.255.0 - next_hop: 10.0.0.8 - state: present - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == false' - -- name: delete static route - ios_static_route: &delete - prefix: 172.16.31.0 - mask: 255.255.255.0 - next_hop: 10.0.0.8 - state: absent - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.commands == ["no ip route 172.16.31.0 255.255.255.0 10.0.0.8"]' - -- name: delete static route again (idempotent) - ios_static_route: *delete - register: result - -- assert: - that: - - 'result.changed == false' - -- name: Add static route aggregates - ios_static_route: - aggregate: - - { prefix: 172.16.32.0 } - - { prefix: 172.16.33.0 } - mask: 255.255.255.0 - next_hop: 10.0.0.8 - state: present - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.commands == ["ip route 172.16.32.0 255.255.255.0 10.0.0.8", "ip route 172.16.33.0 255.255.255.0 10.0.0.8"]' - -- name: Add and remove static route aggregates with overrides - ios_static_route: - aggregate: - - { prefix: 172.16.32.0 } - - { prefix: 172.16.33.0, state: absent } - - { prefix: 172.16.34.0 } - mask: 255.255.255.0 - next_hop: 10.0.0.8 - state: present - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.commands == ["no ip route 172.16.33.0 255.255.255.0 10.0.0.8", "ip route 172.16.34.0 255.255.255.0 10.0.0.8"]' - -- name: Remove static route aggregates - ios_static_route: *delete_all - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.commands == ["no ip route 172.16.32.0 255.255.255.0 10.0.0.8", "no ip route 172.16.34.0 255.255.255.0 10.0.0.8"]' - -- debug: msg="END ios cli/ios_static_route.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_static_route/tests/cli/net_static_route.yaml b/test/integration/targets/ios_static_route/tests/cli/net_static_route.yaml deleted file mode 100644 index 3e7c99d4c6c..00000000000 --- a/test/integration/targets/ios_static_route/tests/cli/net_static_route.yaml +++ /dev/null @@ -1,33 +0,0 @@ ---- -- debug: msg="START ios cli/net_static_route.yaml on connection={{ ansible_connection }}" - -# Add minimal testcase to check args are passed correctly to -# implementation module and module run is successful. - -- name: delete static route - setup - net_static_route: &delete - prefix: 172.16.31.0 - mask: 255.255.255.0 - next_hop: 10.0.0.8 - state: absent - provider: "{{ cli }}" - -- name: create static route using platform agnostic module - net_static_route: - prefix: 172.16.31.0 - mask: 255.255.255.0 - next_hop: 10.0.0.8 - admin_distance: 1 - state: present - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.commands == ["ip route 172.16.31.0 255.255.255.0 10.0.0.8 1"]' - -- name: delete static route - teardown - net_static_route: *delete - -- debug: msg="END ios cli/net_static_route.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_static_routes/defaults/main.yaml b/test/integration/targets/ios_static_routes/defaults/main.yaml deleted file mode 100644 index 164afead284..00000000000 --- a/test/integration/targets/ios_static_routes/defaults/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -testcase: "[^_].*" -test_items: [] diff --git a/test/integration/targets/ios_static_routes/meta/main.yaml b/test/integration/targets/ios_static_routes/meta/main.yaml deleted file mode 100644 index 32cf5dda7ed..00000000000 --- a/test/integration/targets/ios_static_routes/meta/main.yaml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] diff --git a/test/integration/targets/ios_static_routes/tasks/cli.yaml b/test/integration/targets/ios_static_routes/tasks/cli.yaml deleted file mode 100644 index 337e34133b0..00000000000 --- a/test/integration/targets/ios_static_routes/tasks/cli.yaml +++ /dev/null @@ -1,20 +0,0 @@ ---- -- name: Collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - use_regex: true - register: test_cases - delegate_to: localhost - -- name: Set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - delegate_to: localhost - -- name: Run test case (connection=network_cli) - include: "{{ test_case_to_run }}" - vars: - ansible_connection: network_cli - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run diff --git a/test/integration/targets/ios_static_routes/tasks/main.yaml b/test/integration/targets/ios_static_routes/tasks/main.yaml deleted file mode 100644 index 415c99d8b12..00000000000 --- a/test/integration/targets/ios_static_routes/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/ios_static_routes/tests/cli/_intial_setup_config.yaml b/test/integration/targets/ios_static_routes/tests/cli/_intial_setup_config.yaml deleted file mode 100644 index a6b390ad043..00000000000 --- a/test/integration/targets/ios_static_routes/tests/cli/_intial_setup_config.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -- name: Intitial Setup Config - cli_config: - config: "{{ lines }}" - vars: - lines: | - vrf definition ansible_temp_vrf - address-family ipv4 - ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 tag 50 name test_vrf track 150 - ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 - ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 - ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 tag 40 name route_1 multicast - ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name test_v6 diff --git a/test/integration/targets/ios_static_routes/tests/cli/_populate_config.yaml b/test/integration/targets/ios_static_routes/tests/cli/_populate_config.yaml deleted file mode 100644 index e6275cc7e27..00000000000 --- a/test/integration/targets/ios_static_routes/tests/cli/_populate_config.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- name: Populate Config - cli_config: - config: "{{ lines }}" - vars: - lines: | - ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 tag 50 name test_vrf track 150 - ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 - ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 - ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 tag 40 name route_1 multicast - ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name test_v6 diff --git a/test/integration/targets/ios_static_routes/tests/cli/_remove_config.yaml b/test/integration/targets/ios_static_routes/tests/cli/_remove_config.yaml deleted file mode 100644 index acfd6cc8e5d..00000000000 --- a/test/integration/targets/ios_static_routes/tests/cli/_remove_config.yaml +++ /dev/null @@ -1,12 +0,0 @@ ---- -- name: Remove Config - cli_config: - config: "{{ lines }}" - vars: - lines: | - no ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 tag 50 name test_vrf track 150 - no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3 - no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2 - no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 tag 40 name route_1 multicast - no ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 tag 105 name test_v6 - no vrf definition ansible_temp_vrf diff --git a/test/integration/targets/ios_static_routes/tests/cli/deleted.yaml b/test/integration/targets/ios_static_routes/tests/cli/deleted.yaml deleted file mode 100644 index 2d3967b129d..00000000000 --- a/test/integration/targets/ios_static_routes/tests/cli/deleted.yaml +++ /dev/null @@ -1,66 +0,0 @@ ---- -- debug: - msg: "Start Deleted integration state for ios_static_routes ansible_connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _intial_setup_config.yaml - -- block: - - name: Delete attributes of provided configured interfaces - ios_static_routes: &deleted - config: - - vrf: ansible_temp_vrf - address_families: - - afi: ipv4 - routes: - - dest: 192.0.2.0/24 - next_hops: - - forward_router_address: 192.0.2.1 - name: test_vrf - tag: 50 - track: 150 - - address_families: - - afi: ipv4 - routes: - - dest: 198.51.100.0/24 - next_hops: - - forward_router_address: 198.51.101.1 - name: route_1 - distance_metric: 110 - tag: 40 - multicast: True - - forward_router_address: 198.51.101.2 - name: route_2 - distance_metric: 30 - - forward_router_address: 198.51.101.3 - name: route_3 - - afi: ipv6 - routes: - - dest: 2001:DB8:0:3::/64 - next_hops: - - forward_router_address: 2001:DB8:0:3::2 - name: test_v6 - tag: 105 - state: deleted - register: result - - - assert: - that: - - "result.commands|length == 5" - - "result.changed == true" - - "result.commands|symmetric_difference(deleted.commands) == []" - - - name: Delete attributes of all configured interfaces (IDEMPOTENT) - ios_static_routes: *deleted - register: result - - - name: Assert that the previous task was idempotent - assert: - that: - - "result.commands|length == 0" - - "result.changed == false" - - always: - - include_tasks: _populate_config.yaml - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_static_routes/tests/cli/empty_config.yaml b/test/integration/targets/ios_static_routes/tests/cli/empty_config.yaml deleted file mode 100644 index 0cf39e734ae..00000000000 --- a/test/integration/targets/ios_static_routes/tests/cli/empty_config.yaml +++ /dev/null @@ -1,58 +0,0 @@ ---- -- debug: - msg: "START ios_static_routes empty_config.yaml integration tests on connection={{ ansible_connection }}" - -- name: Merged with empty config should give appropriate error message - ios_static_routes: - config: - state: merged - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state merged' - -- name: Replaced with empty config should give appropriate error message - ios_static_routes: - config: - state: replaced - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state replaced' - -- name: Overridden with empty config should give appropriate error message - ios_static_routes: - config: - state: overridden - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state overridden' - -- name: Rendered with empty config should give appropriate error message - ios_static_routes: - config: - state: rendered - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state rendered' - -- name: Parsed with empty config should give appropriate error message - ios_static_routes: - running_config: - state: parsed - register: result - ignore_errors: True - -- assert: - that: - - result.msg == 'value of running_config parameter must not be empty for state parsed' diff --git a/test/integration/targets/ios_static_routes/tests/cli/gathered.yaml b/test/integration/targets/ios_static_routes/tests/cli/gathered.yaml deleted file mode 100644 index 4377f544d00..00000000000 --- a/test/integration/targets/ios_static_routes/tests/cli/gathered.yaml +++ /dev/null @@ -1,22 +0,0 @@ ---- -- debug: - msg: "START ios_static_routes gathered integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _intial_setup_config.yaml - -- block: - - name: Gather the provided configuration with the exisiting running configuration - ios_static_routes: &gathered - config: - state: gathered - register: result - - - name: Assert that gathered dicts was correctly generated - assert: - that: - - "result['changed'] == false" - - always: - - include_tasks: _remove_config.yaml \ No newline at end of file diff --git a/test/integration/targets/ios_static_routes/tests/cli/merged.yaml b/test/integration/targets/ios_static_routes/tests/cli/merged.yaml deleted file mode 100644 index 26825412ca4..00000000000 --- a/test/integration/targets/ios_static_routes/tests/cli/merged.yaml +++ /dev/null @@ -1,66 +0,0 @@ ---- -- debug: - msg: "START Merged ios_static_routes state for integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _intial_setup_config.yaml - -- block: - - name: Merge provided configuration with device configuration - ios_static_routes: &merged - config: - - vrf: ansible_temp_vrf - address_families: - - afi: ipv4 - routes: - - dest: 192.0.2.0/24 - next_hops: - - forward_router_address: 192.0.2.1 - name: merged_vrf - tag: 50 - track: 150 - - address_families: - - afi: ipv4 - routes: - - dest: 198.51.100.0/24 - next_hops: - - forward_router_address: 198.51.101.1 - name: merged_route_1 - distance_metric: 110 - tag: 40 - multicast: True - - forward_router_address: 198.51.101.2 - name: merged_route_2 - distance_metric: 30 - - forward_router_address: 198.51.101.3 - name: merged_route_3 - - afi: ipv6 - routes: - - dest: 2001:DB8:0:3::/64 - next_hops: - - forward_router_address: 2001:DB8:0:3::2 - name: merged_v6 - tag: 105 - state: merged - register: result - - - assert: - that: - - "result.commands|length == 5" - - "result.changed == true" - - "result.commands|symmetric_difference(merged.commands) == []" - - - name: Merge provided configuration with device configuration (IDEMPOTENT) - ios_static_routes: *merged - register: result - - - name: Assert that the previous task was idempotent - assert: - that: - - "result.commands|length == 0" - - "result['changed'] == false" - - always: - - include_tasks: _populate_config.yaml - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_static_routes/tests/cli/overridden.yaml b/test/integration/targets/ios_static_routes/tests/cli/overridden.yaml deleted file mode 100644 index 02b6acb6a87..00000000000 --- a/test/integration/targets/ios_static_routes/tests/cli/overridden.yaml +++ /dev/null @@ -1,58 +0,0 @@ ---- -- debug: - msg: "START Overridden ios_static_routes state for integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _intial_setup_config.yaml - -- block: - - name: Override device configuration of all interfaces with provided configuration - ios_static_routes: &overridden - config: - - vrf: ansible_temp_vrf - address_families: - - afi: ipv4 - routes: - - dest: 192.0.2.0/24 - next_hops: - - forward_router_address: 192.0.2.1 - name: override_vrf - tag: 50 - track: 150 - - address_families: - - afi: ipv4 - routes: - - dest: 198.51.100.0/24 - next_hops: - - forward_router_address: 198.51.101.3 - name: override_route - - afi: ipv6 - routes: - - dest: 2001:DB8:0:3::/64 - next_hops: - - forward_router_address: 2001:DB8:0:3::2 - name: override_v6 - tag: 175 - state: overridden - register: result - - - assert: - that: - - "result.commands|length == 8" - - "result.changed == true" - - "result.commands|symmetric_difference(overridden.commands) == []" - - - name: Override device configuration of all interfaces with provided configuration (IDEMPOTENT) - ios_static_routes: *overridden - register: result - - - name: Assert that task was idempotent - assert: - that: - - "result.commands|length == 0" - - "result['changed'] == false" - - always: - - include_tasks: _populate_config.yaml - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_static_routes/tests/cli/rendered.yaml b/test/integration/targets/ios_static_routes/tests/cli/rendered.yaml deleted file mode 100644 index 9805efebaf9..00000000000 --- a/test/integration/targets/ios_static_routes/tests/cli/rendered.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -- debug: - msg: "START ios_static_routes rendered integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _intial_setup_config.yaml - -- block: - - name: Rendered the provided configuration with the exisiting running configuration - ios_static_routes: &rendered - config: - - vrf: ansible_temp_vrf - address_families: - - afi: ipv4 - routes: - - dest: 192.0.2.0/24 - next_hops: - - forward_router_address: 192.0.2.1 - name: test_vrf - tag: 50 - track: 150 - - address_families: - - afi: ipv4 - routes: - - dest: 198.51.100.0/24 - next_hops: - - forward_router_address: 198.51.101.1 - name: route_1 - distance_metric: 110 - tag: 40 - multicast: True - - forward_router_address: 198.51.101.2 - name: route_2 - distance_metric: 30 - - forward_router_address: 198.51.101.3 - name: route_3 - - afi: ipv6 - routes: - - dest: 2001:DB8:0:3::/64 - next_hops: - - forward_router_address: 2001:DB8:0:3::2 - name: test_v6 - tag: 105 - state: rendered - register: result - - - assert: - that: - - "result.changed == false" - - "result.rendered|symmetric_difference(rendered.commands) == []" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_static_routes/tests/cli/replaced.yaml b/test/integration/targets/ios_static_routes/tests/cli/replaced.yaml deleted file mode 100644 index b7e7badfed2..00000000000 --- a/test/integration/targets/ios_static_routes/tests/cli/replaced.yaml +++ /dev/null @@ -1,61 +0,0 @@ ---- -- debug: - msg: "START Replaced ios_static_routes state for integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _intial_setup_config.yaml - -- block: - - name: Replaces device configuration of listed interfaces with provided configuration - ios_static_routes: &replaced - config: - - vrf: ansible_temp_vrf - address_families: - - afi: ipv4 - routes: - - dest: 192.0.2.0/24 - next_hops: - - forward_router_address: 192.0.2.1 - name: replaced_vrf - tag: 75 - track: 155 - - address_families: - - afi: ipv4 - routes: - - dest: 198.51.100.0/24 - next_hops: - - forward_router_address: 198.51.101.1 - name: replaced_route - distance_metric: 175 - tag: 70 - multicast: True - - afi: ipv6 - routes: - - dest: 2001:DB8:0:3::/64 - next_hops: - - forward_router_address: 2001:DB8:0:3::2 - name: replaced_v6 - tag: 110 - state: replaced - register: result - - - assert: - that: - - "result.commands|length == 7" - - "result.changed == true" - - "result.commands|symmetric_difference(replaced.commands) == []" - - - name: Replaces device configuration of listed interfaces with provided configuration (IDEMPOTENT) - ios_static_routes: *replaced - register: result - - - name: Assert that task was idempotent - assert: - that: - - "result.commands|length == 0" - - "result['changed'] == false" - - always: - - include_tasks: _populate_config.yaml - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_static_routes/tests/cli/rtt.yaml b/test/integration/targets/ios_static_routes/tests/cli/rtt.yaml deleted file mode 100644 index e8a5c6b151c..00000000000 --- a/test/integration/targets/ios_static_routes/tests/cli/rtt.yaml +++ /dev/null @@ -1,78 +0,0 @@ ---- -- debug: - msg: "START ios_static_routes round trip integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- block: - - name: Apply the provided configuration (base config) - ios_static_routes: - config: - - vrf: ansible_temp_vrf - address_families: - - afi: ipv4 - routes: - - dest: 192.0.2.0/24 - next_hops: - - forward_router_address: 192.0.2.1 - name: rtt_vrf - tag: 50 - track: 150 - - address_families: - - afi: ipv4 - routes: - - dest: 198.51.100.0/24 - next_hops: - - forward_router_address: 198.51.101.1 - name: rtt_route_1 - distance_metric: 110 - tag: 40 - multicast: True - state: merged - register: base_config - - - name: Gather static routes facts - ios_facts: - gather_subset: - - "!all" - - "!min" - gather_network_resources: - - static_routes - - - name: Apply the configuration which need to be reverted - ios_static_routes: - config: - - vrf: ansible_temp_vrf - address_families: - - afi: ipv4 - routes: - - dest: 192.0.2.0/24 - next_hops: - - forward_router_address: 192.0.2.12 - name: new_rtt_vrf - tag: 10 - track: 150 - state: overridden - register: result - - - assert: - that: - - "result.commands|length == 2" - - "result.changed == true" - - "result.commands|symmetric_difference(rtt.override_commands) == []" - - - name: Revert back to base config using facts round trip - ios_static_routes: - config: "{{ ansible_facts['network_resources']['static_routes'] }}" - state: overridden - register: revert - - - assert: - that: - - "revert.commands|length == 1" - - "revert.changed == true" - - "revert.commands|symmetric_difference(rtt.override_revert_commands) == []" - - always: - - include_tasks: _populate_config.yaml - - include_tasks: _remove_config.yaml \ No newline at end of file diff --git a/test/integration/targets/ios_static_routes/vars/main.yaml b/test/integration/targets/ios_static_routes/vars/main.yaml deleted file mode 100644 index 30c67c56e95..00000000000 --- a/test/integration/targets/ios_static_routes/vars/main.yaml +++ /dev/null @@ -1,88 +0,0 @@ ---- -deleted: - commands: - - "no ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50" - - "no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40" - - "no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2" - - "no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3" - - "no ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105" - -merged: - commands: - - "ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name merged_vrf track 150 tag 50" - - "ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name merged_route_1 tag 40" - - "ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name merged_route_2" - - "ip route 198.51.100.0 255.255.255.0 198.51.101.3 name merged_route_3" - - "ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name merged_v6 tag 105" - -replaced: - commands: - - "no ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50" - - "no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40" - - "no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2" - - "no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3" - - "ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name replaced_vrf track 155 tag 75" - - "ip route 198.51.100.0 255.255.255.0 198.51.101.1 175 multicast name replaced_route tag 70" - - "ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name replaced_v6 tag 110" - -overridden: - commands: - - "no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40" - - "no ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2" - - "no ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3" - - "no ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50" - - "no ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105" - - "ip route 198.51.100.0 255.255.255.0 198.51.101.3 name override_route" - - "ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name override_vrf track 150 tag 50" - - "ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name override_v6 tag 175" - -rendered: - commands: - - "ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50" - - "ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40" - - "ip route 198.51.100.0 255.255.255.0 198.51.101.2 30 name route_2" - - "ip route 198.51.100.0 255.255.255.0 198.51.101.3 name route_3" - - "ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:3::2 name test_v6 tag 105" - -gathered: - config: - - address_families: - - afi: ipv4 - routes: - - dest: 192.0.2.0/24 - next_hops: - - forward_router_address: 192.0.2.1 - name: test_vrf - tag: 50 - track: 150 - vrf: ansible_temp_vrf - - address_families: - - afi: ipv6 - routes: - - dest: 2001:DB8:0:3::/64 - next_hops: - - forward_router_address: 2001:DB8:0:3::2 - name: test_v6 - tag: 105 - - afi: ipv4 - routes: - - dest: 198.51.100.0/24 - next_hops: - - distance_metric: 110 - forward_router_address: 198.51.101.1 - multicast: true - name: route_1 - tag: 40 - - distance_metric: 30 - forward_router_address: 198.51.101.2 - name: route_2 - - forward_router_address: 198.51.101.3 - name: route_3 - -rtt: - override_commands: - - "no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name rtt_route_1 tag 40" - - "ip route vrf ansible_temp_vrf 192.0.2.0 255.255.255.0 192.0.2.12 name new_rtt_vrf track 150 tag 10" - - override_revert_commands: - - "ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name rtt_route_1 tag 40" diff --git a/test/integration/targets/ios_system/defaults/main.yaml b/test/integration/targets/ios_system/defaults/main.yaml deleted file mode 100644 index 5f709c5aac1..00000000000 --- a/test/integration/targets/ios_system/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" diff --git a/test/integration/targets/ios_system/meta/main.yml b/test/integration/targets/ios_system/meta/main.yml deleted file mode 100644 index 159cea8d383..00000000000 --- a/test/integration/targets/ios_system/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_ios_tests diff --git a/test/integration/targets/ios_system/tasks/cli.yaml b/test/integration/targets/ios_system/tasks/cli.yaml deleted file mode 100644 index 6b93fd5400e..00000000000 --- a/test/integration/targets/ios_system/tasks/cli.yaml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- name: collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - register: test_cases - delegate_to: localhost - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=network_cli) - include: "{{ test_case_to_run }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli - -- name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_local diff --git a/test/integration/targets/ios_system/tasks/main.yaml b/test/integration/targets/ios_system/tasks/main.yaml deleted file mode 100644 index 415c99d8b12..00000000000 --- a/test/integration/targets/ios_system/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/ios_system/tests/cli/net_system.yaml b/test/integration/targets/ios_system/tests/cli/net_system.yaml deleted file mode 100644 index d5e36fea8df..00000000000 --- a/test/integration/targets/ios_system/tests/cli/net_system.yaml +++ /dev/null @@ -1,37 +0,0 @@ ---- -- debug: msg="START ios cli/net_system.yaml on connection={{ ansible_connection }}" - -# Add minimal testcase to check args are passed correctly to -# implementation module and module run is successful. - -- name: setup - ios_config: - lines: - - no ip domain-list ansible.com - - no ip domain-list redhat.com - match: none - provider: "{{ cli }}" - -- name: configure domain_search using platform agnostic module - net_system: - domain_search: - - ansible.com - - redhat.com - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == true - - "'ip domain list ansible.com' in result.commands" - - "'ip domain list redhat.com' in result.commands" - -- name: teardown - ios_config: - lines: - - no ip domain-list ansible.com - - no ip domain-list redhat.com - match: none - provider: "{{ cli }}" - -- debug: msg="END ios cli/net_system.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_system/tests/cli/set_domain_list.yaml b/test/integration/targets/ios_system/tests/cli/set_domain_list.yaml deleted file mode 100644 index d371b7dbd7c..00000000000 --- a/test/integration/targets/ios_system/tests/cli/set_domain_list.yaml +++ /dev/null @@ -1,122 +0,0 @@ ---- -- debug: msg="START cli/set_domain_search.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: - - no ip domain-list ansible.com - - no ip domain-list redhat.com - match: none - provider: "{{ cli }}" - -- name: configure domain_search - ios_system: - domain_search: - - ansible.com - - redhat.com - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == true - - "'ip domain list ansible.com' in result.commands" - - "'ip domain list redhat.com' in result.commands" - -- name: verify domain_search - ios_system: - domain_search: - - ansible.com - - redhat.com - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == false - -- name: remove one entry - ios_system: - domain_search: - - ansible.com - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == true - - "'no ip domain list redhat.com' in result.commands" - -- name: verify remove one entry - ios_system: - domain_search: - - ansible.com - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == false - -- name: add one entry - ios_system: - domain_search: - - ansible.com - - redhat.com - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == true - - "'ip domain list redhat.com' in result.commands" - -- name: verify add one entry - ios_system: - domain_search: - - ansible.com - - redhat.com - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == false - -- name: add and remove one entry - ios_system: - domain_search: - - ansible.com - - eng.ansible.com - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == true - - "'no ip domain list redhat.com' in result.commands" - - "'ip domain list eng.ansible.com' in result.commands" - - result.commands|length == 2 - -- name: verify add and remove one entry - ios_system: - domain_search: - - ansible.com - - eng.ansible.com - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == false - -- name: teardown - ios_config: - lines: - - no ip domain-list ansible.com - - no ip domain-list redhat.com - - no ip domain-list eng.ansible.com - match: none - provider: "{{ cli }}" - -- debug: msg="END cli/set_domain_search.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_system/tests/cli/set_domain_name.yaml b/test/integration/targets/ios_system/tests/cli/set_domain_name.yaml deleted file mode 100644 index 60a4659f653..00000000000 --- a/test/integration/targets/ios_system/tests/cli/set_domain_name.yaml +++ /dev/null @@ -1,36 +0,0 @@ ---- -- debug: msg="START cli/set_domain_name.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: no ip domain-name - match: none - provider: "{{ cli }}" - -- name: configure domain_name - ios_system: - domain_name: eng.ansible.com - provider: "{{ cli }}" - register: result - -- assert: - that: - - "result.changed == true" - -- name: verify domain_name - ios_system: - domain_name: eng.ansible.com - provider: "{{ cli }}" - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - ios_config: - lines: no ip domain-name - match: none - provider: "{{ cli }}" - -- debug: msg="END cli/set_domain_name.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_system/tests/cli/set_hostname.yaml b/test/integration/targets/ios_system/tests/cli/set_hostname.yaml deleted file mode 100644 index 1b39764c6e5..00000000000 --- a/test/integration/targets/ios_system/tests/cli/set_hostname.yaml +++ /dev/null @@ -1,36 +0,0 @@ ---- -- debug: msg="START cli/set_hostname.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: hostname switch - match: none - provider: "{{ cli }}" - -- name: configure hostname - ios_system: - hostname: foo - provider: "{{ cli }}" - register: result - -- assert: - that: - - "result.changed == true" - -- name: verify hostname - ios_system: - hostname: foo - provider: "{{ cli }}" - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - ios_config: - lines: "hostname {{ inventory_hostname }}" - match: none - provider: "{{ cli }}" - -- debug: msg="END cli/set_hostname.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_system/tests/cli/set_lookup_source.yaml b/test/integration/targets/ios_system/tests/cli/set_lookup_source.yaml deleted file mode 100644 index b8cf59d7b2e..00000000000 --- a/test/integration/targets/ios_system/tests/cli/set_lookup_source.yaml +++ /dev/null @@ -1,94 +0,0 @@ ---- -- debug: msg="START cli/set_lookup_source.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: - - no ip domain lookup source-interface Loopback888 - - vrf definition ansible - match: none - provider: "{{ cli }}" - -- name: configure lookup_source - ios_system: - lookup_source: Loopback888 - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == true - - "'ip domain lookup source-interface Loopback888' in result.commands" - -- name: verify lookup_source - ios_system: - lookup_source: Loopback888 - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == false - -- name: Disable lookup_source - ios_system: - lookup_enabled: False - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == true - - "'no ip domain lookup' in result.commands" - -- name: Disable lookup_source - ios_system: - lookup_enabled: True - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == true - - "'ip domain lookup' in result.commands" - -#- name: change to vrf -# ios_system: -# lookup_source: -# - interface: Loopback10 -# vrf: ansible -# provider: "{{ cli }}" -# provider: "{{ cli }}" -# register: result -# -#- assert: -# that: -# - result.changed == true -# - "'no ip domain lookup source-interface Management1' in result.commands" -# - "'ip domain lookup vrf ansible source-interface Management1' in result.commands" -# - result.commands|length == 2 -# -#- name: verify change to vrf -# ios_system: -# lookup_source: -# - interface: Management1 -# vrf: ansible -# provider: "{{ cli }}" -# provider: "{{ cli }}" -# register: result -# -#- assert: -# that: -# - result.changed == false - -- name: teardown - ios_config: - lines: - - no ip domain lookup source-interface Loopback888 - - no vrf definition ansible - match: none - provider: "{{ cli }}" - ignore_errors: yes -# FIXME: Not sure why this is failing with msg": "no vrf definition ansible\r\n% IPv4 and IPv6 addresses from all interfaces in VRF ansible have been removed\r\nfoo(config)#", rc:1 - -- debug: msg="END cli/set_lookup_source.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_system/tests/cli/set_name_servers.yaml b/test/integration/targets/ios_system/tests/cli/set_name_servers.yaml deleted file mode 100644 index 5dcc32ed1f9..00000000000 --- a/test/integration/targets/ios_system/tests/cli/set_name_servers.yaml +++ /dev/null @@ -1,91 +0,0 @@ ---- -- debug: msg="START cli/set_name_servers.yaml on connection={{ ansible_connection }}" - -- name: setup - ios_config: - lines: - - no ip name-server - match: none - provider: "{{ cli }}" - -- name: configure name_servers - ios_system: - name_servers: - - 192.0.2.1 - - 192.0.2.2 - - 192.0.2.3 - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == true - - result.commands|length == 3 - - "'ip name-server 192.0.2.1' in result.commands" - - "'ip name-server 192.0.2.2' in result.commands" - - "'ip name-server 192.0.2.3' in result.commands" - -- name: verify name_servers - ios_system: - name_servers: - - 192.0.2.1 - - 192.0.2.2 - - 192.0.2.3 - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == false - -#- name: change to vrf -# ios_system: -# name_servers: -# - 192.0.2.1 -# - { server: 192.0.2.2, vrf: ansible } -# - 192.0.2.3 -# provider: "{{ cli }}" -# register: result - -#- assert: -# that: -# - result.changed == true -# - result.commands|length == 2 -# - "'no ip name-server 192.0.2.2' in result.commands" -# - "'ip name-server 192.0.2.2 vrf ansible' in result.commands" - -#- name: verify change to vrf -# ios_system: -# name_servers: -# - 192.0.2.1 -# - { server: 192.0.2.2, vrf: ansible } -# - 192.0.2.3 -# provider: "{{ cli }}" -# register: result -# -#- assert: -# that: -# - result.changed == false - -- name: remove one - ios_system: - name_servers: - - 192.0.2.1 - - 192.0.2.2 - provider: "{{ cli }}" - register: result - -- assert: - that: - - result.changed == true - - result.commands|length == 1 - - "'no ip name-server 192.0.2.3' in result.commands" - -- name: teardown - ios_config: - lines: - - no ip name-server - match: none - provider: "{{ cli }}" - -- debug: msg="END cli/set_name_servers.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_user/defaults/main.yaml b/test/integration/targets/ios_user/defaults/main.yaml deleted file mode 100644 index 5f709c5aac1..00000000000 --- a/test/integration/targets/ios_user/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" diff --git a/test/integration/targets/ios_user/files/test_rsa b/test/integration/targets/ios_user/files/test_rsa deleted file mode 100644 index 9fdc8c3af0e..00000000000 --- a/test/integration/targets/ios_user/files/test_rsa +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAseTsv6oTMJbsRgOSaNEVBlsqE4tKI2MBEOHzTlUnE3GBRtZi -xlUlF9rZcjtk+hTIz3N3UrLtxMnWqv0YGM8tXZTcz50M9ANDE/oNXrXkkMKX5WWr -OcgDCAAZYSVJ/vIt/xZkYteax6zMZQqEBIc/rKo8KuxKZTUMqj0GHkCQbA/o7lBQ -hpdUZxtU/Y2uc9tXVhav3jVzTFUOdwZrCAJghdCCweJfwAj1DdHODip+/hNu+3Sk -DNl0bdhWoNNnUFCYPOUK2B79OMg2+r5bwH7xgURIoTuc54HlGectJpIzI7GB6VfL -UCsJn0uQ7HwX7XAtZjhJWP8dKPd1FuUgg5M8MwIDAQABAoIBACfBVz9GDN/Q+qBy -7+dIwoAXI4IWoMzjtTtGo48f7Iml1hQ0mQJlyNJZ8DpdF6XjuzTRQxtSLVzLFpRD -13zD4AmH2Qj0ug5WJEl0mkRONfQ76KI1ZFyXXEYPb5yMLssw6CKXqHuGX2q8LTlv -bi1s5Ef8C1I0WDPh9SCeXp2oJB5h2G+HtCXDyxASK2nAKqhkpQqPhg5Rd50mBOpD -WE/lor358hU0Aj/qhzjeWKNNK8pgeahXz5anEQZ69TUH102B6bNh8Ao4ZL2j3tr0 -6FbE3ooQT7+zOLm5xOFJ9OnJ2yDVW6Dj1Czllx2vJUcxKsKxaGF76xNCIPiSUUfS -mnOnEfECgYEA2bBFc9Pb8AI0bZZ8Q6XE7Jqa6BOaLbzyjK6IzdyAV/LKdk3yRfEZ -Rb2iNy8poBUYBqBUMfRsRVq5dabjYkz9X5e+75S8Lm/qiktlhTpQYWk5q+eBZdPm -I+dG64Tdyv+Y/NwN4enIsw8LGllY472iUf37ms2+uOA8/BysQ2n7ss0CgYEA0TPD -IhmLqNhQGkS2GU6tM8G7LyGOaIH3mmyCviYgEauWWw3bn/Hhiq/6tLtQc6pv2nIa -ifbACnI+GiIoBFwz8ofuFA8dm76uro7o6eWP5iUizoGISYSewCFpcCpp0xn7/FNR -3RT4YRBMt3yL8J1cVBpPRRbIwp/bZ+pRb0Ggqv8CgYEAoNAFHqHdkhou3N4UgmzN -YvR7hwIkHbG9hIvS6DECZvYm9upyFZUcVFbYpOekWmv6ybpbOGQWL83rv6w/wfia -HKofFSHNOojWvL8iCh+gDbYMMp/dCXpWQyOxUn9e0X2saO+vGbr41r5AN4DVl7gZ -V3THD/75691Lb/tGjq6Wj+kCgYB6ZhadNOUJfMYhGGKSm/2qcobaJH/1lVUQ/Lvi -FNxeek4WKB1/jz2urxe39oAzrFyVKn1sivoBIqZDFAjlxCyAkhcxlUZ1gTMi3mpX -rwBqXv/mYtMicH2RW/scrTQNVv6fuwACoepQoADCuhQGS4thiaMngRUlCfKM8gOD -XJpscQKBgQDIMURtVIV/2ZcGqHv/3G5jsPJPsTycv6YR4gTs5GUBy5If2Rs7DMWE -pJLIcU+SJhMeVKTZPrePibzCp2+rMSI5pc6T+9LC79RKsfie3UybWfLZrSmtnxJx -MgC49TR4NFP6yoYJPYiTdRJ/1Bu68WfVafFK86i9MKAI5OU2ba3/Bg== ------END RSA PRIVATE KEY----- diff --git a/test/integration/targets/ios_user/files/test_rsa.pub b/test/integration/targets/ios_user/files/test_rsa.pub deleted file mode 100644 index e6939a2955a..00000000000 --- a/test/integration/targets/ios_user/files/test_rsa.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCx5Oy/qhMwluxGA5Jo0RUGWyoTi0ojYwEQ4fNOVScTcYFG1mLGVSUX2tlyO2T6FMjPc3dSsu3Eydaq/RgYzy1dlNzPnQz0A0MT+g1eteSQwpflZas5yAMIABlhJUn+8i3/FmRi15rHrMxlCoQEhz+sqjwq7EplNQyqPQYeQJBsD+juUFCGl1RnG1T9ja5z21dWFq/eNXNMVQ53BmsIAmCF0ILB4l/ACPUN0c4OKn7+E277dKQM2XRt2Fag02dQUJg85QrYHv04yDb6vlvAfvGBREihO5zngeUZ5y0mkjMjsYHpV8tQKwmfS5DsfBftcC1mOElY/x0o93UW5SCDkzwz ansible_ios_user_test diff --git a/test/integration/targets/ios_user/meta/main.yaml b/test/integration/targets/ios_user/meta/main.yaml deleted file mode 100644 index 159cea8d383..00000000000 --- a/test/integration/targets/ios_user/meta/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_ios_tests diff --git a/test/integration/targets/ios_user/tasks/cli.yaml b/test/integration/targets/ios_user/tasks/cli.yaml deleted file mode 100644 index 6b93fd5400e..00000000000 --- a/test/integration/targets/ios_user/tasks/cli.yaml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- name: collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - register: test_cases - delegate_to: localhost - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=network_cli) - include: "{{ test_case_to_run }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli - -- name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_local diff --git a/test/integration/targets/ios_user/tasks/main.yaml b/test/integration/targets/ios_user/tasks/main.yaml deleted file mode 100644 index 415c99d8b12..00000000000 --- a/test/integration/targets/ios_user/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/ios_user/tests/cli/auth.yaml b/test/integration/targets/ios_user/tests/cli/auth.yaml deleted file mode 100644 index 7e7a7b000c0..00000000000 --- a/test/integration/targets/ios_user/tests/cli/auth.yaml +++ /dev/null @@ -1,83 +0,0 @@ ---- -- block: - - name: Create user with password - ios_user: - name: auth_user - privilege: 15 - role: network-operator - state: present - provider: "{{ cli }}" - configured_password: pass123 - - - name: test login - expect: - command: "ssh auth_user@{{ ansible_ssh_host }} -p {{ ansible_ssh_port|default(22) }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PubkeyAuthentication=no show version" - responses: - (?i)password: "pass123" - - - name: test login with invalid password (should fail) - expect: - command: "ssh auth_user@{{ ansible_ssh_host }} -p {{ ansible_ssh_port|default(22) }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PubkeyAuthentication=no show version" - responses: - (?i)password: "badpass" - ignore_errors: yes - register: results - - - name: check that attempt failed - assert: - that: - - results.failed - - always: - - name: delete user - ios_user: - name: auth_user - state: absent - provider: "{{ cli }}" - register: result - - - name: reset connection - meta: reset_connection - - -- block: - - name: Ensure ssh key is not world readable - file: - path: "{{ role_path }}/files/test_rsa" - mode: 0600 - - - name: Create user with sshkey - ios_user: - name: ssh_user - privilege: 15 - role: network-operator - state: present - provider: "{{ cli }}" - sshkey: "{{ lookup('file', 'files/test_rsa.pub') }}" - - - name: test sshkey login - shell: "ssh ssh_user@{{ ansible_ssh_host }} -p {{ ansible_ssh_port|default(22) }} -o IdentityFile={{ role_path }}/files/test_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o BatchMode=yes -o PubkeyAuthentication=yes show version" - - - name: test login without sshkey (should fail) - expect: - command: "ssh ssh_user@{{ ansible_ssh_host }} -p {{ ansible_ssh_port|default(22) }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PubkeyAuthentication=no show version" - responses: - (?i)password: badpass - ignore_errors: yes - register: results - - - name: check that attempt failed - assert: - that: - - results.failed - - always: - - name: delete user - ios_user: - name: ssh_user - state: absent - provider: "{{ cli }}" - register: result - - - name: reset connection - meta: reset_connection diff --git a/test/integration/targets/ios_user/tests/cli/basic.yaml b/test/integration/targets/ios_user/tests/cli/basic.yaml deleted file mode 100644 index 144b0738798..00000000000 --- a/test/integration/targets/ios_user/tests/cli/basic.yaml +++ /dev/null @@ -1,142 +0,0 @@ ---- -- name: tear down old users if they exist (Setup) - become: true - ios_user: - aggregate: - - name: ansibletest1 - - name: ansibletest2 - - name: ansibletest3 - - name: ansibletest4 - - name: ansibletest5 - - name: ansibletest6 - state: absent - provider: "{{ cli }}" - -- name: Create user (SetUp) - become: true - ios_user: - name: ansibletest1 - privilege: 15 - role: network-operator - state: present - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.commands == ["username ansibletest1 view network-operator", "username ansibletest1 privilege 15"]' - -- name: Collection of users (SetUp) - become: true - ios_user: - aggregate: - - name: ansibletest2 - - name: ansibletest3 - provider: "{{ cli }}" - state: present - view: network-admin - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.commands == ["username ansibletest2 view network-admin", "username ansibletest3 view network-admin"]' - -- name: Add user again (Idempotent) - become: true - ios_user: - name: ansibletest1 - privilege: 15 - role: network-operator - state: present - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.commands | length == 0' - -- name: Add collection of users again (Idempotent) - become: true - ios_user: - aggregate: - - name: ansibletest2 - - name: ansibletest3 - provider: "{{ cli }}" - state: present - view: network-admin - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.commands | length == 0' - -- name: Create user with password_type (password) - become: true - ios_user: - name: ansibleuser4 - password_type: password - configured_password: testpass - provider: "{{ cli }}" - state: present - register: result - -- assert: - that: - - 'result.changed == true' - - "'username ansibleuser4 password' in result.commands[0]" - -- name: Create user with password_type (secret) - become: true - ios_user: - name: ansibleuser5 - password_type: secret - configured_password: testpass - provider: "{{ cli }}" - state: present - register: result - -- assert: - that: - - 'result.changed == true' - - "'username ansibleuser5 secret' in result.commands[0]" - -- name: Create user with hashed_password - become: true - ios_user: - name: ansibleuser6 - hashed_password: - type: 5 - value: $3$8JcDilcYgFZi.yz4ApaqkHG2.8/ - provider: "{{ cli }}" - state: present - register: result - -- assert: - that: - - 'result.changed == true' - - "'username ansibleuser6 secret' in result.commands[0]" - -- name: tearDown - become: true - ios_user: - aggregate: - - name: ansibletest1 - - name: ansibletest2 - - name: ansibletest3 - - name: ansibletest4 - - name: ansibletest5 - - name: ansibletest6 - state: absent - provider: "{{ cli }}" - register: result - -- assert: - that: - - 'result.changed == true' - - '"no username ansibletest1" in result.commands[0]["command"]' - - '"no username ansibletest2" in result.commands[1]["command"]' - - '"no username ansibletest3" in result.commands[2]["command"]' diff --git a/test/integration/targets/ios_vlan/defaults/main.yaml b/test/integration/targets/ios_vlan/defaults/main.yaml deleted file mode 100644 index 9ef5ba51651..00000000000 --- a/test/integration/targets/ios_vlan/defaults/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -testcase: "*" -test_items: [] diff --git a/test/integration/targets/ios_vlan/meta/main.yaml b/test/integration/targets/ios_vlan/meta/main.yaml deleted file mode 100644 index 159cea8d383..00000000000 --- a/test/integration/targets/ios_vlan/meta/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_ios_tests diff --git a/test/integration/targets/ios_vlan/tasks/cli.yaml b/test/integration/targets/ios_vlan/tasks/cli.yaml deleted file mode 100644 index 6b93fd5400e..00000000000 --- a/test/integration/targets/ios_vlan/tasks/cli.yaml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- name: collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - register: test_cases - delegate_to: localhost - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=network_cli) - include: "{{ test_case_to_run }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli - -- name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_local diff --git a/test/integration/targets/ios_vlan/tasks/main.yaml b/test/integration/targets/ios_vlan/tasks/main.yaml deleted file mode 100644 index 415c99d8b12..00000000000 --- a/test/integration/targets/ios_vlan/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/ios_vlan/tests/cli/basic.yaml b/test/integration/targets/ios_vlan/tests/cli/basic.yaml deleted file mode 100644 index 4f71458d22e..00000000000 --- a/test/integration/targets/ios_vlan/tests/cli/basic.yaml +++ /dev/null @@ -1,239 +0,0 @@ ---- -- debug: msg="START cli/basic.yaml on connection={{ ansible_connection }}" - -- set_fact: switch_type="{{ switch_type }}" - -- block: - - - name: setup - remove vlan used in test - ios_config: - lines: - - no vlan 100 - - no vlan 200 - - no vlan 300 - provider: "{{ cli }}" - - - name: setup - remove switchport settings on interfaces used in test - ios_config: - lines: - - switchport mode access - - no switchport access vlan 100 - provider: "{{ cli }}" - parents: "{{ item }}" - loop: - - interface GigabitEthernet0/1 - - interface GigabitEthernet0/2 - - - name: create vlan - ios_vlan: &create - vlan_id: 100 - name: test-vlan - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.changed == true" - - "'vlan 100' in result.commands" - - "'name test-vlan' in result.commands" - - - name: create vlan(idempotence) - ios_vlan: *create - register: result - - - assert: - that: - - "result.changed == false" - - - name: Add interfaces to vlan - ios_vlan: &interfaces - vlan_id: 100 - interfaces: - - GigabitEthernet0/1 - - GigabitEthernet0/2 - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.changed == true" - - "'interface GigabitEthernet0/1' in result.commands" - - "'switchport mode access' in result.commands" - - "'switchport access vlan 100' in result.commands" - - "'interface GigabitEthernet0/2' in result.commands" - - "'switchport mode access' in result.commands" - - "'switchport access vlan 100' in result.commands" - - - name: Add interfaces to vlan(idempotence) - ios_vlan: *interfaces - register: result - - - assert: - that: - - "result.changed == false" - - - name: Check interface assigned to vrf (intent) - ios_vlan: - vlan_id: 100 - associated_interfaces: - - GigabitEthernet0/1 - - GigabitEthernet0/2 - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.failed == false" - - - name: Check interface assigned to vrf (fail) - ios_vlan: - vlan_id: 100 - associated_interfaces: - - test - provider: "{{ cli }}" - ignore_errors: yes - register: result - - - assert: - that: - - "result.failed == True" - - - name: Remove interface from vlan - ios_vlan: &single_int - vlan_id: 100 - interfaces: - - GigabitEthernet0/1 - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.changed == true" - - "'vlan 100' in result.commands" - - "'interface GigabitEthernet0/2' in result.commands" - - "'switchport mode access' in result.commands" - - "'no switchport access vlan 100' in result.commands" - - - name: Remove interface from vlan(idempotence) - ios_vlan: *single_int - register: result - - - assert: - that: - - "result.changed == false" - - - name: Suspend vlan - ios_vlan: - vlan_id: 100 - state: suspend - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.changed == true" - - "'vlan 100' in result.commands" - - "'state suspend' in result.commands" - - - name: Unsuspend vlan - ios_vlan: - vlan_id: 100 - state: active - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.changed == true" - - "'vlan 100' in result.commands" - - "'state active' in result.commands" - - - name: delete vlan - ios_vlan: &delete - vlan_id: 100 - provider: "{{ cli }}" - state: absent - register: result - - - assert: - that: - - "result.changed == true" - - "'no vlan 100' in result.commands" - - - name: delete vlan(idempotence) - ios_vlan: *delete - register: result - - - assert: - that: - - "result.changed == false" - - - name: create vlans using aggregate - ios_vlan: &create_aggregate - aggregate: - - { vlan_id: 200, name: vlan-200 } - - { vlan_id: 300, name: vlan-300 } - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.changed == true" - - "'vlan 200' in result.commands" - - "'name vlan-200' in result.commands" - - "'vlan 300' in result.commands" - - "'name vlan-300' in result.commands" - - - name: create vlans using aggregate(idempotence) - ios_vlan: *create_aggregate - register: result - - - assert: - that: - - "result.changed == false" - - - name: delete vlans using aggregate - ios_vlan: &delete_aggregate - aggregate: - - { vlan_id: 200, name: vlan-200 } - - { vlan_id: 300, name: vlan-300 } - state: absent - provider: "{{ cli }}" - register: result - - - assert: - that: - - "result.changed == true" - - "'no vlan 200' in result.commands" - - "'no vlan 300' in result.commands" - - - name: delete vlans using aggregate(idempotence) - ios_vlan: *delete_aggregate - register: result - - - assert: - that: - - "result.changed == false" - - - name: teardown(part1) - ios_config: - lines: - - no vlan 100 - - no vlan 200 - - no vlan 300 - provider: "{{ cli }}" - - - name: teardown(part2) - ios_config: - lines: - - switchport mode access - - no switchport access vlan 100 - provider: "{{ cli }}" - parents: "{{ item }}" - loop: - - interface GigabitEthernet0/1 - - interface GigabitEthernet0/2 - - when: switch_type == 'L2' - -- debug: msg="END cli/basic.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/ios_vlans/defaults/main.yaml b/test/integration/targets/ios_vlans/defaults/main.yaml deleted file mode 100644 index 164afead284..00000000000 --- a/test/integration/targets/ios_vlans/defaults/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -testcase: "[^_].*" -test_items: [] diff --git a/test/integration/targets/ios_vlans/meta/main.yaml b/test/integration/targets/ios_vlans/meta/main.yaml deleted file mode 100644 index 32cf5dda7ed..00000000000 --- a/test/integration/targets/ios_vlans/meta/main.yaml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] diff --git a/test/integration/targets/ios_vlans/tasks/cli.yaml b/test/integration/targets/ios_vlans/tasks/cli.yaml deleted file mode 100644 index 3bafcd702f4..00000000000 --- a/test/integration/targets/ios_vlans/tasks/cli.yaml +++ /dev/null @@ -1,25 +0,0 @@ ---- -- name: Collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - use_regex: true - register: test_cases - delegate_to: localhost - -- name: Set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - delegate_to: localhost - -- name: Get the IOS version - ios_facts: - gather_subset: all - -- name: Run test case (connection=network_cli) - include: "{{ test_case_to_run }}" - vars: - ansible_connection: network_cli - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - tags: connection_network_cli diff --git a/test/integration/targets/ios_vlans/tasks/main.yaml b/test/integration/targets/ios_vlans/tasks/main.yaml deleted file mode 100644 index 415c99d8b12..00000000000 --- a/test/integration/targets/ios_vlans/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/ios_vlans/tests/cli/_populate_config.yaml b/test/integration/targets/ios_vlans/tests/cli/_populate_config.yaml deleted file mode 100644 index c8c7402ee5b..00000000000 --- a/test/integration/targets/ios_vlans/tests/cli/_populate_config.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -- name: Setup - cli_config: - config: "{{ lines }}" - vars: - lines: | - vlan 10 - vlan 20 - vlan 30 - when: ansible_net_version != "15.6(2)T" diff --git a/test/integration/targets/ios_vlans/tests/cli/_remove_config.yaml b/test/integration/targets/ios_vlans/tests/cli/_remove_config.yaml deleted file mode 100644 index 8b45b6fa113..00000000000 --- a/test/integration/targets/ios_vlans/tests/cli/_remove_config.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- name: Remove Config - cli_config: - config: "{{ lines }}" - vars: - lines: | - no vlan 10 - no vlan 20 - no vlan 30 - no vlan 40 - when: ansible_net_version != "15.6(2)T" diff --git a/test/integration/targets/ios_vlans/tests/cli/deleted.yaml b/test/integration/targets/ios_vlans/tests/cli/deleted.yaml deleted file mode 100644 index 99ca146fd51..00000000000 --- a/test/integration/targets/ios_vlans/tests/cli/deleted.yaml +++ /dev/null @@ -1,42 +0,0 @@ ---- -- debug: - msg: "Start Deleted integration state for ios_vlans ansible_connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _populate_config.yaml - -- block: - - name: Delete VLANs attributes for all configured VLANs - ios_vlans: &deleted - state: deleted - register: result - - - name: Assert that correct set of commands were generated - assert: - that: - - "{{ deleted['commands'] | symmetric_difference(result['commands']) | length == 0 }}" - - - name: Assert that before dicts are correctly generated - assert: - that: - - "{{ deleted['before'] | symmetric_difference(result['before']) | length == 0 }}" - - - name: Assert that after dict is correctly generated - assert: - that: - - "{{ deleted['after'] | symmetric_difference(result['after']) | length == 0 }}" - - - name: Delete VLANs attributes for all configured VLANs (IDEMPOTENT) - ios_vlans: *deleted - register: result - - - name: Assert that the previous task was idempotent - assert: - that: - - "result.changed == false" - - when: ansible_net_version != "15.6(2)T" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_vlans/tests/cli/empty_config.yaml b/test/integration/targets/ios_vlans/tests/cli/empty_config.yaml deleted file mode 100644 index f54c1f86deb..00000000000 --- a/test/integration/targets/ios_vlans/tests/cli/empty_config.yaml +++ /dev/null @@ -1,38 +0,0 @@ ---- -- debug: - msg: "START ios_vlans empty_config.yaml integration tests on connection={{ ansible_connection }}" - -- block: - - name: Merged with empty config should give appropriate error message - ios_vlans: - config: - state: merged - register: result - ignore_errors: True - - - assert: - that: - - result.msg == 'value of config parameter must not be empty for state merged' - - - name: Replaced with empty config should give appropriate error message - ios_vlans: - config: - state: replaced - register: result - ignore_errors: True - - - assert: - that: - - result.msg == 'value of config parameter must not be empty for state replaced' - - - name: Overridden with empty config should give appropriate error message - ios_vlans: - config: - state: overridden - register: result - ignore_errors: True - - - assert: - that: - - result.msg == 'value of config parameter must not be empty for state overridden' - when: ansible_net_version != "15.6(2)T" diff --git a/test/integration/targets/ios_vlans/tests/cli/merged.yaml b/test/integration/targets/ios_vlans/tests/cli/merged.yaml deleted file mode 100644 index 1e16cdd3a47..00000000000 --- a/test/integration/targets/ios_vlans/tests/cli/merged.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -- debug: - msg: "START Merged ios_vlans state for integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- block: - - name: Merge provided configuration with device configuration - ios_vlans: &merged - config: - - name: Vlan_10 - vlan_id: 10 - state: active - shutdown: disabled - remote_span: True - - name: Vlan_20 - vlan_id: 20 - mtu: 610 - state: active - shutdown: enabled - - name: Vlan_30 - vlan_id: 30 - state: suspend - shutdown: enabled - state: merged - register: result - - - name: Assert that correct set of commands were generated - assert: - that: - - "{{ merged['commands'] | symmetric_difference(result['commands']) | length == 0 }}" - - - name: Assert that before dicts are correctly generated - assert: - that: - - "{{ merged['before'] | symmetric_difference(result['before']) | length == 0 }}" - - - name: Assert that after dict is correctly generated - assert: - that: - - "{{ merged['after'] | symmetric_difference(result['after']) | length == 0 }}" - - - name: Merge provided configuration with device configuration (IDEMPOTENT) - ios_vlans: *merged - register: result - - - name: Assert that the previous task was idempotent - assert: - that: - - "result['changed'] == false" - when: ansible_net_version != "15.6(2)T" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_vlans/tests/cli/overridden.yaml b/test/integration/targets/ios_vlans/tests/cli/overridden.yaml deleted file mode 100644 index d464b91a26a..00000000000 --- a/test/integration/targets/ios_vlans/tests/cli/overridden.yaml +++ /dev/null @@ -1,48 +0,0 @@ ---- -- debug: - msg: "START Overridden ios_vlans state for integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _populate_config.yaml - -- block: - - name: Override device configuration of all VLANs with provided configuration - ios_vlans: &overridden - config: - - name: VLAN_10 - vlan_id: 10 - mtu: 1000 - - name: VLAN_40 - vlan_id: 40 - mtu: 850 - state: overridden - register: result - - - name: Assert that correct set of commands were generated - assert: - that: - - "{{ overridden['commands'] | symmetric_difference(result['commands']) | length == 0 }}" - - - name: Assert that before dicts are correctly generated - assert: - that: - - "{{ overridden['before'] | symmetric_difference(result['before']) | length == 0 }}" - - - name: Assert that after dict is correctly generated - assert: - that: - - "{{ overridden['after'] | symmetric_difference(result['after']) | length == 0 }}" - - - name: Override device configuration of all interfaces with provided configuration (IDEMPOTENT) - ios_vlans: *overridden - register: result - - - name: Assert that task was idempotent - assert: - that: - - "result['changed'] == false" - when: ansible_net_version != "15.6(2)T" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_vlans/tests/cli/replaced.yaml b/test/integration/targets/ios_vlans/tests/cli/replaced.yaml deleted file mode 100644 index 3fbeef796ce..00000000000 --- a/test/integration/targets/ios_vlans/tests/cli/replaced.yaml +++ /dev/null @@ -1,49 +0,0 @@ ---- -- debug: - msg: "START Replaced ios_vlans state for integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _populate_config.yaml - -- block: - - name: Replaces device configuration of listed VLANs with provided configuration - ios_vlans: &replaced - config: - - vlan_id: 20 - name: Test_VLAN20 - mtu: 700 - shutdown: disabled - - vlan_id: 30 - name: Test_VLAN30 - mtu: 1000 - state: replaced - register: result - - - name: Assert that correct set of commands were generated - assert: - that: - - "{{ replaced['commands'] | symmetric_difference(result['commands']) | length == 0 }}" - - - name: Assert that before dicts are correctly generated - assert: - that: - - "{{ replaced['before'] | symmetric_difference(result['before']) | length == 0 }}" - - - name: Assert that after dict is correctly generated - assert: - that: - - "{{ replaced['after'] | symmetric_difference(result['after']) | length == 0 }}" - - - name: Replaces device configuration of listed interfaces with provided configuration (IDEMPOTENT) - ios_vlans: *replaced - register: result - - - name: Assert that task was idempotent - assert: - that: - - "result['changed'] == false" - when: ansible_net_version != "15.6(2)T" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/ios_vlans/vars/main.yaml b/test/integration/targets/ios_vlans/vars/main.yaml deleted file mode 100644 index 24e92dc898d..00000000000 --- a/test/integration/targets/ios_vlans/vars/main.yaml +++ /dev/null @@ -1,345 +0,0 @@ ---- -merged: - before: - - mtu: 1500 - name: default - shutdown: disabled - state: active - vlan_id: 1 - - mtu: 1500 - name: fddi-default - shutdown: enabled - state: active - vlan_id: 1002 - - mtu: 1500 - name: token-ring-default - shutdown: enabled - state: active - vlan_id: 1003 - - mtu: 1500 - name: fddinet-default - shutdown: enabled - state: active - vlan_id: 1004 - - mtu: 1500 - name: trnet-default - shutdown: enabled - state: active - vlan_id: 1005 - - commands: - - "vlan 10" - - "name Vlan_10" - - "state active" - - "remote-span" - - "no shutdown" - - "vlan 20" - - "name Vlan_20" - - "state active" - - "mtu 610" - - "shutdown" - - "vlan 30" - - "name Vlan_30" - - "state suspend" - - "shutdown" - - after: - - mtu: 1500 - name: default - shutdown: disabled - state: active - vlan_id: 1 - - mtu: 1500 - name: Vlan_10 - remote_span: true - shutdown: disabled - state: active - vlan_id: 10 - - mtu: 610 - name: Vlan_20 - shutdown: enabled - state: active - vlan_id: 20 - - mtu: 1500 - name: Vlan_30 - shutdown: enabled - state: suspend - vlan_id: 30 - - mtu: 1500 - name: fddi-default - shutdown: enabled - state: active - vlan_id: 1002 - - mtu: 1500 - name: token-ring-default - shutdown: enabled - state: active - vlan_id: 1003 - - mtu: 1500 - name: fddinet-default - shutdown: enabled - state: active - vlan_id: 1004 - - mtu: 1500 - name: trnet-default - shutdown: enabled - state: active - vlan_id: 1005 - -replaced: - before: - - mtu: 1500 - name: default - shutdown: disabled - state: active - vlan_id: 1 - - mtu: 1500 - name: VLAN0010 - shutdown: disabled - state: active - vlan_id: 10 - - mtu: 1500 - name: VLAN0020 - shutdown: disabled - state: active - vlan_id: 20 - - mtu: 1500 - name: VLAN0030 - shutdown: disabled - state: active - vlan_id: 30 - - mtu: 1500 - name: fddi-default - shutdown: enabled - state: active - vlan_id: 1002 - - mtu: 1500 - name: token-ring-default - shutdown: enabled - state: active - vlan_id: 1003 - - mtu: 1500 - name: fddinet-default - shutdown: enabled - state: active - vlan_id: 1004 - - mtu: 1500 - name: trnet-default - shutdown: enabled - state: active - vlan_id: 1005 - - commands: - - "vlan 20" - - "name Test_VLAN20" - - "mtu 700" - - "vlan 30" - - "name Test_VLAN30" - - "mtu 1000" - - after: - - mtu: 1500 - name: default - shutdown: disabled - state: active - vlan_id: 1 - - mtu: 1500 - name: VLAN0010 - shutdown: disabled - state: active - vlan_id: 10 - - mtu: 700 - name: Test_VLAN20 - shutdown: disabled - state: active - vlan_id: 20 - - mtu: 1000 - name: Test_VLAN30 - shutdown: disabled - state: active - vlan_id: 30 - - mtu: 1500 - name: fddi-default - shutdown: enabled - state: active - vlan_id: 1002 - - mtu: 1500 - name: token-ring-default - shutdown: enabled - state: active - vlan_id: 1003 - - mtu: 1500 - name: fddinet-default - shutdown: enabled - state: active - vlan_id: 1004 - - mtu: 1500 - name: trnet-default - shutdown: enabled - state: active - vlan_id: 1005 - -overridden: - before: - - mtu: 1500 - name: default - shutdown: disabled - state: active - vlan_id: 1 - - mtu: 1500 - name: VLAN0010 - shutdown: disabled - state: active - vlan_id: 10 - - mtu: 1500 - name: VLAN0020 - shutdown: disabled - state: active - vlan_id: 20 - - mtu: 1500 - name: VLAN0030 - shutdown: disabled - state: active - vlan_id: 30 - - mtu: 1500 - name: fddi-default - shutdown: enabled - state: active - vlan_id: 1002 - - mtu: 1500 - name: token-ring-default - shutdown: enabled - state: active - vlan_id: 1003 - - mtu: 1500 - name: fddinet-default - shutdown: enabled - state: active - vlan_id: 1004 - - mtu: 1500 - name: trnet-default - shutdown: enabled - state: active - vlan_id: 1005 - - commands: - - "vlan 10" - - "name VLAN_10" - - "mtu 1000" - - "no vlan 20" - - "no vlan 30" - - "vlan 40" - - "name VLAN_40" - - "mtu 850" - - after: - - mtu: 1500 - name: default - shutdown: disabled - state: active - vlan_id: 1 - - mtu: 1000 - name: VLAN_10 - shutdown: disabled - state: active - vlan_id: 10 - - mtu: 850 - name: VLAN_40 - shutdown: disabled - state: active - vlan_id: 40 - - mtu: 1500 - name: fddi-default - shutdown: enabled - state: active - vlan_id: 1002 - - mtu: 1500 - name: token-ring-default - shutdown: enabled - state: active - vlan_id: 1003 - - mtu: 1500 - name: fddinet-default - shutdown: enabled - state: active - vlan_id: 1004 - - mtu: 1500 - name: trnet-default - shutdown: enabled - state: active - vlan_id: 1005 - -deleted: - before: - - mtu: 1500 - name: default - shutdown: disabled - state: active - vlan_id: 1 - - mtu: 1500 - name: VLAN0010 - shutdown: disabled - state: active - vlan_id: 10 - - mtu: 1500 - name: VLAN0020 - shutdown: disabled - state: active - vlan_id: 20 - - mtu: 1500 - name: VLAN0030 - shutdown: disabled - state: active - vlan_id: 30 - - mtu: 1500 - name: fddi-default - shutdown: enabled - state: active - vlan_id: 1002 - - mtu: 1500 - name: token-ring-default - shutdown: enabled - state: active - vlan_id: 1003 - - mtu: 1500 - name: fddinet-default - shutdown: enabled - state: active - vlan_id: 1004 - - mtu: 1500 - name: trnet-default - shutdown: enabled - state: active - vlan_id: 1005 - - commands: - - "no vlan 10" - - "no vlan 20" - - "no vlan 30" - - after: - - mtu: 1500 - name: default - shutdown: disabled - state: active - vlan_id: 1 - - mtu: 1500 - name: fddi-default - shutdown: enabled - state: active - vlan_id: 1002 - - mtu: 1500 - name: token-ring-default - shutdown: enabled - state: active - vlan_id: 1003 - - mtu: 1500 - name: fddinet-default - shutdown: enabled - state: active - vlan_id: 1004 - - mtu: 1500 - name: trnet-default - shutdown: enabled - state: active - vlan_id: 1005 diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt index 99bc316d2a7..cb050a04675 100644 --- a/test/sanity/ignore.txt +++ b/test/sanity/ignore.txt @@ -92,20 +92,6 @@ lib/ansible/module_utils/network/dellos6/dellos6.py future-import-boilerplate lib/ansible/module_utils/network/dellos6/dellos6.py metaclass-boilerplate lib/ansible/module_utils/network/dellos9/dellos9.py future-import-boilerplate lib/ansible/module_utils/network/dellos9/dellos9.py metaclass-boilerplate -lib/ansible/module_utils/network/ios/ios.py future-import-boilerplate -lib/ansible/module_utils/network/ios/ios.py metaclass-boilerplate -lib/ansible/module_utils/network/ios/providers/cli/config/base.py future-import-boilerplate -lib/ansible/module_utils/network/ios/providers/cli/config/base.py metaclass-boilerplate -lib/ansible/module_utils/network/ios/providers/cli/config/bgp/address_family.py future-import-boilerplate -lib/ansible/module_utils/network/ios/providers/cli/config/bgp/address_family.py metaclass-boilerplate -lib/ansible/module_utils/network/ios/providers/cli/config/bgp/neighbors.py future-import-boilerplate -lib/ansible/module_utils/network/ios/providers/cli/config/bgp/neighbors.py metaclass-boilerplate -lib/ansible/module_utils/network/ios/providers/cli/config/bgp/process.py future-import-boilerplate -lib/ansible/module_utils/network/ios/providers/cli/config/bgp/process.py metaclass-boilerplate -lib/ansible/module_utils/network/ios/providers/module.py future-import-boilerplate -lib/ansible/module_utils/network/ios/providers/module.py metaclass-boilerplate -lib/ansible/module_utils/network/ios/providers/providers.py future-import-boilerplate -lib/ansible/module_utils/network/ios/providers/providers.py metaclass-boilerplate lib/ansible/module_utils/network/iosxr/iosxr.py future-import-boilerplate lib/ansible/module_utils/network/iosxr/iosxr.py metaclass-boilerplate lib/ansible/module_utils/network/iosxr/providers/cli/config/bgp/address_family.py future-import-boilerplate @@ -1829,142 +1815,6 @@ lib/ansible/modules/network/f5/bigiq_regkey_license_assignment.py validate-modul lib/ansible/modules/network/f5/bigiq_regkey_pool.py validate-modules:doc-required-mismatch lib/ansible/modules/network/f5/bigiq_utility_license.py validate-modules:doc-required-mismatch lib/ansible/modules/network/f5/bigiq_utility_license_assignment.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/_ios_interface.py validate-modules:doc-choices-do-not-match-spec -lib/ansible/modules/network/ios/_ios_interface.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/_ios_interface.py validate-modules:doc-elements-mismatch -lib/ansible/modules/network/ios/_ios_interface.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/_ios_interface.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/_ios_interface.py validate-modules:missing-suboption-docs -lib/ansible/modules/network/ios/_ios_interface.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/_ios_interface.py validate-modules:undocumented-parameter -lib/ansible/modules/network/ios/_ios_l2_interface.py validate-modules:doc-choices-do-not-match-spec -lib/ansible/modules/network/ios/_ios_l2_interface.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/_ios_l2_interface.py validate-modules:doc-elements-mismatch -lib/ansible/modules/network/ios/_ios_l2_interface.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/_ios_l2_interface.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/_ios_l2_interface.py validate-modules:missing-suboption-docs -lib/ansible/modules/network/ios/_ios_l2_interface.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/_ios_l2_interface.py validate-modules:undocumented-parameter -lib/ansible/modules/network/ios/_ios_l3_interface.py validate-modules:doc-choices-do-not-match-spec -lib/ansible/modules/network/ios/_ios_l3_interface.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/_ios_l3_interface.py validate-modules:doc-elements-mismatch -lib/ansible/modules/network/ios/_ios_l3_interface.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/_ios_l3_interface.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/_ios_l3_interface.py validate-modules:missing-suboption-docs -lib/ansible/modules/network/ios/_ios_l3_interface.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/_ios_l3_interface.py validate-modules:undocumented-parameter -lib/ansible/modules/network/ios/_ios_vlan.py validate-modules:doc-choices-do-not-match-spec -lib/ansible/modules/network/ios/_ios_vlan.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/_ios_vlan.py validate-modules:doc-elements-mismatch -lib/ansible/modules/network/ios/_ios_vlan.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/_ios_vlan.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/_ios_vlan.py validate-modules:missing-suboption-docs -lib/ansible/modules/network/ios/_ios_vlan.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/ios/_ios_vlan.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/_ios_vlan.py validate-modules:undocumented-parameter -lib/ansible/modules/network/ios/ios_banner.py future-import-boilerplate -lib/ansible/modules/network/ios/ios_banner.py metaclass-boilerplate -lib/ansible/modules/network/ios/ios_banner.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_banner.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/ios_banner.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_bgp.py validate-modules:doc-elements-mismatch -lib/ansible/modules/network/ios/ios_bgp.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/ios_bgp.py validate-modules:invalid-ansiblemodule-schema -lib/ansible/modules/network/ios/ios_bgp.py validate-modules:nonexistent-parameter-documented -lib/ansible/modules/network/ios/ios_bgp.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/ios_command.py future-import-boilerplate -lib/ansible/modules/network/ios/ios_command.py metaclass-boilerplate -lib/ansible/modules/network/ios/ios_command.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_command.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/ios_command.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_command.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/ios/ios_command.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/ios_config.py future-import-boilerplate -lib/ansible/modules/network/ios/ios_config.py metaclass-boilerplate -lib/ansible/modules/network/ios/ios_config.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_config.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/ios_config.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_config.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/ios/ios_config.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/ios_facts.py future-import-boilerplate -lib/ansible/modules/network/ios/ios_facts.py metaclass-boilerplate -lib/ansible/modules/network/ios/ios_facts.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_facts.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_facts.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/ios/ios_facts.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/ios_interfaces.py validate-modules:doc-elements-mismatch -lib/ansible/modules/network/ios/ios_l2_interfaces.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/ios/ios_l3_interfaces.py validate-modules:doc-elements-mismatch -lib/ansible/modules/network/ios/ios_l3_interfaces.py validate-modules:invalid-ansiblemodule-schema -lib/ansible/modules/network/ios/ios_l3_interfaces.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/ios/ios_lag_interfaces.py validate-modules:doc-elements-mismatch -lib/ansible/modules/network/ios/ios_lag_interfaces.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_linkagg.py validate-modules:doc-choices-do-not-match-spec -lib/ansible/modules/network/ios/ios_linkagg.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_linkagg.py validate-modules:doc-elements-mismatch -lib/ansible/modules/network/ios/ios_linkagg.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/ios_linkagg.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_linkagg.py validate-modules:missing-suboption-docs -lib/ansible/modules/network/ios/ios_linkagg.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/ios/ios_linkagg.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/ios_linkagg.py validate-modules:undocumented-parameter -lib/ansible/modules/network/ios/ios_lldp.py validate-modules:doc-choices-do-not-match-spec -lib/ansible/modules/network/ios/ios_lldp.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_lldp.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/ios_lldp.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_logging.py future-import-boilerplate -lib/ansible/modules/network/ios/ios_logging.py metaclass-boilerplate -lib/ansible/modules/network/ios/ios_logging.py validate-modules:doc-choices-do-not-match-spec -lib/ansible/modules/network/ios/ios_logging.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_logging.py validate-modules:doc-elements-mismatch -lib/ansible/modules/network/ios/ios_logging.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/ios_logging.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_logging.py validate-modules:missing-suboption-docs -lib/ansible/modules/network/ios/ios_logging.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/ios_logging.py validate-modules:undocumented-parameter -lib/ansible/modules/network/ios/ios_ntp.py future-import-boilerplate -lib/ansible/modules/network/ios/ios_ntp.py metaclass-boilerplate -lib/ansible/modules/network/ios/ios_ntp.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_ntp.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/ios_ntp.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_ping.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_ping.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_ping.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/ios_static_route.py future-import-boilerplate -lib/ansible/modules/network/ios/ios_static_route.py metaclass-boilerplate -lib/ansible/modules/network/ios/ios_static_route.py validate-modules:doc-choices-do-not-match-spec -lib/ansible/modules/network/ios/ios_static_route.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_static_route.py validate-modules:doc-elements-mismatch -lib/ansible/modules/network/ios/ios_static_route.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/ios_static_route.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_static_route.py validate-modules:missing-suboption-docs -lib/ansible/modules/network/ios/ios_static_route.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/ios_static_route.py validate-modules:undocumented-parameter -lib/ansible/modules/network/ios/ios_system.py future-import-boilerplate -lib/ansible/modules/network/ios/ios_system.py metaclass-boilerplate -lib/ansible/modules/network/ios/ios_system.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_system.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/ios_system.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_system.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/ios/ios_system.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/ios_user.py future-import-boilerplate -lib/ansible/modules/network/ios/ios_user.py metaclass-boilerplate -lib/ansible/modules/network/ios/ios_user.py validate-modules:doc-choices-do-not-match-spec -lib/ansible/modules/network/ios/ios_user.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_user.py validate-modules:doc-elements-mismatch -lib/ansible/modules/network/ios/ios_user.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/ios_user.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_user.py validate-modules:missing-suboption-docs -lib/ansible/modules/network/ios/ios_user.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/ios/ios_user.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/network/ios/ios_user.py validate-modules:undocumented-parameter -lib/ansible/modules/network/ios/ios_vrf.py future-import-boilerplate -lib/ansible/modules/network/ios/ios_vrf.py metaclass-boilerplate -lib/ansible/modules/network/ios/ios_vrf.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/network/ios/ios_vrf.py validate-modules:doc-missing-type -lib/ansible/modules/network/ios/ios_vrf.py validate-modules:doc-required-mismatch -lib/ansible/modules/network/ios/ios_vrf.py validate-modules:parameter-list-no-elements -lib/ansible/modules/network/ios/ios_vrf.py validate-modules:parameter-type-not-in-doc lib/ansible/modules/network/iosxr/_iosxr_interface.py validate-modules:doc-choices-do-not-match-spec lib/ansible/modules/network/iosxr/_iosxr_interface.py validate-modules:doc-default-does-not-match-spec lib/ansible/modules/network/iosxr/_iosxr_interface.py validate-modules:doc-elements-mismatch @@ -3130,7 +2980,6 @@ lib/ansible/plugins/action/bigiq.py action-plugin-docs # undocumented action plu lib/ansible/plugins/action/dellos10.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` lib/ansible/plugins/action/dellos6.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` lib/ansible/plugins/action/dellos9.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` -lib/ansible/plugins/action/ios.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` lib/ansible/plugins/action/iosxr.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` lib/ansible/plugins/action/junos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` lib/ansible/plugins/action/normal.py action-plugin-docs # default action plugin for modules without a dedicated action plugin @@ -3163,8 +3012,6 @@ lib/ansible/plugins/doc_fragments/hcloud.py future-import-boilerplate lib/ansible/plugins/doc_fragments/hcloud.py metaclass-boilerplate lib/ansible/plugins/doc_fragments/inventory_cache.py future-import-boilerplate lib/ansible/plugins/doc_fragments/inventory_cache.py metaclass-boilerplate -lib/ansible/plugins/doc_fragments/ios.py future-import-boilerplate -lib/ansible/plugins/doc_fragments/ios.py metaclass-boilerplate lib/ansible/plugins/doc_fragments/iosxr.py future-import-boilerplate lib/ansible/plugins/doc_fragments/iosxr.py metaclass-boilerplate lib/ansible/plugins/doc_fragments/junos.py future-import-boilerplate diff --git a/test/units/modules/network/ios/fixtures/configure_terminal b/test/units/modules/network/ios/fixtures/configure_terminal deleted file mode 100644 index 139597f9cb0..00000000000 --- a/test/units/modules/network/ios/fixtures/configure_terminal +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/test/units/modules/network/ios/fixtures/ios_acl_interfaces.cfg b/test/units/modules/network/ios/fixtures/ios_acl_interfaces.cfg deleted file mode 100644 index 1462c135300..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_acl_interfaces.cfg +++ /dev/null @@ -1,8 +0,0 @@ -interface GigabitEthernet0/1 -ip access-group 110 in -ip access-group 123 out -ipv6 traffic-filter temp_v6 in -ipv6 traffic-filter test_v6 out -interface GigabitEthernet0/2 -ip access-group 110 in -ip access-group 123 out diff --git a/test/units/modules/network/ios/fixtures/ios_acls_config.cfg b/test/units/modules/network/ios/fixtures/ios_acls_config.cfg deleted file mode 100644 index c90c8db9090..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_acls_config.cfg +++ /dev/null @@ -1,4 +0,0 @@ -ip access-list extended 110 -deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10 -ipv6 access-list R1_TRAFFIC -deny tcp any eq www any eq telnet ack dscp af11 \ No newline at end of file diff --git a/test/units/modules/network/ios/fixtures/ios_banner_show_banner.txt b/test/units/modules/network/ios/fixtures/ios_banner_show_banner.txt deleted file mode 100644 index a134a31753c..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_banner_show_banner.txt +++ /dev/null @@ -1,3 +0,0 @@ -this is a sample -mulitline banner -used for testing diff --git a/test/units/modules/network/ios/fixtures/ios_banner_show_running_config_ios12.txt b/test/units/modules/network/ios/fixtures/ios_banner_show_running_config_ios12.txt deleted file mode 100644 index 004387a9b84..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_banner_show_running_config_ios12.txt +++ /dev/null @@ -1,15 +0,0 @@ -banner exec ^C -this is a sample -mulitline banner -used for testing -^C -banner login ^C -this is a sample -mulitline banner -used for testing -^C -! -dummy -end -of -config diff --git a/test/units/modules/network/ios/fixtures/ios_bgp_config.cfg b/test/units/modules/network/ios/fixtures/ios_bgp_config.cfg deleted file mode 100644 index 9fec934aa4a..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_bgp_config.cfg +++ /dev/null @@ -1,24 +0,0 @@ -! -router bgp 64496 - bgp router-id 192.0.2.1 - bgp log-neighbor-changes - neighbor 192.51.100.1 remote-as 64496 - neighbor 192.51.100.1 timers 120 360 360 - neighbor 198.51.100.3 remote-as 64498 - neighbor 203.0.113.5 remote-as 500 - neighbor 203.0.113.5 description EBGP_PEER - ! - address-family ipv4 - network 192.0.2.0 mask 255.255.254.0 route-map RMAP_1 - network 198.51.100.0 mask 255.255.255.128 route-map RMAP_2 - redistribute static metric 100 - redistribute eigrp metric 10 route-map RMAP_3 - neighbor 203.0.113.1 remove-private-as - neighbor 203.0.113.1 maximum-prefix 100 - exit-address-family - ! - address-family ipv4 multicast - network 203.0.113.0 mask 255.255.255.224 route-map RMAP_1 - network 192.0.2.0 mask 255.255.255.192 route-map RMAP_2 - exit-address-family -! diff --git a/test/units/modules/network/ios/fixtures/ios_config_config.cfg b/test/units/modules/network/ios/fixtures/ios_config_config.cfg deleted file mode 100644 index afad9d08aa7..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_config_config.cfg +++ /dev/null @@ -1,12 +0,0 @@ -! -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/test/units/modules/network/ios/fixtures/ios_config_defaults.cfg b/test/units/modules/network/ios/fixtures/ios_config_defaults.cfg deleted file mode 100644 index e54645ab142..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_config_defaults.cfg +++ /dev/null @@ -1,13 +0,0 @@ -! -hostname router -! -interface GigabitEthernet0/0 - ip address 1.2.3.4 255.255.255.0 - description test string - no shutdown -! -interface GigabitEthernet0/1 - ip address 6.7.8.9 255.255.255.0 - description test string - shutdown -! diff --git a/test/units/modules/network/ios/fixtures/ios_config_src.cfg b/test/units/modules/network/ios/fixtures/ios_config_src.cfg deleted file mode 100644 index b3d8961a99c..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_config_src.cfg +++ /dev/null @@ -1,11 +0,0 @@ -! -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/test/units/modules/network/ios/fixtures/ios_facts_dir b/test/units/modules/network/ios/fixtures/ios_facts_dir deleted file mode 100644 index 3adc44adba7..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_facts_dir +++ /dev/null @@ -1,23 +0,0 @@ -Directory of bootflash:/ - - 11 drwx 16384 Jun 1 2017 13:03:27 +00:00 lost+found -325121 drwx 4096 Jun 1 2017 13:03:54 +00:00 .super.iso.dir - 12 -rw- 31 Jun 22 2018 15:17:06 +00:00 .CsrLxc_LastInstall - 13 -rw- 69 Jun 1 2017 13:05:53 +00:00 virtual-instance.conf -438913 drwx 4096 Jun 1 2017 13:04:57 +00:00 core - 15 -rw- 125736960 Jun 1 2017 13:03:54 +00:00 iosxe-remote-mgmt.16.03.04.ova -105667 -rw- 292164568 Jun 1 2017 13:04:04 +00:00 csr1000v-mono-universalk9.16.03.04.SPA.pkg -105668 -rw- 34370768 Jun 1 2017 13:04:10 +00:00 csr1000v-rpboot.16.03.04.SPA.pkg -105666 -rw- 5317 Jun 1 2017 13:04:10 +00:00 packages.conf -195073 drwx 4096 Jun 1 2017 13:04:51 +00:00 .prst_sync -414529 drwx 4096 Jun 1 2017 13:04:57 +00:00 .rollback_timer - 16 -rw- 0 Jun 1 2017 13:05:00 +00:00 tracelogs.kZn -16257 drwx 24576 Jun 22 2018 16:03:11 +00:00 tracelogs -349505 drwx 4096 Jun 1 2017 13:05:08 +00:00 .installer -292609 drwx 4096 Jun 1 2017 13:05:59 +00:00 virtual-instance - 17 -rw- 30 Jun 22 2018 15:17:59 +00:00 throughput_monitor_params -48769 drwx 4096 Jun 1 2017 13:06:04 +00:00 onep - 19 -rw- 376 Jun 22 2018 15:18:11 +00:00 csrlxc-cfg.log - 20 -rw- 0 Jun 22 2018 15:17:59 +00:00 cvac.log - -7897796608 bytes total (6608056320 bytes free) diff --git a/test/units/modules/network/ios/fixtures/ios_facts_show_cdp b/test/units/modules/network/ios/fixtures/ios_facts_show_cdp deleted file mode 100644 index c5fff7d2782..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_facts_show_cdp +++ /dev/null @@ -1,4 +0,0 @@ -Global CDP information: - Sending CDP packets every 60 seconds - Sending a holdtime value of 180 seconds - Sending CDPv2 advertisements is enabled diff --git a/test/units/modules/network/ios/fixtures/ios_facts_show_cdp_neighbors_detail b/test/units/modules/network/ios/fixtures/ios_facts_show_cdp_neighbors_detail deleted file mode 100644 index b3d5453dd29..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_facts_show_cdp_neighbors_detail +++ /dev/null @@ -1,40 +0,0 @@ -------------------------- -Device ID: R2 -Entry address(es): - IP address: 10.0.0.3 -Platform: cisco CSR1000V, Capabilities: Router IGMP -Interface: GigabitEthernet1, Port ID (outgoing port): GigabitEthernet2 -Holdtime : 149 sec - -Version : -Cisco IOS Software [Everest], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.6.4, RELEASE SOFTWARE (fc3) -Technical Support: http://www.cisco.com/techsupport -Copyright (c) 1986-2018 by Cisco Systems, Inc. -Compiled Sun 08-Jul-18 04:30 by mcpre - -advertisement version: 2 -Duplex: full -Management address(es): - IP address: 10.0.0.3 - -------------------------- -Device ID: R3 -Entry address(es): - IP address: 10.0.0.4 -Platform: cisco CSR1000V, Capabilities: Router IGMP -Interface: GigabitEthernet1, Port ID (outgoing port): GigabitEthernet3 -Holdtime : 149 sec - -Version : -Cisco IOS Software [Everest], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.6.4, RELEASE SOFTWARE (fc3) -Technical Support: http://www.cisco.com/techsupport -Copyright (c) 1986-2018 by Cisco Systems, Inc. -Compiled Sun 08-Jul-18 04:30 by mcpre - -advertisement version: 2 -Duplex: full -Management address(es): - IP address: 10.0.0.4 - - -Total cdp entries displayed : 2 diff --git a/test/units/modules/network/ios/fixtures/ios_facts_show_interfaces b/test/units/modules/network/ios/fixtures/ios_facts_show_interfaces deleted file mode 100644 index 002b8b9eeed..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_facts_show_interfaces +++ /dev/null @@ -1,61 +0,0 @@ -GigabitEthernet0/0 is up, line protocol is up - Hardware is iGbE, address is 5e00.0003.0000 (bia 5e00.0003.0000) - Description: OOB Management - Internet address is 10.8.38.66/24 - MTU 1500 bytes, BW 1000000 Kbit/sec, DLY 10 usec, - reliability 253/255, txload 1/255, rxload 1/255 - Encapsulation ARPA, loopback not set - Keepalive set (10 sec) - Full Duplex, Auto Speed, link type is auto, media type is RJ45 - output flow-control is unsupported, input flow-control is unsupported - ARP type: ARPA, ARP Timeout 04:00:00 - Last input 00:00:00, output 00:00:00, output hang never - Last clearing of "show interface" counters never - Input queue: 0/75/0/0 (size/max/drops/flushes); Total output drops: 0 - Queueing strategy: fifo - Output queue: 0/40 (size/max) - 5 minute input rate 3000 bits/sec, 2 packets/sec - 5 minute output rate 2000 bits/sec, 2 packets/sec - 2226666 packets input, 398288440 bytes, 0 no buffer - Received 156442 broadcasts (0 IP multicasts) - 25440 runts, 0 giants, 0 throttles - 25440 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored - 0 watchdog, 0 multicast, 0 pause input - 1304895 packets output, 119337031 bytes, 0 underruns - 0 output errors, 0 collisions, 3 interface resets - 1083697 unknown protocol drops - 0 babbles, 0 late collision, 0 deferred - 1 lost carrier, 0 no carrier, 0 pause output - 0 output buffer failures, 0 output buffers swapped out -GigabitEthernet1 is up, line protocol is up - Hardware is CSR vNIC, address is 5e00.0006.0000 (bia 5e00.0006.0000) - Description: OOB Management - Internet address is 10.8.38.67/24 - MTU 1500 bytes, BW 1000000 Kbit/sec, DLY 10 usec, - reliability 255/255, txload 1/255, rxload 1/255 - Encapsulation ARPA, loopback not set - Keepalive set (10 sec) - Full Duplex, 1000Mbps, link type is auto, media type is RJ45 - output flow-control is unsupported, input flow-control is unsupported - ARP type: ARPA, ARP Timeout 04:00:00 - Last input 00:00:01, output 00:00:07, output hang never - Last clearing of "show interface" counters never - Input queue: 0/375/0/0 (size/max/drops/flushes); Total output drops: 0 - Queueing strategy: fifo - Output queue: 0/40 (size/max) - 5 minute input rate 3000 bits/sec, 3 packets/sec - 5 minute output rate 3000 bits/sec, 3 packets/sec - 8463791 packets input, 1445150230 bytes, 0 no buffer - Received 0 broadcasts (0 IP multicasts) - 0 runts, 0 giants, 0 throttles - 0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored - 0 watchdog, 0 multicast, 0 pause input - 3521571 packets output, 348781823 bytes, 0 underruns - 0 output errors, 0 collisions, 1 interface resets - 4150764 unknown protocol drops - 0 babbles, 0 late collision, 0 deferred - 0 lost carrier, 0 no carrier, 0 pause output - 0 output buffer failures, 0 output buffers swapped out -Tunnel1110 is up, line protocol is up - Hardware is Tunnel - Internet address is 10.10.10.2/30 diff --git a/test/units/modules/network/ios/fixtures/ios_facts_show_ip_interface b/test/units/modules/network/ios/fixtures/ios_facts_show_ip_interface deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/units/modules/network/ios/fixtures/ios_facts_show_ipv6_interface b/test/units/modules/network/ios/fixtures/ios_facts_show_ipv6_interface deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/units/modules/network/ios/fixtures/ios_facts_show_lldp b/test/units/modules/network/ios/fixtures/ios_facts_show_lldp deleted file mode 100644 index 09847c318c7..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_facts_show_lldp +++ /dev/null @@ -1,6 +0,0 @@ - -Global LLDP Information: - Status: ACTIVE - LLDP advertisements are sent every 30 seconds - LLDP hold time advertised is 120 seconds - LLDP interface reinitialisation delay is 2 seconds diff --git a/test/units/modules/network/ios/fixtures/ios_facts_show_lldp_neighbors_detail b/test/units/modules/network/ios/fixtures/ios_facts_show_lldp_neighbors_detail deleted file mode 100644 index adc4f30e466..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_facts_show_lldp_neighbors_detail +++ /dev/null @@ -1,50 +0,0 @@ ------------------------------------------------- -Local Intf: Gi1 -Chassis id: 001e.14d4.5300 -Port id: Gi3 -Port Description: GigabitEthernet3 -System Name: R3 - -System Description: -Cisco IOS Software [Everest], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.6.4, RELEASE SOFTWARE (fc3) -Technical Support: http://www.cisco.com/techsupport -Copyright (c) 1986-2018 by Cisco Systems, Inc. -Compiled Sun 08-Jul-18 04:30 by - -Time remaining: 116 seconds -System Capabilities: B,R -Enabled Capabilities: R -Management Addresses: - IP: 10.0.0.4 -Auto Negotiation - not supported -Physical media capabilities - not advertised -Media Attachment Unit type - not advertised -Vlan ID: - not advertised - ------------------------------------------------- -Local Intf: Gi3 -Chassis id: 001e.e6c9.6d00 -Port id: Gi1 -Port Description: GigabitEthernet1 -System Name: Rtest - -System Description: -Cisco IOS Software [Everest], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.6.4, RELEASE SOFTWARE (fc3) -Technical Support: http://www.cisco.com/techsupport -Copyright (c) 1986-2018 by Cisco Systems, Inc. -Compiled Sun 08-Jul-18 04:30 by - -Time remaining: 116 seconds -System Capabilities: B,R -Enabled Capabilities: R -Management Addresses: - IP: 10.3.0.3 -Auto Negotiation - not supported -Physical media capabilities - not advertised -Media Attachment Unit type - not advertised -Vlan ID: - not advertised - - -Total entries displayed: 2 - - diff --git a/test/units/modules/network/ios/fixtures/ios_facts_show_memory_statistics b/test/units/modules/network/ios/fixtures/ios_facts_show_memory_statistics deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/units/modules/network/ios/fixtures/ios_facts_show_version b/test/units/modules/network/ios/fixtures/ios_facts_show_version deleted file mode 100644 index 58322c80b43..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_facts_show_version +++ /dev/null @@ -1,68 +0,0 @@ -Cisco Internetwork Operating System Software -IOS (tm) C3750 Software (C3750-I5-M), Version 12.1(14)EA1, RELEASE SOFTWARE (fc1) -Copyright (c) 1986-2003 by cisco Systems, Inc. -Compiled Tue 22-Jul-03 13:17 by antonino -Image text-base: 0x00003000, data-base: 0x008F0CF8 - -ROM: Bootstrap program is C3750 boot loader -BOOTLDR: C3750 Boot Loader (C3750-HBOOT-M) Version 12.1(11r)AX, RELEASE SOFTWARE (fc1) - -3750RJ uptime is 1 hour, 29 minutes -System returned to ROM by power-on -System image file is "flash:c3750-i5-mz.121.14-EA1/c3750-i5-mz.121.14-EA1.bin" - -cisco WS-C3750-24TS (PowerPC405) processor (revision A0) with 120822K/10240K bytes of memory. -Processor board ID CAT0726R0ZU -Last reset from power-on -Bridging software. -2 Virtual Ethernet/IEEE 802.3 interface(s) -48 FastEthernet/IEEE 802.3 interface(s) -16 Gigabit Ethernet/IEEE 802.3 interface(s) -The password-recovery mechanism is enabled. - -512K bytes of flash-simulated non-volatile configuration memory. -Base ethernet MAC Address : 00:0D:29:B4:18:00 -Motherboard assembly number : 73-7055-06 -Power supply part number : 341-0034-01 -Motherboard serial number : CAT0726043V -Power supply serial number : PHI0708009K -Model revision number : A0 -Motherboard revision number : A0 -Model number : WS-C3750-24TS-E -System serial number : CAT0726R0ZU - -Switch Ports Model SW Version SW Image ------- ----- ----- ---------- ---------- -* 1 26 WS-C3750-24TS 12.1(14)EA1 C3750-I5-M -2 26 WS-C3750-24TS 12.1(14)EA1 C3750-I5-M -3 12 WS-C3750G-12S 12.1(14)EA1 C3750-I5-M - -Switch 02 ---------- -Switch Uptime : 1 hour, 29 minutes -Base ethernet MAC Address : 00:0D:29:B4:3F:00 -Motherboard assembly number : 73-7055-06 -Power supply part number : 341-0034-01 -Motherboard serial number : CAT07260438 -Power supply serial number : PHI0708008X -Model revision number : A0 -Motherboard revision number : A0 -Model number : WS-C3750-24TS-E -System serial number : CAT0726R10A - -Switch 03 ---------- -Switch Uptime : 1 hour, 29 minutes -Base ethernet MAC Address : 00:0D:BD:6A:3E:00 -Motherboard assembly number : 73-8307-06 -Power supply part number : 341-0048-01 -Motherboard serial number : CAT073205S2 -Power supply serial number : DTH0731055Z -Model revision number : A0 -Motherboard revision number : A0 -Model number : WS-C3750G-12S-E -System serial number : CAT0732R0M4 -Top assembly part number : 800-23419-01 -Top assembly revision number : A0 - -Configuration register is 0xF diff --git a/test/units/modules/network/ios/fixtures/ios_logging_config.cfg b/test/units/modules/network/ios/fixtures/ios_logging_config.cfg deleted file mode 100644 index 8a51afa7e5c..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_logging_config.cfg +++ /dev/null @@ -1,11 +0,0 @@ -! -logging buffered 5000 -logging console informational -logging facility local0 -no logging monitor -logging host 1.2.3.4 transport tcp -logging host 1.2.3.4 -logging host 2.3.4.5 -logging host 1.2.3.4 transport tcp port 1000 -logging host 1.2.3.4 transport udp port 1000 -! diff --git a/test/units/modules/network/ios/fixtures/ios_logging_config_ios12.cfg b/test/units/modules/network/ios/fixtures/ios_logging_config_ios12.cfg deleted file mode 100644 index 58be36dff5b..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_logging_config_ios12.cfg +++ /dev/null @@ -1,6 +0,0 @@ -! -logging buffered 5000 -logging console informational -logging facility local0 -logging 2.3.4.5 -! diff --git a/test/units/modules/network/ios/fixtures/ios_ntp_config.cfg b/test/units/modules/network/ios/fixtures/ios_ntp_config.cfg deleted file mode 100644 index ccd8558ab3e..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_ntp_config.cfg +++ /dev/null @@ -1,7 +0,0 @@ -ntp logging -ntp authentication-key 10 md5 15435A030726242723273C21181319000A 7 -ntp authenticate -ntp trusted-key 10 -ntp source Loopback0 -ntp access-group peer NTP_ACL -ntp server 10.75.32.5 diff --git a/test/units/modules/network/ios/fixtures/ios_ping_ping_10.255.255.250_repeat_2 b/test/units/modules/network/ios/fixtures/ios_ping_ping_10.255.255.250_repeat_2 deleted file mode 100644 index 9b25d64549f..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_ping_ping_10.255.255.250_repeat_2 +++ /dev/null @@ -1,4 +0,0 @@ -Type escape sequence to abort. -Sending 2, 100-byte ICMP Echos to 10.255.255.250, timeout is 2 seconds: -.. -Success rate is 0 percent (0/2) diff --git a/test/units/modules/network/ios/fixtures/ios_ping_ping_8.8.8.8_repeat_2 b/test/units/modules/network/ios/fixtures/ios_ping_ping_8.8.8.8_repeat_2 deleted file mode 100644 index 4dddd76b0f6..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_ping_ping_8.8.8.8_repeat_2 +++ /dev/null @@ -1,4 +0,0 @@ -Type escape sequence to abort. -Sending 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 diff --git a/test/units/modules/network/ios/fixtures/ios_static_routes_config.cfg b/test/units/modules/network/ios/fixtures/ios_static_routes_config.cfg deleted file mode 100644 index b947d5dcfef..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_static_routes_config.cfg +++ /dev/null @@ -1,2 +0,0 @@ -ip route vrf ansible_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 175 tag 50 -ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 60 diff --git a/test/units/modules/network/ios/fixtures/ios_system_config.cfg b/test/units/modules/network/ios/fixtures/ios_system_config.cfg deleted file mode 100644 index 3330b4aa345..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_system_config.cfg +++ /dev/null @@ -1,14 +0,0 @@ -! -hostname ios01 -! -ip domain list vrf management example.net -ip domain list example.net -ip domain list example.com -ip domain lookup source-interface GigabitEthernet0/0 -ip domain name vrf management eng.example.net -ip domain name eng.example.net -ip name-server vrf management 8.8.8.8 -ip name-server 8.8.8.8 -! -vrf definition test -! diff --git a/test/units/modules/network/ios/fixtures/ios_user_config.cfg b/test/units/modules/network/ios/fixtures/ios_user_config.cfg deleted file mode 100644 index dd5b2095fa2..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_user_config.cfg +++ /dev/null @@ -1,2 +0,0 @@ -username admin view network-admin secret 5 $1$mdQIUxjg$3t3lzBpfKfITKvFm1uEIY. -username ansible view network-admin secret 5 $1$3yWSXiIi$VdzV59ChiurrNdGxlDeAW/ diff --git a/test/units/modules/network/ios/fixtures/ios_vlan_config.cfg b/test/units/modules/network/ios/fixtures/ios_vlan_config.cfg deleted file mode 100644 index 69ac0b5e55e..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_vlan_config.cfg +++ /dev/null @@ -1,9 +0,0 @@ -VLAN Name Status Ports ----- -------------------------------- --------- ------------------------------- -1 default active Gi1/0/4, Gi1/0/5 - Gi1/0/52 - Gi1/0/54 -2 vlan2 active Gi1/0/6, Gi1/0/7 -9 vlan9 active Gi1/0/6 -1002 fddi-default act/unsup -1003 fddo-default act/unsup diff --git a/test/units/modules/network/ios/fixtures/ios_vrf_config.cfg b/test/units/modules/network/ios/fixtures/ios_vrf_config.cfg deleted file mode 100644 index 0a2d35f8fb8..00000000000 --- a/test/units/modules/network/ios/fixtures/ios_vrf_config.cfg +++ /dev/null @@ -1,81 +0,0 @@ -! -vrf definition test_1 - description test vrf 1 - rd 1:100 -! -vrf definition test_2 - description test vrf 2 -! -vrf definition test_3 -! -vrf definition test_17 - rd 2:100 - ! - address-family ipv4 - exit-address-family - ! - address-family ipv6 - route-target export 168.0.0.15:100 - route-target export 4:100 - route-target export 2:100 - route-target export 168.0.0.13:100 - route-target import 168.0.0.14:100 - route-target import 2:100 - route-target import 168.0.0.13:100 - exit-address-family -! -vrf definition test_18 - rd 168.0.0.9:100 - ! - address-family ipv4 - route-target export 168.0.0.10:100 - route-target export 168.0.0.9:100 - route-target export 3:100 - route-target import 168.0.0.9:100 - route-target import 3:100 - route-target import 168.0.0.10:600 - exit-address-family - ! - address-family ipv6 - exit-address-family -! -vrf definition test_19 - rd 10:700 - route-target export 2:102 - route-target export 2:103 - route-target export 2:100 - route-target export 2:101 - route-target import 2:104 - route-target import 2:105 - route-target import 2:100 - route-target import 2:101 - ! - address-family ipv4 - route-target export 2:102 - route-target export 2:103 - route-target export 2:100 - route-target export 2:101 - route-target import 2:104 - route-target import 2:105 - route-target import 2:100 - route-target import 2:101 - exit-address-family - ! - address-family ipv6 - route-target export 2:102 - route-target export 2:103 - route-target export 2:100 - route-target export 2:101 - route-target import 2:104 - route-target import 2:105 - route-target import 2:100 - route-target import 2:101 - exit-address-family -! -interface Ethernet1 - ip address 1.2.3.4/5 -! -interface Ethernet2 - ip address 1.2.3.4/5 - vrf forwarding test_1 -! diff --git a/test/units/modules/network/ios/fixtures/show_version b/test/units/modules/network/ios/fixtures/show_version deleted file mode 100644 index d293df3a181..00000000000 --- a/test/units/modules/network/ios/fixtures/show_version +++ /dev/null @@ -1,45 +0,0 @@ -Cisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.6(1)T, RELEASE SOFTWARE (fc1) -Technical Support: http://www.cisco.com/techsupport -Copyright (c) 1986-2015 by Cisco Systems, Inc. -Compiled Fri 20-Nov-15 13:39 by prod_rel_team - - -ROM: Bootstrap program is IOSv - -ios01 uptime is 7 weeks, 5 days, 11 hours, 14 minutes -System returned to ROM by reload -System image file is "flash0:/vios-adventerprisek9-m" -Last reload reason: Unknown reason - - - -This product contains cryptographic features and is subject to United -States and local country laws governing import, export, transfer and -use. Delivery of Cisco cryptographic products does not imply -third-party authority to import, export, distribute or use encryption. -Importers, exporters, distributors and users are responsible for -compliance with U.S. and local country laws. By using this product you -agree to comply with applicable laws and regulations. If you are unable -to comply with U.S. and local laws, return this product immediately. - -A summary of U.S. laws governing Cisco cryptographic products may be found at: -http://www.cisco.com/wwl/export/crypto/tool/stqrg.html - -If you require further assistance please contact us by sending email to -export@cisco.com. - -Cisco IOSv (revision 1.0) with with 472441K/50176K bytes of memory. -Processor board ID 99I10YFMUCJ3JEZMV4DQB -3 Gigabit Ethernet interfaces -DRAM configuration is 72 bits wide with parity disabled. -256K bytes of non-volatile configuration memory. -2097152K bytes of ATA System CompactFlash 0 (Read/Write) -0K bytes of ATA CompactFlash 1 (Read/Write) -0K bytes of ATA CompactFlash 2 (Read/Write) -10080K bytes of ATA CompactFlash 3 (Read/Write) - - - -Configuration register is 0x0 - - diff --git a/test/units/modules/network/ios/ios_module.py b/test/units/modules/network/ios/ios_module.py deleted file mode 100644 index 34df31c8127..00000000000 --- a/test/units/modules/network/ios/ios_module.py +++ /dev/null @@ -1,87 +0,0 @@ -# (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 . - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import os -import json - -from units.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 TestIosModule(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/test/units/modules/network/ios/test_ios_acl_interfaces.py b/test/units/modules/network/ios/test_ios_acl_interfaces.py deleted file mode 100644 index b3296062a56..00000000000 --- a/test/units/modules/network/ios/test_ios_acl_interfaces.py +++ /dev/null @@ -1,335 +0,0 @@ -# -# (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 units.compat.mock import patch -from ansible.modules.network.ios import ios_acl_interfaces -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosAclInterfacesModule(TestIosModule): - module = ios_acl_interfaces - - def setUp(self): - super(TestIosAclInterfacesModule, self).setUp() - - self.mock_get_config = patch('ansible.module_utils.network.common.network.Config.get_config') - self.get_config = self.mock_get_config.start() - - self.mock_load_config = patch('ansible.module_utils.network.common.network.Config.load_config') - self.load_config = self.mock_load_config.start() - - self.mock_get_resource_connection_config = patch('ansible.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.module_utils.network.common.facts.facts.' - 'get_resource_connection') - self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() - - self.mock_edit_config = patch('ansible.module_utils.network.ios.providers.providers.CliProvider.edit_config') - self.edit_config = self.mock_edit_config.start() - - self.mock_execute_show_command = patch('ansible.module_utils.network.ios.facts.acl_interfaces.acl_interfaces.' - 'Acl_InterfacesFacts.get_acl_interfaces_data') - self.execute_show_command = self.mock_execute_show_command.start() - - def tearDown(self): - super(TestIosAclInterfacesModule, 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('ios_acl_interfaces.cfg') - self.execute_show_command.side_effect = load_from_file - - def test_ios_acl_interfaces_merged(self): - set_module_args( - dict(config=[ - dict(name="GigabitEthernet0/1", - access_groups=[ - dict(afi="ipv4", - acls=[ - dict(name="merge_110", - direction="in"), - dict(name="merge_123", - direction="out") - ]), - dict(afi="ipv6", - acls=[ - dict(name="merge_temp_v6", - direction="in"), - dict(name="merge_test_v6", - direction="out") - ]) - ]), - dict(name="GigabitEthernet0/2", - access_groups=[ - dict(afi="ipv4", - acls=[ - dict(name="merge_110", - direction="in"), - dict(name="merge_123", - direction="out") - ]) - ]) - ], state="merged")) - commands = ['interface GigabitEthernet0/1', - 'ip access-group merge_110 in', - 'ip access-group merge_123 out', - 'ipv6 traffic-filter merge_temp_v6 in', - 'ipv6 traffic-filter merge_test_v6 out', - 'interface GigabitEthernet0/2', - 'ip access-group merge_110 in', - 'ip access-group merge_123 out' - ] - result = self.execute_module(changed=True) - self.assertEqual(result['commands'], commands) - - def test_ios_acl_interfaces_merged_idempotent(self): - set_module_args(dict( - config=[dict( - name="GigabitEthernet0/1", - access_groups=[dict( - afi="ipv4", - acls=[dict( - name="110", - direction="in" - ), dict( - name="123", - direction="out" - )] - ), dict( - afi="ipv6", - acls=[dict( - name="test_v6", - direction="out" - ), dict( - name="temp_v6", - direction="in" - )] - )] - ), dict( - name="GigabitEthernet0/2", - access_groups=[dict( - afi="ipv4", - acls=[dict( - name="110", - direction="in" - ), dict( - name="123", - direction="out" - )] - )] - )], state="merged" - )) - self.execute_module(changed=False, commands=[]) - - def test_ios_acl_interfaces_replaced(self): - set_module_args(dict( - config=[dict( - name="GigabitEthernet0/1", - access_groups=[dict( - afi="ipv4", - acls=[dict( - name="replace_100", - direction="out" - ), dict( - name="110", - direction="in" - )] - )] - )], state="replaced" - )) - commands = ['interface GigabitEthernet0/1', - 'no ip access-group 123 out', - 'no ipv6 traffic-filter temp_v6 in', - 'no ipv6 traffic-filter test_v6 out', - 'ip access-group replace_100 out' - ] - result = self.execute_module(changed=True) - self.assertEqual(result['commands'], commands) - - def test_ios_acl_interfaces_replaced_idempotent(self): - set_module_args(dict( - config=[dict( - name="GigabitEthernet0/1", - access_groups=[dict( - afi="ipv4", - acls=[dict( - name="110", - direction="in" - ), dict( - name="123", - direction="out" - )] - ), dict( - afi="ipv6", - acls=[dict( - name="test_v6", - direction="out" - ), dict( - name="temp_v6", - direction="in" - )] - )] - )], state="replaced" - )) - self.execute_module(changed=False, commands=[]) - - def test_ios_acl_interfaces_overridden(self): - set_module_args(dict( - config=[dict( - name="GigabitEthernet0/1", - access_groups=[dict( - afi="ipv4", - acls=[dict( - name="100", - direction="out" - ), dict( - name="110", - direction="in" - )] - )] - )], state="overridden" - )) - - commands = [ - 'interface GigabitEthernet0/1', - 'no ip access-group 123 out', - 'no ipv6 traffic-filter test_v6 out', - 'no ipv6 traffic-filter temp_v6 in', - 'ip access-group 100 out', - 'interface GigabitEthernet0/2', - 'no ip access-group 110 in', - 'no ip access-group 123 out' - ] - self.execute_module(changed=True, commands=commands) - - def test_ios_acl_interfaces_overridden_idempotent(self): - set_module_args(dict( - config=[dict( - name="GigabitEthernet0/1", - access_groups=[dict( - afi="ipv4", - acls=[dict( - name="110", - direction="in" - ), dict( - name="123", - direction="out" - )] - ), dict( - afi="ipv6", - acls=[dict( - name="test_v6", - direction="out" - ), dict( - name="temp_v6", - direction="in" - )] - )] - ), dict( - name="GigabitEthernet0/2", - access_groups=[dict( - afi="ipv4", - acls=[dict( - name="110", - direction="in" - ), dict( - name="123", - direction="out" - )] - )] - )], state="overridden" - )) - self.execute_module(changed=False, commands=[]) - - def test_ios_acl_interfaces_deleted_interface(self): - set_module_args( - dict(config=[ - dict(name="GigabitEthernet0/1") - ], state="deleted")) - commands = ['interface GigabitEthernet0/1', - 'no ip access-group 110 in', - 'no ip access-group 123 out', - 'no ipv6 traffic-filter test_v6 out', - 'no ipv6 traffic-filter temp_v6 in', - ] - self.execute_module(changed=True, commands=commands) - - def test_ios_acl_interfaces_deleted_afi(self): - set_module_args( - dict(config=[ - dict(name="GigabitEthernet0/1", - access_groups=[ - dict(afi="ipv6")]) - ], state="deleted")) - commands = ['interface GigabitEthernet0/1', - 'no ipv6 traffic-filter test_v6 out', - 'no ipv6 traffic-filter temp_v6 in', - ] - self.execute_module(changed=True, commands=commands) - - def test_ios_acl_interfaces_parsed(self): - set_module_args( - dict( - running_config="interface GigabitEthernet0/1\nip access-group 110 in\nipv6 traffic-filter test_v6 out", - state="parsed" - ) - ) - result = self.execute_module(changed=False) - parsed_list = [ - {'access_groups': - [ - {'acls': - [ - {'direction': 'in', 'name': '110'} - ], 'afi': 'ipv4'}, - {'acls': - [ - {'direction': 'out', 'name': 'test_v6'} - ], - 'afi': 'ipv6'} - ], - 'name': 'GigabitEthernet0/1'}] - self.assertEqual(parsed_list, result['parsed']) - - def test_ios_acl_interfaces_rendered(self): - set_module_args( - dict(config=[ - dict(name="GigabitEthernet0/1", - access_groups=[ - dict(afi="ipv4", - acls=[ - dict(name="110", - direction="in"), - dict(name="123", - direction="out") - ]), - dict(afi="ipv6", - acls=[ - dict(name="temp_v6", direction="in"), - dict(name="test_v6", direction="out") - ]) - ]) - ], state="rendered")) - commands = ['interface GigabitEthernet0/1', - 'ip access-group 110 in', - 'ip access-group 123 out', - 'ipv6 traffic-filter temp_v6 in', - 'ipv6 traffic-filter test_v6 out' - ] - result = self.execute_module(changed=False) - self.assertEqual(sorted(result['rendered']), commands) diff --git a/test/units/modules/network/ios/test_ios_acls.py b/test/units/modules/network/ios/test_ios_acls.py deleted file mode 100644 index 3dc7ee6aa24..00000000000 --- a/test/units/modules/network/ios/test_ios_acls.py +++ /dev/null @@ -1,451 +0,0 @@ -# -# (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 - -import sys - -import pytest - -# These tests and/or the module under test are unstable on Python 3.5. -# See: https://app.shippable.com/github/ansible/ansible/runs/161331/15/tests -# This is most likely due to CPython 3.5 not maintaining dict insertion order. -pytestmark = pytest.mark.skipif(sys.version_info[:2] == (3, 5), reason="Tests and/or module are unstable on Python 3.5.") - -from units.compat.mock import patch -from ansible.modules.network.ios import ios_acls -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosAclsModule(TestIosModule): - module = ios_acls - - def setUp(self): - super(TestIosAclsModule, self).setUp() - - self.mock_get_config = patch('ansible.module_utils.network.common.network.Config.get_config') - self.get_config = self.mock_get_config.start() - - self.mock_load_config = patch('ansible.module_utils.network.common.network.Config.load_config') - self.load_config = self.mock_load_config.start() - - self.mock_get_resource_connection_config = patch('ansible.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.module_utils.network.common.facts.facts.' - 'get_resource_connection') - self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() - - self.mock_edit_config = patch('ansible.module_utils.network.ios.providers.providers.CliProvider.edit_config') - self.edit_config = self.mock_edit_config.start() - - self.mock_execute_show_command = patch('ansible.module_utils.network.ios.facts.acls.acls.' - 'AclsFacts.get_acl_data') - self.execute_show_command = self.mock_execute_show_command.start() - - def tearDown(self): - super(TestIosAclsModule, 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, transport='cli'): - def load_from_file(*args, **kwargs): - return load_fixture('ios_acls_config.cfg') - self.execute_show_command.side_effect = load_from_file - - def test_ios_acls_merged(self): - set_module_args( - dict(config=[ - dict(afi="ipv4", - acls=[ - dict(name="std_acl", - acl_type="standard", - aces=[ - dict( - grant="deny", - source=dict( - address="192.0.2.0", - wildcard_bits="0.0.0.255" - ) - ) - ]) - ]), - dict(afi="ipv6", - acls=[ - dict(name="merge_v6_acl", - aces=[ - dict( - grant="deny", - protocol_options=dict( - tcp=dict(ack="true") - ), - source=dict( - any="true", - port_protocol=dict(eq="www") - ), - destination=dict( - any="true", - port_protocol=dict(eq="telnet")), - dscp="af11" - ) - ]) - ]) - ], state="merged" - ) - ) - result = self.execute_module(changed=True) - commands = [ - 'ip access-list standard std_acl', - 'deny 192.0.2.0 0.0.0.255', - 'ipv6 access-list merge_v6_acl', - 'deny tcp any eq www any eq telnet ack dscp af11' - ] - self.assertEqual(result['commands'], commands) - - def test_ios_acls_merged_idempotent(self): - set_module_args( - dict(config=[ - dict(afi="ipv4", - acls=[ - dict(name="110", - aces=[ - dict( - grant="deny", - protocol_options=dict( - icmp=dict(echo="true") - ), - source=dict( - address="192.0.2.0", - wildcard_bits="0.0.0.255" - ), - destination=dict( - address="192.0.3.0", - wildcard_bits="0.0.0.255" - ), - dscp="ef", - ttl=dict(eq=10) - ) - ]) - ]), - dict(afi="ipv6", - acls=[ - dict(name="R1_TRAFFIC", - aces=[ - dict( - grant="deny", - protocol_options=dict(tcp=dict(ack="true")), - source=dict( - any="true", - port_protocol=dict(eq="www") - ), - destination=dict( - any="true", - port_protocol=dict(eq="telnet") - ), - dscp="af11" - ) - ]) - ]) - ], state="merged" - )) - self.execute_module(changed=False, commands=[], sort=True) - - def test_ios_acls_replaced(self): - set_module_args( - dict(config=[ - dict(afi="ipv4", - acls=[ - dict(name="replace_acl", - acl_type="extended", - aces=[ - dict( - grant="deny", - protocol_options=dict( - tcp=dict(ack="true") - ), - source=dict( - address="198.51.100.0", - wildcard_bits="0.0.0.255" - ), - destination=dict( - address="198.51.101.0", - wildcard_bits="0.0.0.255", - port_protocol=dict(eq="telnet") - ), - tos=dict(service_value=12) - ) - ]) - ]) - ], state="replaced" - )) - result = self.execute_module(changed=True) - commands = [ - 'ip access-list extended replace_acl', - 'deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12' - ] - self.assertEqual(result['commands'], commands) - - def test_ios_acls_replaced_idempotent(self): - set_module_args( - dict(config=[ - dict(afi="ipv4", - acls=[ - dict(name="110", - aces=[ - dict( - grant="deny", - protocol_options=dict( - icmp=dict(echo="true") - ), - source=dict( - address="192.0.2.0", - wildcard_bits="0.0.0.255" - ), - destination=dict( - address="192.0.3.0", - wildcard_bits="0.0.0.255" - ), - dscp="ef", - ttl=dict(eq=10) - ) - ]) - ]) - ], state="replaced" - )) - self.execute_module(changed=False, commands=[], sort=True) - - def test_ios_acls_overridden(self): - set_module_args( - dict(config=[ - dict(afi="ipv4", - acls=[ - dict(name="150", - aces=[ - dict( - grant="deny", - protocol_options=dict( - tcp=dict(syn="true") - ), - source=dict( - address="198.51.100.0", - wildcard_bits="0.0.0.255", - port_protocol=dict(eq="telnet") - ), - destination=dict( - address="198.51.110.0", - wildcard_bits="0.0.0.255", - port_protocol=dict(eq="telnet") - ), - dscp="ef", - ttl=dict(eq=10) - ) - ]) - ]) - ], state="overridden" - )) - result = self.execute_module(changed=True) - commands = [ - 'no ip access-list extended 110', - 'no ipv6 access-list R1_TRAFFIC', - 'ip access-list extended 150', - 'deny tcp 198.51.100.0 0.0.0.255 eq telnet 198.51.110.0 0.0.0.255 eq telnet syn dscp ef ttl eq 10' - ] - self.assertEqual(result['commands'], commands) - - def test_ios_acls_overridden_idempotent(self): - set_module_args( - dict(config=[ - dict(afi="ipv4", - acls=[ - dict(name="110", - aces=[ - dict( - grant="deny", - protocol_options=dict( - icmp=dict(echo="true") - ), - source=dict( - address="192.0.2.0", - wildcard_bits="0.0.0.255" - ), - destination=dict( - address="192.0.3.0", - wildcard_bits="0.0.0.255" - ), - dscp="ef", - ttl=dict(eq=10) - ) - ]) - ]), - dict(afi="ipv6", - acls=[ - dict(name="R1_TRAFFIC", - aces=[ - dict( - grant="deny", - protocol_options=dict(tcp=dict(ack="true")), - source=dict( - any="true", - port_protocol=dict(eq="www") - ), - destination=dict( - any="true", - port_protocol=dict(eq="telnet") - ), - dscp="af11" - ) - ]) - ]) - ], state="overridden" - )) - self.execute_module(changed=False, commands=[], sort=True) - - def test_ios_acls_deleted_afi_based(self): - set_module_args( - dict(config=[ - dict(afi="ipv4") - ], state="deleted" - )) - result = self.execute_module(changed=True) - commands = [ - 'no ip access-list extended 110' - ] - self.assertEqual(result['commands'], commands) - - def test_ios_acls_deleted_acl_based(self): - set_module_args( - dict(config=[ - dict(afi="ipv4", - acls=[ - dict(name="110", - aces=[ - dict( - grant="deny", - protocol_options=dict( - icmp=dict(echo="true") - ), - source=dict( - address="192.0.2.0", - wildcard_bits="0.0.0.255" - ), - destination=dict( - address="192.0.3.0", - wildcard_bits="0.0.0.255" - ), - dscp="ef", - ttl=dict(eq=10) - ) - ]) - ]), - dict(afi="ipv6", - acls=[ - dict(name="R1_TRAFFIC", - aces=[ - dict( - grant="deny", - protocol_options=dict(tcp=dict(ack="true")), - source=dict( - any="true", - port_protocol=dict(eq="www") - ), - destination=dict( - any="true", - port_protocol=dict(eq="telnet") - ), - dscp="af11" - ) - ]) - ]) - ], state="deleted" - )) - result = self.execute_module(changed=True) - commands = [ - 'no ip access-list extended 110', - 'no ipv6 access-list R1_TRAFFIC', - ] - self.assertEqual(result['commands'], commands) - - def test_ios_acls_rendered(self): - set_module_args( - dict(config=[ - dict(afi="ipv4", - acls=[ - dict(name="110", - aces=[ - dict( - grant="deny", - sequence="10", - protocol_options=dict( - tcp=dict(syn="true") - ), - source=dict( - address="192.0.2.0", - wildcard_bits="0.0.0.255" - ), - destination=dict( - address="192.0.3.0", - wildcard_bits="0.0.0.255", - port_protocol=dict(eq="www") - ), - dscp="ef", - ttl=dict(eq=10) - ) - ]) - ]) - ], state="rendered")) - commands = [ - 'ip access-list extended 110', - '10 deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www syn dscp ef ttl eq 10' - ] - result = self.execute_module(changed=False) - self.assertEqual(result['rendered'], commands) - - def test_ios_acls_parsed(self): - set_module_args( - dict(running_config="ipv6 access-list R1_TRAFFIC\ndeny tcp any eq www any eq telnet ack dscp af11", - state="parsed")) - result = self.execute_module(changed=False) - parsed_list = [ - { - "acls": [ - { - "aces": [ - { - "destination": { - "any": True, - "port_protocol": { - "eq": "telnet" - } - }, - "dscp": "af11", - "grant": "deny", - "protocol": "tcp", - "protocol_options": { - "tcp": { - "ack": True - } - }, - "source": { - "any": True, - "port_protocol": { - "eq": "www" - } - } - } - ], - "name": "R1_TRAFFIC" - } - ], - "afi": "ipv6" - } - ] - self.assertEqual(parsed_list, result['parsed']) diff --git a/test/units/modules/network/ios/test_ios_banner.py b/test/units/modules/network/ios/test_ios_banner.py deleted file mode 100644 index cdd43d8e799..00000000000 --- a/test/units/modules/network/ios/test_ios_banner.py +++ /dev/null @@ -1,76 +0,0 @@ -# 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 . - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from units.compat.mock import patch -from ansible.modules.network.ios import ios_banner -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosBannerModule(TestIosModule): - - module = ios_banner - - def setUp(self): - super(TestIosBannerModule, self).setUp() - - self.mock_get_config = patch('ansible.modules.network.ios.ios_banner.get_config') - self.get_config = self.mock_get_config.start() - - self.mock_load_config = patch('ansible.modules.network.ios.ios_banner.load_config') - self.load_config = self.mock_load_config.start() - - def tearDown(self): - super(TestIosBannerModule, self).tearDown() - self.mock_get_config.stop() - self.mock_load_config.stop() - - def load_fixtures(self, commands=None): - def load_from_file(*args, **kwargs): - return load_fixture('ios_banner_show_running_config_ios12.txt') - self.get_config.side_effect = load_from_file - - def test_ios_banner_create(self): - for banner_type in ('login', 'motd', 'exec', 'incoming', 'slip-ppp'): - set_module_args(dict(banner=banner_type, text='test\nbanner\nstring')) - commands = ['banner {0} @\ntest\nbanner\nstring\n@'.format(banner_type)] - self.execute_module(changed=True, commands=commands) - - def test_ios_banner_remove(self): - set_module_args(dict(banner='login', state='absent')) - commands = ['no banner login'] - self.execute_module(changed=True, commands=commands) - - def test_ios_banner_nochange(self): - banner_text = load_fixture('ios_banner_show_banner.txt') - set_module_args(dict(banner='login', text=banner_text)) - self.execute_module() - - -class TestIosBannerIos12Module(TestIosBannerModule): - - def load_fixtures(self, commands=None): - def load_from_file(*args, **kwargs): - return load_fixture('ios_banner_show_running_config_ios12.txt') - self.get_config.side_effect = load_from_file - - def test_ios_banner_nochange(self): - banner_text = load_fixture('ios_banner_show_banner.txt') - set_module_args(dict(banner='exec', text=banner_text)) - self.execute_module() diff --git a/test/units/modules/network/ios/test_ios_bgp.py b/test/units/modules/network/ios/test_ios_bgp.py deleted file mode 100644 index 792219778ca..00000000000 --- a/test/units/modules/network/ios/test_ios_bgp.py +++ /dev/null @@ -1,207 +0,0 @@ -# -# (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.module_utils.network.ios.providers.cli.config.bgp.process import Provider -from ansible.modules.network.ios import ios_bgp -from .ios_module import TestIosModule, load_fixture - - -class TestIosBgpModule(TestIosModule): - module = ios_bgp - - def setUp(self): - super(TestIosBgpModule, self).setUp() - self._bgp_config = load_fixture('ios_bgp_config.cfg') - - def test_ios_bgp(self): - obj = Provider(params=dict(config=dict(bgp_as=64496, router_id='192.0.2.2', networks=None, - address_family=None), operation='merge')) - commands = obj.render(self._bgp_config) - self.assertEqual(commands, ['router bgp 64496', 'bgp router-id 192.0.2.2', 'exit']) - - def test_ios_bgp_idempotent(self): - obj = Provider(params=dict(config=dict(bgp_as=64496, router_id='192.0.2.1', networks=None, - address_family=None), operation='merge')) - commands = obj.render(self._bgp_config) - self.assertEqual(commands, []) - - def test_ios_bgp_remove(self): - obj = Provider(params=dict(config=dict(bgp_as=64496, networks=None, address_family=None), operation='delete')) - commands = obj.render(self._bgp_config) - self.assertEqual(commands, ['no router bgp 64496']) - - def test_ios_bgp_neighbor(self): - obj = Provider(params=dict(config=dict(bgp_as=64496, neighbors=[dict(neighbor='192.51.100.2', remote_as=64496)], - networks=None, address_family=None), - operation='merge')) - commands = obj.render(self._bgp_config) - self.assertEqual(commands, ['router bgp 64496', 'neighbor 192.51.100.2 remote-as 64496', 'exit']) - - def test_ios_bgp_neighbor_idempotent(self): - obj = Provider(params=dict(config=dict(bgp_as=64496, neighbors=[dict(neighbor='192.51.100.1', remote_as=64496, - timers=dict(keepalive=120, holdtime=360, - min_neighbor_holdtime=360))], - networks=None, address_family=None), - operation='merge')) - commands = obj.render(self._bgp_config) - self.assertEqual(commands, []) - - def test_ios_bgp_network(self): - obj = Provider(params=dict(config=dict(bgp_as=64496, networks=[dict(prefix='192.0.1.0', masklen=23, route_map='RMAP_1')], - address_family=None), - operation='merge')) - commands = obj.render(self._bgp_config) - self.assertEqual(sorted(commands), sorted(['router bgp 64496', 'network 192.0.1.0 mask 255.255.254.0 route-map RMAP_1', - 'exit'])) - - def test_ios_bgp_network_idempotent(self): - obj = Provider( - params=dict(config=dict(bgp_as=64496, networks=[dict(prefix='192.0.2.0', masklen=23, route_map='RMAP_1'), - dict(prefix='198.51.100.0', masklen=25, - route_map='RMAP_2')], - address_family=None), - operation='merge')) - commands = obj.render(self._bgp_config) - self.assertEqual(commands, []) - - def test_ios_bgp_address_family_redistribute(self): - rd_1 = dict(protocol='ospf', id='233', metric=90, route_map=None) - - config = dict(bgp_as=64496, address_family=[dict(afi='ipv4', safi='unicast', redistribute=[rd_1])], - networks=None) - - obj = Provider(params=dict(config=config, operation='merge')) - - commands = obj.render(self._bgp_config) - cmd = ['router bgp 64496', 'address-family ipv4', 'redistribute ospf 233 metric 90', - 'exit-address-family', 'exit'] - self.assertEqual(sorted(commands), sorted(cmd)) - - def test_ios_bgp_address_family_redistribute_idempotent(self): - rd_1 = dict(protocol='eigrp', metric=10, route_map='RMAP_3', id=None) - rd_2 = dict(protocol='static', metric=100, id=None, route_map=None) - - config = dict(bgp_as=64496, address_family=[dict(afi='ipv4', safi='unicast', redistribute=[rd_1, rd_2])], - networks=None) - - obj = Provider(params=dict(config=config, operation='merge')) - - commands = obj.render(self._bgp_config) - self.assertEqual(commands, []) - - def test_ios_bgp_address_family_neighbors(self): - af_nbr_1 = dict(neighbor='192.51.100.1', maximum_prefix=35, activate=True) - af_nbr_2 = dict(neighbor='192.51.100.3', route_reflector_client=True, activate=True) - - config = dict(bgp_as=64496, address_family=[dict(afi='ipv4', safi='multicast', neighbors=[af_nbr_1, af_nbr_2])], - networks=None) - - obj = Provider(params=dict(config=config, operation='merge')) - - commands = obj.render(self._bgp_config) - cmd = ['router bgp 64496', 'address-family ipv4 multicast', 'neighbor 192.51.100.1 activate', - 'neighbor 192.51.100.1 maximum-prefix 35', 'neighbor 192.51.100.3 activate', - 'neighbor 192.51.100.3 route-reflector-client', 'exit-address-family', 'exit'] - self.assertEqual(sorted(commands), sorted(cmd)) - - def test_ios_bgp_address_family_neighbors_idempotent(self): - af_nbr_1 = dict(neighbor='203.0.113.1', remove_private_as=True, maximum_prefix=100) - - config = dict(bgp_as=64496, address_family=[dict(afi='ipv4', safi='unicast', neighbors=[af_nbr_1])], - networks=None) - - obj = Provider(params=dict(config=config, operation='merge')) - - commands = obj.render(self._bgp_config) - self.assertEqual(commands, []) - - def test_ios_bgp_address_family_networks(self): - net = dict(prefix='1.0.0.0', masklen=8, route_map='RMAP_1') - net2 = dict(prefix='192.168.1.0', masklen=24, route_map='RMAP_2') - - config = dict(bgp_as=64496, address_family=[dict(afi='ipv4', safi='multicast', networks=[net, net2])], - networks=None) - - obj = Provider(params=dict(config=config, operation='merge')) - - commands = obj.render(self._bgp_config) - cmd = ['router bgp 64496', 'address-family ipv4 multicast', 'network 1.0.0.0 mask 255.0.0.0 route-map RMAP_1', - 'network 192.168.1.0 mask 255.255.255.0 route-map RMAP_2', 'exit-address-family', 'exit'] - self.assertEqual(sorted(commands), sorted(cmd)) - - def test_ios_bgp_address_family_networks_idempotent(self): - net = dict(prefix='203.0.113.0', masklen=27, route_map='RMAP_1') - net2 = dict(prefix='192.0.2.0', masklen=26, route_map='RMAP_2') - - config = dict(bgp_as=64496, address_family=[dict(afi='ipv4', safi='multicast', networks=[net, net2])], - networks=None) - - obj = Provider(params=dict(config=config, operation='merge')) - - commands = obj.render(self._bgp_config) - self.assertEqual(commands, []) - - def test_ios_bgp_operation_override(self): - net_1 = dict(prefix='1.0.0.0', masklen=8, route_map='RMAP_1') - net_2 = dict(prefix='192.168.1.0', masklen=24, route_map='RMAP_2') - nbr_1 = dict(neighbor='192.51.100.1', remote_as=64496, update_source='GigabitEthernet0/1') - nbr_2 = dict(neighbor='192.51.100.3', remote_as=64496, timers=dict(keepalive=300, holdtime=360, - min_neighbor_holdtime=360)) - af_nbr_1 = dict(neighbor='192.51.100.1', maximum_prefix=35) - af_nbr_2 = dict(neighbor='192.51.100.3', route_reflector_client=True) - - af_1 = dict(afi='ipv4', safi='unicast', neighbors=[af_nbr_1, af_nbr_2]) - af_2 = dict(afi='ipv4', safi='multicast', networks=[net_1, net_2]) - config = dict(bgp_as=64496, neighbors=[nbr_1, nbr_2], address_family=[af_1, af_2], networks=None) - - obj = Provider(params=dict(config=config, operation='override')) - commands = obj.render(self._bgp_config) - - cmd = ['no router bgp 64496', 'router bgp 64496', 'neighbor 192.51.100.1 remote-as 64496', - 'neighbor 192.51.100.1 update-source GigabitEthernet0/1', 'neighbor 192.51.100.3 remote-as 64496', - 'neighbor 192.51.100.3 timers 300 360 360', 'address-family ipv4', - 'neighbor 192.51.100.1 maximum-prefix 35', 'neighbor 192.51.100.3 route-reflector-client', - 'exit-address-family', - 'address-family ipv4 multicast', 'network 1.0.0.0 mask 255.0.0.0 route-map RMAP_1', - 'network 192.168.1.0 mask 255.255.255.0 route-map RMAP_2', - 'exit-address-family', 'exit'] - - self.assertEqual(sorted(commands), sorted(cmd)) - - def test_ios_bgp_operation_replace(self): - rd = dict(protocol='ospf', id=223, metric=110, route_map=None) - net = dict(prefix='203.0.113.0', masklen=27, route_map='RMAP_1') - net2 = dict(prefix='192.0.2.0', masklen=26, route_map='RMAP_2') - - af_1 = dict(afi='ipv4', safi='unicast', redistribute=[rd]) - af_2 = dict(afi='ipv4', safi='multicast', networks=[net, net2]) - - config = dict(bgp_as=64496, address_family=[af_1, af_2], networks=None) - obj = Provider(params=dict(config=config, operation='replace')) - commands = obj.render(self._bgp_config) - - cmd = ['router bgp 64496', 'address-family ipv4', 'redistribute ospf 223 metric 110', - 'no redistribute eigrp', - 'no redistribute static', 'exit-address-family', 'exit'] - - self.assertEqual(sorted(commands), sorted(cmd)) - - def test_ios_bgp_operation_replace_with_new_as(self): - rd = dict(protocol='ospf', id=223, metric=110, route_map=None) - - af_1 = dict(afi='ipv4', safi='unicast', redistribute=[rd]) - - config = dict(bgp_as=64497, address_family=[af_1], networks=None) - obj = Provider(params=dict(config=config, operation='replace')) - commands = obj.render(self._bgp_config) - - cmd = ['no router bgp 64496', 'router bgp 64497', 'address-family ipv4', - 'redistribute ospf 223 metric 110', - 'exit-address-family', 'exit'] - - self.assertEqual(sorted(commands), sorted(cmd)) diff --git a/test/units/modules/network/ios/test_ios_command.py b/test/units/modules/network/ios/test_ios_command.py deleted file mode 100644 index 1dab227b9ac..00000000000 --- a/test/units/modules/network/ios/test_ios_command.py +++ /dev/null @@ -1,126 +0,0 @@ -# (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 . - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import json - -from units.compat.mock import patch -from ansible.modules.network.ios import ios_command -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosCommandModule(TestIosModule): - - module = ios_command - - def setUp(self): - super(TestIosCommandModule, self).setUp() - - self.mock_run_commands = patch('ansible.modules.network.ios.ios_command.run_commands') - self.run_commands = self.mock_run_commands.start() - - def tearDown(self): - super(TestIosCommandModule, 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: - obj = json.loads(item['command']) - command = obj['command'] - except ValueError: - command = item['command'] - filename = str(command).replace(' ', '_') - output.append(load_fixture(filename)) - return output - - self.run_commands.side_effect = load_from_file - - def test_ios_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 Software')) - - def test_ios_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 Software')) - - def test_ios_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_ios_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_ios_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_ios_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_ios_command_match_all(self): - wait_for = ['result[0] contains "Cisco IOS"', - 'result[0] contains "IOSv Software"'] - set_module_args(dict(commands=['show version'], wait_for=wait_for, match='all')) - self.execute_module() - - def test_ios_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) - - def test_ios_command_configure_check_warning(self): - commands = ['configure terminal'] - set_module_args({ - 'commands': commands, - '_ansible_check_mode': True, - }) - result = self.execute_module() - self.assertEqual( - result['warnings'], - ['Only show commands are supported when using check mode, not executing configure terminal'], - ) - - def test_ios_command_configure_not_warning(self): - commands = ['configure terminal'] - set_module_args(dict(commands=commands)) - result = self.execute_module() - self.assertEqual(result['warnings'], []) diff --git a/test/units/modules/network/ios/test_ios_config.py b/test/units/modules/network/ios/test_ios_config.py deleted file mode 100644 index 0aa4dcc90be..00000000000 --- a/test/units/modules/network/ios/test_ios_config.py +++ /dev/null @@ -1,250 +0,0 @@ -# -# (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 . - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from units.compat.mock import patch, MagicMock -from ansible.modules.network.ios import ios_config -from ansible.plugins.cliconf.ios import Cliconf -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosConfigModule(TestIosModule): - - module = ios_config - - def setUp(self): - super(TestIosConfigModule, self).setUp() - - self.mock_get_config = patch('ansible.modules.network.ios.ios_config.get_config') - self.get_config = self.mock_get_config.start() - - self.mock_get_connection = patch('ansible.modules.network.ios.ios_config.get_connection') - self.get_connection = self.mock_get_connection.start() - - self.conn = self.get_connection() - self.conn.edit_config = MagicMock() - - self.mock_run_commands = patch('ansible.modules.network.ios.ios_config.run_commands') - self.run_commands = self.mock_run_commands.start() - - self.cliconf_obj = Cliconf(MagicMock()) - self.running_config = load_fixture('ios_config_config.cfg') - - def tearDown(self): - super(TestIosConfigModule, self).tearDown() - self.mock_get_config.stop() - self.mock_run_commands.stop() - self.mock_get_connection.stop() - - def load_fixtures(self, commands=None): - config_file = 'ios_config_config.cfg' - self.get_config.return_value = load_fixture(config_file) - self.get_connection.edit_config.return_value = None - - def test_ios_config_unchanged(self): - src = load_fixture('ios_config_config.cfg') - self.conn.get_diff = MagicMock(return_value=self.cliconf_obj.get_diff(src, src)) - set_module_args(dict(src=src)) - self.execute_module() - - def test_ios_config_src(self): - src = load_fixture('ios_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_ios_config_backup(self): - set_module_args(dict(backup=True)) - result = self.execute_module() - self.assertIn('__backup__', result) - - def test_ios_config_save_changed_true(self): - src = load_fixture('ios_config_src.cfg') - set_module_args(dict(src=src, save_when='changed')) - commands = ['hostname foo', 'interface GigabitEthernet0/0', 'no ip address'] - self.conn.get_diff = MagicMock(return_value=self.cliconf_obj.get_diff(src, self.running_config)) - self.execute_module(changed=True, commands=commands) - self.assertEqual(self.run_commands.call_count, 1) - self.assertEqual(self.get_config.call_count, 1) - self.assertEqual(self.conn.edit_config.call_count, 1) - args = self.run_commands.call_args[0][1] - self.assertIn('copy running-config startup-config\r', args) - - def test_ios_config_save_changed_false(self): - set_module_args(dict(save_when='changed')) - self.execute_module(changed=False) - self.assertEqual(self.run_commands.call_count, 0) - self.assertEqual(self.get_config.call_count, 0) - self.assertEqual(self.conn.edit_config.call_count, 0) - - def test_ios_config_save_always(self): - self.run_commands.return_value = "hostname foo" - set_module_args(dict(save_when='always')) - self.execute_module(changed=True) - self.assertEqual(self.run_commands.call_count, 1) - self.assertEqual(self.get_config.call_count, 0) - self.assertEqual(self.conn.edit_config.call_count, 0) - args = self.run_commands.call_args[0][1] - self.assertIn('copy running-config startup-config\r', args) - - def test_ios_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_ios_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 = ios_config.get_candidate_config(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_ios_config_before(self): - lines = ['hostname foo'] - set_module_args(dict(lines=lines, before=['test1', 'test2'])) - self.conn.get_diff = MagicMock(return_value=self.cliconf_obj.get_diff('\n'.join(lines), self.running_config)) - commands = ['test1', 'test2', 'hostname foo'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_config_after(self): - lines = ['hostname foo'] - set_module_args(dict(lines=lines, after=['test1', 'test2'])) - self.conn.get_diff = MagicMock(return_value=self.cliconf_obj.get_diff('\n'.join(lines), self.running_config)) - commands = ['hostname foo', 'test1', 'test2'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_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_ios_config_config(self): - config = 'hostname localhost' - lines = ['hostname router'] - set_module_args(dict(lines=lines, 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_ios_config_replace_block(self): - lines = ['description test string', 'test string'] - parents = ['interface GigabitEthernet0/0'] - set_module_args(dict(lines=lines, replace='block', parents=parents)) - - module = MagicMock() - module.params = {'lines': lines, 'parents': parents, 'src': None} - candidate_config = ios_config.get_candidate_config(module) - - self.conn.get_diff = MagicMock(return_value=self.cliconf_obj.get_diff(candidate_config, self.running_config, diff_replace='block', path=parents)) - - commands = parents + lines - self.execute_module(changed=True, commands=commands) - - def test_ios_config_match_none(self): - lines = ['hostname router'] - set_module_args(dict(lines=lines, match='none')) - 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_ios_config_match_none2(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')) - - module = MagicMock() - module.params = {'lines': lines, 'parents': parents, 'src': None} - candidate_config = ios_config.get_candidate_config(module) - self.conn.get_diff = MagicMock(return_value=self.cliconf_obj.get_diff(candidate_config, self.running_config, diff_match='none', path=parents)) - - commands = parents + lines - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_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')) - - module = MagicMock() - module.params = {'lines': lines, 'parents': parents, 'src': None} - candidate_config = ios_config.get_candidate_config(module) - self.conn.get_diff = MagicMock(return_value=self.cliconf_obj.get_diff(candidate_config, self.running_config, diff_match='strict', path=parents)) - - commands = parents + ['shutdown'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_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')) - - module = MagicMock() - module.params = {'lines': lines, 'parents': parents, 'src': None} - candidate_config = ios_config.get_candidate_config(module) - self.conn.get_diff = MagicMock(return_value=self.cliconf_obj.get_diff(candidate_config, self.running_config, diff_match='exact', path=parents)) - - commands = parents + lines - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_config_src_and_lines_fails(self): - args = dict(src='foo', lines='foo') - set_module_args(args) - self.execute_module(failed=True) - - def test_ios_config_src_and_parents_fails(self): - args = dict(src='foo', parents='foo') - set_module_args(args) - self.execute_module(failed=True) - - def test_ios_config_match_exact_requires_lines(self): - args = dict(match='exact') - set_module_args(args) - self.execute_module(failed=True) - - def test_ios_config_match_strict_requires_lines(self): - args = dict(match='strict') - set_module_args(args) - self.execute_module(failed=True) - - def test_ios_config_replace_block_requires_lines(self): - args = dict(replace='block') - set_module_args(args) - self.execute_module(failed=True) - - def test_ios_config_replace_config_requires_src(self): - args = dict(replace='config') - set_module_args(args) - self.execute_module(failed=True) diff --git a/test/units/modules/network/ios/test_ios_facts.py b/test/units/modules/network/ios/test_ios_facts.py deleted file mode 100644 index e197fe59959..00000000000 --- a/test/units/modules/network/ios/test_ios_facts.py +++ /dev/null @@ -1,123 +0,0 @@ -# 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 . - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from units.compat.mock import patch -from ansible.modules.network.ios import ios_facts -from ansible.module_utils.six import assertCountEqual -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosFactsModule(TestIosModule): - - module = ios_facts - - def setUp(self): - super(TestIosFactsModule, self).setUp() - self.mock_run_commands = patch('ansible.module_utils.network.ios.facts.legacy.base.run_commands') - self.run_commands = self.mock_run_commands.start() - - self.mock_get_resource_connection = patch('ansible.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.module_utils.network.ios.facts.legacy.base.get_capabilities') - self.get_capabilities = self.mock_get_capabilities.start() - self.get_capabilities.return_value = { - 'device_info': { - 'network_os': 'ios', - 'network_os_hostname': 'an-ios-01', - 'network_os_image': 'flash0:/vios-adventerprisek9-m', - 'network_os_model': 'WS-C3750-24TS', - 'network_os_version': '15.6(3)M2' - }, - 'network_api': 'cliconf' - } - - def tearDown(self): - super(TestIosFactsModule, self).tearDown() - self.mock_run_commands.stop() - self.mock_get_capabilities.stop() - - def load_fixtures(self, commands=None): - def load_from_file(*args, **kwargs): - commands = kwargs['commands'] - output = list() - - for command in commands: - filename = str(command).split(' | ')[0].replace(' ', '_') - output.append(load_fixture('ios_facts_%s' % filename)) - return output - - self.run_commands.side_effect = load_from_file - - def test_ios_facts_stacked(self): - set_module_args(dict(gather_subset='default')) - result = self.execute_module() - self.assertEqual( - result['ansible_facts']['ansible_net_model'], 'WS-C3750-24TS' - ) - self.assertEqual( - result['ansible_facts']['ansible_net_serialnum'], 'CAT0726R0ZU' - ) - self.assertEqual( - result['ansible_facts']['ansible_net_stacked_models'], ['WS-C3750-24TS-E', 'WS-C3750-24TS-E', 'WS-C3750G-12S-E'] - ) - self.assertEqual( - result['ansible_facts']['ansible_net_stacked_serialnums'], ['CAT0726R0ZU', 'CAT0726R10A', 'CAT0732R0M4'] - ) - - def test_ios_facts_tunnel_address(self): - set_module_args(dict(gather_subset='interfaces')) - result = self.execute_module() - self.assertEqual( - result['ansible_facts']['ansible_net_interfaces']['GigabitEthernet0/0']['macaddress'], '5e00.0003.0000' - ) - self.assertEqual( - result['ansible_facts']['ansible_net_interfaces']['GigabitEthernet1']['macaddress'], '5e00.0006.0000' - ) - self.assertIsNone( - result['ansible_facts']['ansible_net_interfaces']['Tunnel1110']['macaddress'] - ) - - def test_ios_facts_filesystems_info(self): - set_module_args(dict(gather_subset='hardware')) - result = self.execute_module() - self.assertEqual( - result['ansible_facts']['ansible_net_filesystems_info']['bootflash:']['spacetotal_kb'], 7712692.0 - ) - self.assertEqual( - result['ansible_facts']['ansible_net_filesystems_info']['bootflash:']['spacefree_kb'], 6453180.0 - ) - - def test_ios_facts_neighbors(self): - set_module_args(dict(gather_subset='interfaces')) - result = self.execute_module() - assertCountEqual( - self, - result['ansible_facts']['ansible_net_neighbors'].keys(), ['GigabitEthernet1', 'GigabitEthernet3'] - ) - assertCountEqual( - self, - result['ansible_facts']['ansible_net_neighbors']['GigabitEthernet1'], - [{'host': 'R2', 'port': 'GigabitEthernet2'}, {'host': 'R3', 'port': 'GigabitEthernet3'}] - ) - assertCountEqual( - self, - result['ansible_facts']['ansible_net_neighbors']['GigabitEthernet3'], [{'host': 'Rtest', 'port': 'Gi1'}] - ) diff --git a/test/units/modules/network/ios/test_ios_logging.py b/test/units/modules/network/ios/test_ios_logging.py deleted file mode 100644 index c54f4a6eb63..00000000000 --- a/test/units/modules/network/ios/test_ios_logging.py +++ /dev/null @@ -1,140 +0,0 @@ -# -# (c) 2016 Red Hat Inc. -# (c) 2017 Paul Neumann -# -# 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 . - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from units.compat.mock import patch -from ansible.modules.network.ios import ios_logging -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosLoggingModule(TestIosModule): - - module = ios_logging - - def setUp(self): - super(TestIosLoggingModule, self).setUp() - - self.mock_get_config = patch('ansible.modules.network.ios.ios_logging.get_config') - self.get_config = self.mock_get_config.start() - - self.mock_load_config = patch('ansible.modules.network.ios.ios_logging.load_config') - self.load_config = self.mock_load_config.start() - - self.mock_get_capabilities = patch('ansible.modules.network.ios.ios_logging.get_capabilities') - self.get_capabilities = self.mock_get_capabilities.start() - self.get_capabilities.return_value = {'device_info': {'network_os_version': '15.6(2)T'}} - - def tearDown(self): - super(TestIosLoggingModule, self).tearDown() - - self.mock_get_config.stop() - self.mock_load_config.stop() - self.mock_get_capabilities.stop() - - def load_fixtures(self, commands=None): - self.get_config.return_value = load_fixture('ios_logging_config.cfg') - self.load_config.return_value = None - - def test_ios_logging_buffer_size_changed_implicit(self): - set_module_args(dict(dest='buffered')) - commands = ['logging buffered 4096'] - self.execute_module(changed=True, commands=commands) - - def test_ios_logging_buffer_size_changed_explicit(self): - set_module_args(dict(dest='buffered', size=6000)) - commands = ['logging buffered 6000'] - self.execute_module(changed=True, commands=commands) - - def test_ios_logging_add_host(self): - set_module_args(dict(dest='host', name='192.168.1.1')) - commands = ['logging host 192.168.1.1'] - self.execute_module(changed=True, commands=commands) - - def test_ios_logging_host_idempotent(self): - set_module_args(dict(dest='host', name='2.3.4.5')) - commands = [] - self.execute_module(changed=False, commands=commands) - - def test_ios_logging_delete_non_exist_host(self): - set_module_args(dict(dest='host', name='192.168.1.1', state='absent')) - commands = [] - self.execute_module(changed=False, commands=commands) - - def test_ios_logging_delete_host(self): - set_module_args(dict(dest='host', name='2.3.4.5', state='absent')) - commands = ['no logging host 2.3.4.5'] - self.execute_module(changed=True, commands=commands) - - def test_ios_logging_configure_disabled_monitor_destination(self): - set_module_args(dict(dest='monitor', level='debugging')) - commands = ['logging monitor debugging'] - self.execute_module(changed=True, commands=commands) - - -class TestIosLoggingModuleIOS12(TestIosModule): - - module = ios_logging - - def setUp(self): - super(TestIosLoggingModuleIOS12, self).setUp() - - self.mock_get_config = patch('ansible.modules.network.ios.ios_logging.get_config') - self.get_config = self.mock_get_config.start() - - self.mock_load_config = patch('ansible.modules.network.ios.ios_logging.load_config') - self.load_config = self.mock_load_config.start() - - self.mock_get_capabilities = patch('ansible.modules.network.ios.ios_logging.get_capabilities') - self.get_capabilities = self.mock_get_capabilities.start() - self.get_capabilities.return_value = {'device_info': {'network_os_version': '12.1(2)T'}} - - def tearDown(self): - super(TestIosLoggingModuleIOS12, self).tearDown() - - self.mock_get_config.stop() - self.mock_load_config.stop() - self.mock_get_capabilities.stop() - - def load_fixtures(self, commands=None): - self.get_config.return_value = load_fixture('ios_logging_config_ios12.cfg') - self.load_config.return_value = None - - def test_ios_logging_add_host(self): - set_module_args(dict(dest='host', name='192.168.1.1')) - commands = ['logging 192.168.1.1'] - self.execute_module(changed=True, commands=commands) - - def test_ios_logging_host_idempotent(self): - set_module_args(dict(dest='host', name='2.3.4.5')) - commands = [] - self.execute_module(changed=False, commands=commands) - - def test_ios_logging_delete_non_exist_host(self): - set_module_args(dict(dest='host', name='192.168.1.1', state='absent')) - commands = [] - self.execute_module(changed=False, commands=commands) - - def test_ios_logging_delete_host(self): - set_module_args(dict(dest='host', name='2.3.4.5', state='absent')) - commands = ['no logging 2.3.4.5'] - self.execute_module(changed=True, commands=commands) diff --git a/test/units/modules/network/ios/test_ios_ntp.py b/test/units/modules/network/ios/test_ios_ntp.py deleted file mode 100644 index 0d106a75c0b..00000000000 --- a/test/units/modules/network/ios/test_ios_ntp.py +++ /dev/null @@ -1,99 +0,0 @@ -# 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 . - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from units.compat.mock import patch -from ansible.modules.network.ios import ios_ntp -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosNtpModule(TestIosModule): - - module = ios_ntp - - def setUp(self): - super(TestIosNtpModule, self).setUp() - - self.mock_get_config = patch('ansible.modules.network.ios.ios_ntp.get_config') - self.get_config = self.mock_get_config.start() - - self.mock_load_config = patch('ansible.modules.network.ios.ios_ntp.load_config') - self.load_config = self.mock_load_config.start() - - def tearDown(self): - super(TestIosNtpModule, 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('ios_ntp_config.cfg').strip() - self.load_config.return_value = dict(diff=None, session='session') - - def test_ios_ntp_idempotent(self): - set_module_args(dict( - server='10.75.32.5', - source_int='Loopback0', - acl='NTP_ACL', - logging=True, - auth=True, - auth_key='15435A030726242723273C21181319000A', - key_id='10', - state='present' - )) - commands = [] - self.execute_module(changed=False, commands=commands) - - def test_ios_ntp_config(self): - set_module_args(dict( - server='10.75.33.5', - source_int='Vlan2', - acl='NTP_ACL', - logging=True, - auth=True, - auth_key='15435A030726242723273C21181319000A', - key_id='10', - state='present' - )) - commands = [ - 'ntp server 10.75.33.5', - 'ntp source Vlan2' - ] - self.execute_module(changed=True, commands=commands) - - def test_ios_ntp_remove(self): - set_module_args(dict( - server='10.75.32.5', - source_int='Loopback0', - acl='NTP_ACL', - logging=True, - auth=True, - auth_key='15435A030726242723273C21181319000A', - key_id='10', - state='absent' - )) - commands = [ - 'no ntp server 10.75.32.5', - 'no ntp source Loopback0', - 'no ntp access-group peer NTP_ACL', - 'no ntp logging', - 'no ntp authenticate', - 'no ntp trusted-key 10', - 'no ntp authentication-key 10 md5 15435A030726242723273C21181319000A 7' - ] - self.execute_module(changed=True, commands=commands) diff --git a/test/units/modules/network/ios/test_ios_ping.py b/test/units/modules/network/ios/test_ios_ping.py deleted file mode 100644 index 0bb73bb7568..00000000000 --- a/test/units/modules/network/ios/test_ios_ping.py +++ /dev/null @@ -1,72 +0,0 @@ -# -# (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 . - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from units.compat.mock import patch -from ansible.modules.network.ios import ios_ping -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosPingModule(TestIosModule): - ''' Class used for Unit Tests agains ios_ping module ''' - module = ios_ping - - def setUp(self): - super(TestIosPingModule, self).setUp() - self.mock_run_commands = patch('ansible.modules.network.ios.ios_ping.run_commands') - self.run_commands = self.mock_run_commands.start() - - def tearDown(self): - super(TestIosPingModule, self).tearDown() - self.mock_run_commands.stop() - - def load_fixtures(self, commands=None): - def load_from_file(*args, **kwargs): - commands = kwargs['commands'] - output = list() - - for command in commands: - filename = str(command).split(' | ')[0].replace(' ', '_') - output.append(load_fixture('ios_ping_%s' % filename)) - return output - - self.run_commands.side_effect = load_from_file - - def test_ios_ping_expected_success(self): - ''' Test for successful pings when destination should be reachable ''' - set_module_args(dict(count=2, dest="8.8.8.8")) - self.execute_module() - - def test_ios_ping_expected_failure(self): - ''' Test for unsuccessful pings when destination should not be reachable ''' - set_module_args(dict(count=2, dest="10.255.255.250", state="absent")) - self.execute_module() - - def test_ios_ping_unexpected_success(self): - ''' Test for successful pings when destination should not be reachable - FAIL. ''' - set_module_args(dict(count=2, dest="8.8.8.8", state="absent")) - self.execute_module(failed=True) - - def test_ios_ping_unexpected_failure(self): - ''' Test for unsuccessful pings when destination should be reachable - FAIL. ''' - set_module_args(dict(count=2, dest="10.255.255.250")) - self.execute_module(failed=True) diff --git a/test/units/modules/network/ios/test_ios_static_routes.py b/test/units/modules/network/ios/test_ios_static_routes.py deleted file mode 100644 index 50b0ffa7ecd..00000000000 --- a/test/units/modules/network/ios/test_ios_static_routes.py +++ /dev/null @@ -1,357 +0,0 @@ -# -# (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 units.compat.mock import patch -from ansible.modules.network.ios import ios_static_routes -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosStaticRoutesModule(TestIosModule): - module = ios_static_routes - - def setUp(self): - super(TestIosStaticRoutesModule, self).setUp() - - self.mock_get_config = patch('ansible.module_utils.network.common.network.Config.get_config') - self.get_config = self.mock_get_config.start() - - self.mock_load_config = patch('ansible.module_utils.network.common.network.Config.load_config') - self.load_config = self.mock_load_config.start() - - self.mock_get_resource_connection_config = patch('ansible.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.module_utils.network.common.facts.facts.' - 'get_resource_connection') - self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() - - self.mock_edit_config = patch('ansible.module_utils.network.ios.providers.providers.CliProvider.edit_config') - self.edit_config = self.mock_edit_config.start() - - self.mock_execute_show_command = patch('ansible.module_utils.network.ios.facts.static_routes.static_routes.' - 'Static_RoutesFacts.get_static_routes_data') - self.execute_show_command = self.mock_execute_show_command.start() - - def tearDown(self): - super(TestIosStaticRoutesModule, 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, transport='cli'): - def load_from_file(*args, **kwargs): - return load_fixture('ios_static_routes_config.cfg') - self.execute_show_command.side_effect = load_from_file - - def test_ios_static_routes_merged(self): - set_module_args(dict( - config=[dict( - vrf="ansible_vrf", - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="192.0.2.0 255.255.255.0", - next_hops=[dict( - forward_router_address="192.0.2.1", - name="test_vrf", - tag=50, - track=150 - )], - )], - )], - ), dict( - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="198.51.100.0 255.255.255.0", - next_hops=[dict( - forward_router_address="198.51.101.1", - name="route_1", - distance_metric=110, - tag=40, - multicast=True - )], - )], - )], - )], state="merged" - )) - result = self.execute_module(changed=True) - commands = ['ip route vrf ansible_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 150 tag 50', - 'ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 40' - ] - self.assertEqual(result['commands'], commands) - - def test_ios_static_routes_merged_idempotent(self): - set_module_args(dict( - config=[dict( - vrf="ansible_vrf", - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="192.0.2.0/24", - next_hops=[dict( - forward_router_address="192.0.2.1", - name="test_vrf", - tag=50, - track=175 - )], - )], - )], - ), dict( - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="198.51.100.0/24", - next_hops=[dict( - forward_router_address="198.51.101.1", - name="route_1", - distance_metric=110, - tag=60, - multicast=True - )], - )], - )], - )], state="merged" - )) - self.execute_module(changed=False, commands=[], sort=True) - - def test_ios_static_routes_replaced(self): - set_module_args(dict( - config=[dict( - vrf="ansible_vrf", - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="192.0.2.0 255.255.255.0", - next_hops=[dict( - forward_router_address="192.0.2.1", - name="replaced_vrf", - tag=10, - track=170 - )], - )], - )], - ), dict( - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="198.51.100.0 255.255.255.0", - next_hops=[dict( - forward_router_address="198.51.101.1", - name="replaced_route_1", - distance_metric=110, - tag=60, - multicast=True - )], - )], - )], - )], state="replaced" - )) - result = self.execute_module(changed=True) - commands = ['ip route vrf ansible_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name replaced_vrf track 170 tag 10', - 'ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name replaced_route_1 tag 60' - ] - self.assertEqual(result['commands'], commands) - - def test_ios_static_routes_replaced_idempotent(self): - set_module_args(dict( - config=[dict( - vrf="ansible_vrf", - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="192.0.2.0/24", - next_hops=[dict( - forward_router_address="192.0.2.1", - name="test_vrf", - tag=50, - track=175 - )], - )], - )], - ), dict( - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="198.51.100.0/24", - next_hops=[dict( - forward_router_address="198.51.101.1", - name="route_1", - distance_metric=110, - tag=60, - multicast=True - )], - )], - )], - )], state="replaced" - )) - self.execute_module(changed=False, commands=[], sort=True) - - def test_ios_static_routes_overridden(self): - set_module_args(dict( - config=[dict( - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="198.51.100.0 255.255.255.0", - next_hops=[dict( - forward_router_address="198.51.101.1", - name="override_route_1", - distance_metric=150, - tag=50, - multicast=True - )], - )], - )], - )], state="overridden" - )) - result = self.execute_module(changed=True) - commands = [ - 'no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 60', - 'no ip route vrf ansible_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 175 tag 50', - 'ip route 198.51.100.0 255.255.255.0 198.51.101.1 150 multicast name override_route_1 tag 50' - ] - - self.assertEqual(result['commands'], commands) - - def test_ios_static_routes_overridden_idempotent(self): - set_module_args(dict( - config=[dict( - vrf="ansible_vrf", - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="192.0.2.0/24", - next_hops=[dict( - forward_router_address="192.0.2.1", - name="test_vrf", - tag=50, - track=175 - )], - )], - )], - ), dict( - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="198.51.100.0/24", - next_hops=[dict( - forward_router_address="198.51.101.1", - name="route_1", - distance_metric=110, - tag=60, - multicast=True - )], - )], - )], - )], state="overridden" - )) - self.execute_module(changed=False, commands=[], sort=True) - - def test_ios_delete_static_route_config(self): - set_module_args(dict( - config=[dict( - vrf="ansible_vrf", - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="192.0.2.0/24", - next_hops=[dict( - forward_router_address="192.0.2.1", - name="test_vrf", - tag=50, - track=175 - )], - )], - )], - ), dict( - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="198.51.100.0/24", - next_hops=[dict( - forward_router_address="198.51.101.1", - name="route_1", - distance_metric=110, - tag=60, - multicast=True - )], - )], - )], - )], state="deleted" - )) - result = self.execute_module(changed=True) - commands = [ - 'no ip route vrf ansible_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 175 tag 50', - 'no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 60' - ] - self.assertEqual(result['commands'], commands) - - def test_ios_delete_static_route_dest_based(self): - set_module_args(dict( - config=[dict( - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="198.51.100.0/24" - )], - )], - )], state="deleted" - )) - result = self.execute_module(changed=True) - commands = [ - 'no ip route 198.51.100.0 255.255.255.0 198.51.101.1 110 multicast name route_1 tag 60' - ] - self.assertEqual(result['commands'], commands) - - def test_ios_delete_static_route_vrf_based(self): - set_module_args(dict( - config=[dict( - vrf="ansible_vrf", - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="192.0.2.0/24" - )], - )], - )], state="deleted" - )) - result = self.execute_module(changed=True) - commands = [ - 'no ip route vrf ansible_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 175 tag 50' - ] - self.assertEqual(result['commands'], commands) - - def test_static_route_rendered(self): - set_module_args(dict( - config=[dict( - vrf="ansible_vrf", - address_families=[dict( - afi="ipv4", - routes=[dict( - dest="192.0.2.0/24", - next_hops=[dict( - forward_router_address="192.0.2.1", - name="test_vrf", - tag=50, - track=175 - )], - )], - )], - )], state="rendered" - )) - commands = [ - 'ip route vrf ansible_vrf 192.0.2.0 255.255.255.0 192.0.2.1 name test_vrf track 175 tag 50' - ] - result = self.execute_module(changed=False) - self.assertEqual(sorted(result['rendered']), commands) diff --git a/test/units/modules/network/ios/test_ios_system.py b/test/units/modules/network/ios/test_ios_system.py deleted file mode 100644 index 0d43949f479..00000000000 --- a/test/units/modules/network/ios/test_ios_system.py +++ /dev/null @@ -1,123 +0,0 @@ -# -# (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 . - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from units.compat.mock import patch -from ansible.modules.network.ios import ios_system -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosSystemModule(TestIosModule): - - module = ios_system - - def setUp(self): - super(TestIosSystemModule, self).setUp() - - self.mock_get_config = patch('ansible.modules.network.ios.ios_system.get_config') - self.get_config = self.mock_get_config.start() - - self.mock_load_config = patch('ansible.modules.network.ios.ios_system.load_config') - self.load_config = self.mock_load_config.start() - - def tearDown(self): - super(TestIosSystemModule, 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('ios_system_config.cfg') - self.load_config.return_value = None - - def test_ios_system_hostname_changed(self): - set_module_args(dict(hostname='foo')) - commands = ['hostname foo'] - self.execute_module(changed=True, commands=commands) - - def test_ios_system_domain_name(self): - set_module_args(dict(domain_name=['test.com'])) - commands = ['ip domain name test.com', - 'no ip domain name eng.example.net', - 'no ip domain name vrf management eng.example.net'] - self.execute_module(changed=True, commands=commands) - - def test_ios_system_domain_name_complex(self): - set_module_args(dict(domain_name=[{'name': 'test.com', 'vrf': 'test'}, - {'name': 'eng.example.net'}])) - commands = ['ip domain name vrf test test.com', - 'no ip domain name vrf management eng.example.net'] - self.execute_module(changed=True, commands=commands) - - def test_ios_system_domain_search(self): - set_module_args(dict(domain_search=['ansible.com', 'redhat.com'])) - commands = ['no ip domain list vrf management example.net', - 'no ip domain list example.net', - 'no ip domain list example.com', - 'ip domain list ansible.com', - 'ip domain list redhat.com'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_system_domain_search_complex(self): - set_module_args(dict(domain_search=[{'name': 'ansible.com', 'vrf': 'test'}])) - commands = ['no ip domain list vrf management example.net', - 'no ip domain list example.net', - 'no ip domain list example.com', - 'ip domain list vrf test ansible.com'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_system_lookup_source(self): - set_module_args(dict(lookup_source='Ethernet1')) - commands = ['ip domain lookup source-interface Ethernet1'] - self.execute_module(changed=True, commands=commands) - - def test_ios_system_name_servers(self): - name_servers = ['8.8.8.8', '8.8.4.4'] - set_module_args(dict(name_servers=name_servers)) - commands = ['no ip name-server vrf management 8.8.8.8', - 'ip name-server 8.8.4.4'] - self.execute_module(changed=True, commands=commands, sort=False) - - def rest_ios_system_name_servers_complex(self): - name_servers = dict(server='8.8.8.8', vrf='test') - set_module_args(dict(name_servers=name_servers)) - commands = ['no name-server 8.8.8.8', - 'no name-server vrf management 8.8.8.8', - 'ip name-server vrf test 8.8.8.8'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_system_state_absent(self): - set_module_args(dict(state='absent')) - commands = ['no hostname', - 'no ip domain lookup source-interface GigabitEthernet0/0', - 'no ip domain list vrf management', 'no ip domain list', - 'no ip domain name vrf management', 'no ip domain name', - 'no ip name-server vrf management', 'no ip name-server'] - self.execute_module(changed=True, commands=commands) - - def test_ios_system_no_change(self): - set_module_args(dict(hostname='ios01')) - self.execute_module(commands=[]) - - def test_ios_system_missing_vrf(self): - name_servers = dict(server='8.8.8.8', vrf='missing') - set_module_args(dict(name_servers=name_servers)) - self.execute_module(failed=True) diff --git a/test/units/modules/network/ios/test_ios_user.py b/test/units/modules/network/ios/test_ios_user.py deleted file mode 100644 index 5f0032bcae6..00000000000 --- a/test/units/modules/network/ios/test_ios_user.py +++ /dev/null @@ -1,141 +0,0 @@ -# (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 . - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from units.compat.mock import patch -from ansible.modules.network.ios import ios_user -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosUserModule(TestIosModule): - - module = ios_user - - def setUp(self): - super(TestIosUserModule, self).setUp() - - self.mock_get_config = patch('ansible.modules.network.ios.ios_user.get_config') - self.get_config = self.mock_get_config.start() - - self.mock_load_config = patch('ansible.modules.network.ios.ios_user.load_config') - self.load_config = self.mock_load_config.start() - - def tearDown(self): - super(TestIosUserModule, self).tearDown() - self.mock_get_config.stop() - self.mock_load_config.stop() - - def load_fixtures(self, commands=None, transport='cli'): - self.get_config.return_value = load_fixture('ios_user_config.cfg') - self.load_config.return_value = dict(diff=None, session='session') - - def test_ios_user_create(self): - set_module_args(dict(name='test', nopassword=True)) - result = self.execute_module(changed=True) - self.assertEqual(result['commands'], ['username test nopassword']) - - def test_ios_user_delete(self): - set_module_args(dict(name='ansible', state='absent')) - result = self.execute_module(changed=True) - cmds = [ - { - "command": "no username ansible", "answer": "y", "newline": False, - "prompt": "This operation will remove all username related configurations with same name", - } - ] - - result_cmd = [] - for i in result['commands']: - result_cmd.append(i) - - self.assertEqual(result_cmd, cmds) - - def test_ios_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_ios_user_privilege(self): - set_module_args(dict(name='ansible', privilege=15)) - result = self.execute_module(changed=True) - self.assertEqual(result['commands'], ['username ansible privilege 15']) - - def test_ios_user_privilege_invalid(self): - set_module_args(dict(name='ansible', privilege=25)) - self.execute_module(failed=True) - - def test_ios_user_purge(self): - set_module_args(dict(purge=True)) - result = self.execute_module(changed=True) - cmd = { - "command": "no username ansible", "answer": "y", "newline": False, - "prompt": "This operation will remove all username related configurations with same name", - } - - result_cmd = [] - for i in result['commands']: - result_cmd.append(i) - - self.assertEqual(result_cmd, [cmd]) - - def test_ios_user_view(self): - set_module_args(dict(name='ansible', view='test')) - result = self.execute_module(changed=True) - self.assertEqual(result['commands'], ['username ansible view test']) - - def test_ios_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 secret test']) - - def test_ios_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_ios_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_ios_user_set_sshkey(self): - set_module_args(dict(name='ansible', sshkey='dGVzdA==')) - commands = [ - 'ip ssh pubkey-chain', - 'username ansible', - 'key-hash ssh-rsa 098F6BCD4621D373CADE4E832627B4F6', - 'exit', - 'exit' - ] - result = self.execute_module(changed=True, commands=commands) - self.assertEqual(result['commands'], commands) - - def test_ios_user_set_sshkey_multiple(self): - set_module_args(dict(name='ansible', sshkey=['dGVzdA==', 'eHWacB2=='])) - commands = [ - 'ip ssh pubkey-chain', - 'username ansible', - 'key-hash ssh-rsa 098F6BCD4621D373CADE4E832627B4F6', - 'key-hash ssh-rsa A019918340A1E9183388D9A675603036', - 'exit', - 'exit' - ] - result = self.execute_module(changed=True, commands=commands) - self.assertEqual(result['commands'], commands) diff --git a/test/units/modules/network/ios/test_ios_vlan.py b/test/units/modules/network/ios/test_ios_vlan.py deleted file mode 100644 index 201efd1ad49..00000000000 --- a/test/units/modules/network/ios/test_ios_vlan.py +++ /dev/null @@ -1,149 +0,0 @@ -# (c) 2018 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 . - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from units.compat.mock import patch -from ansible.modules.network.ios import _ios_vlan -from ansible.modules.network.ios._ios_vlan import parse_vlan_brief -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosVlanModule(TestIosModule): - - module = _ios_vlan - - def setUp(self): - super(TestIosVlanModule, self).setUp() - - self.mock_run_commands = patch('ansible.modules.network.ios._ios_vlan.run_commands') - self.run_commands = self.mock_run_commands.start() - - self.mock_load_config = patch('ansible.modules.network.ios._ios_vlan.load_config') - self.load_config = self.mock_load_config.start() - - def tearDown(self): - super(TestIosVlanModule, self).tearDown() - self.mock_run_commands.stop() - self.mock_load_config.stop() - - def load_fixtures(self, commands=None, transport='cli'): - self.run_commands.return_value = [load_fixture('ios_vlan_config.cfg')] - self.load_config.return_value = {'diff': None, 'session': 'session'} - - def test_ios_vlan_create(self): - set_module_args({'vlan_id': '3', 'name': 'test', 'state': 'present'}) - result = self.execute_module(changed=True) - expected_commands = [ - 'vlan 3', - 'name test', - ] - self.assertEqual(result['commands'], expected_commands) - - def test_ios_vlan_id_startwith_9(self): - set_module_args({'vlan_id': '9', 'name': 'vlan9', 'state': 'present'}) - result = self.execute_module(changed=False) - expected_commands = [] - self.assertEqual(result['commands'], expected_commands) - - def test_ios_vlan_rename(self): - set_module_args({'vlan_id': '2', 'name': 'test', 'state': 'present'}) - result = self.execute_module(changed=True) - expected_commands = [ - 'vlan 2', - 'name test', - ] - self.assertEqual(result['commands'], expected_commands) - - def test_ios_vlan_with_interfaces(self): - set_module_args({'vlan_id': '2', 'name': 'vlan2', 'state': 'present', 'interfaces': ['GigabitEthernet1/0/8', 'GigabitEthernet1/0/7']}) - result = self.execute_module(changed=True) - expected_commands = [ - 'vlan 2', - 'interface GigabitEthernet1/0/8', - 'switchport mode access', - 'switchport access vlan 2', - 'vlan 2', - 'interface GigabitEthernet1/0/6', - 'switchport mode access', - 'no switchport access vlan 2', - ] - self.assertEqual(result['commands'], expected_commands) - - def test_ios_vlan_with_interfaces_and_newvlan(self): - set_module_args({'vlan_id': '3', 'name': 'vlan3', 'state': 'present', 'interfaces': ['GigabitEthernet1/0/8', 'GigabitEthernet1/0/7']}) - result = self.execute_module(changed=True) - expected_commands = [ - 'vlan 3', - 'name vlan3', - 'interface GigabitEthernet1/0/8', - 'switchport mode access', - 'switchport access vlan 3', - 'interface GigabitEthernet1/0/7', - 'switchport mode access', - 'switchport access vlan 3', - ] - self.assertEqual(result['commands'], expected_commands) - - def test_parse_vlan_brief(self): - result = parse_vlan_brief(load_fixture('ios_vlan_config.cfg')) - obj = [ - { - 'name': 'default', - 'interfaces': [ - 'GigabitEthernet1/0/4', - 'GigabitEthernet1/0/5', - 'GigabitEthernet1/0/52', - 'GigabitEthernet1/0/54', - ], - 'state': 'active', - 'vlan_id': '1', - }, - { - 'name': 'vlan2', - 'interfaces': [ - 'GigabitEthernet1/0/6', - 'GigabitEthernet1/0/7', - ], - 'state': 'active', - 'vlan_id': '2', - }, - { - 'name': 'vlan9', - 'interfaces': [ - 'GigabitEthernet1/0/6', - ], - 'state': 'active', - 'vlan_id': '9', - }, - { - 'name': 'fddi-default', - 'interfaces': [], - 'state': 'act/unsup', - 'vlan_id': '1002', - }, - { - 'name': 'fddo-default', - 'interfaces': [], - 'state': 'act/unsup', - 'vlan_id': '1003', - }, - ] - self.assertEqual(result, obj) diff --git a/test/units/modules/network/ios/test_ios_vrf.py b/test/units/modules/network/ios/test_ios_vrf.py deleted file mode 100644 index 1b00c4e6652..00000000000 --- a/test/units/modules/network/ios/test_ios_vrf.py +++ /dev/null @@ -1,210 +0,0 @@ -# -# (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 . - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) - -__metaclass__ = type - -from units.compat.mock import patch -from ansible.modules.network.ios import ios_vrf -from units.modules.utils import set_module_args -from .ios_module import TestIosModule, load_fixture - - -class TestIosVrfModule(TestIosModule): - module = ios_vrf - - def setUp(self): - super(TestIosVrfModule, self).setUp() - - self.mock_get_config = patch('ansible.modules.network.ios.ios_vrf.get_config') - self.get_config = self.mock_get_config.start() - - self.mock_load_config = patch('ansible.modules.network.ios.ios_vrf.load_config') - self.load_config = self.mock_load_config.start() - - self.mock_exec_command = patch('ansible.modules.network.ios.ios_vrf.exec_command') - self.exec_command = self.mock_exec_command.start() - - def tearDown(self): - super(TestIosVrfModule, self).tearDown() - self.mock_get_config.stop() - self.mock_load_config.stop() - self.mock_exec_command.stop() - - def load_fixtures(self, commands=None): - self.get_config.return_value = load_fixture('ios_vrf_config.cfg') - self.exec_command.return_value = (0, load_fixture('ios_vrf_config.cfg').strip(), None) - self.load_config.return_value = None - - def test_ios_vrf_name(self): - set_module_args(dict(name='test_4')) - commands = ['vrf definition test_4'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_name_unchanged(self): - set_module_args(dict(name='test_1', rd='1:100', description='test vrf 1')) - self.execute_module() - - def test_ios_vrf_description(self): - set_module_args(dict(name='test_1', description='test string')) - commands = ['vrf definition test_1', 'description test string'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_rd(self): - set_module_args(dict(name='test_1', rd='2:100')) - commands = ['vrf definition test_1', 'rd 2:100'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_interfaces(self): - set_module_args(dict(name='test_1', interfaces=['Ethernet1'])) - commands = ['interface Ethernet2', 'no vrf forwarding test_1', 'interface Ethernet1', 'vrf forwarding test_1', 'ip address 1.2.3.4/5'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_state_absent(self): - set_module_args(dict(name='test_1', state='absent')) - commands = ['no vrf definition test_1'] - self.execute_module(changed=True, commands=commands) - - def test_ios_vrf_purge_all(self): - set_module_args(dict(purge=True)) - commands = ['no vrf definition test_1', 'no vrf definition test_2', 'no vrf definition test_3', 'no vrf definition test_17', - 'no vrf definition test_18', 'no vrf definition test_19'] - self.execute_module(changed=True, commands=commands) - - def test_ios_vrf_purge_all_but_one(self): - set_module_args(dict(name='test_1', purge=True)) - commands = ['no vrf definition test_2', 'no vrf definition test_3', 'no vrf definition test_17', 'no vrf definition test_18', - 'no vrf definition test_19'] - self.execute_module(changed=True, commands=commands) - - def test_ios_vrfs_no_purge(self): - vrfs = [{'name': 'test_1'}, {'name': 'test_4'}] - set_module_args(dict(vrfs=vrfs)) - commands = ['vrf definition test_4'] - self.execute_module(changed=True, commands=commands) - - def test_ios_vrfs_purge(self): - vrfs = [{'name': 'test_1'}, {'name': 'test_4'}] - set_module_args(dict(vrfs=vrfs, purge=True)) - commands = ['vrf definition test_4', 'no vrf definition test_2', - 'no vrf definition test_3', 'no vrf definition test_17', 'no vrf definition test_18', 'no vrf definition test_19'] - self.execute_module(changed=True, commands=commands) - - def test_ios_vrfs_global_arg(self): - vrfs = [{'name': 'test_1'}, {'name': 'test_2'}] - set_module_args(dict(vrfs=vrfs, description='test string')) - commands = ['vrf definition test_1', 'description test string', 'vrf definition test_2', 'description test string'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrfs_local_override_description(self): - vrfs = [{'name': 'test_1', 'description': 'test vrf 1'}, {'name': 'test_2'}] - set_module_args(dict(vrfs=vrfs, description='test string')) - commands = ['vrf definition test_2', 'description test string'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrfs_local_override_state(self): - vrfs = [{'name': 'test_1', 'state': 'absent'}, {'name': 'test_2'}] - set_module_args(dict(vrfs=vrfs, description='test string')) - commands = ['no vrf definition test_1', 'vrf definition test_2', 'description test string'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_route_both(self): - set_module_args(dict(name='test_5', rd='2:100', route_both=['2:100', '3:100'])) - commands = ['vrf definition test_5', 'address-family ipv4', 'exit', 'address-family ipv6', 'exit', 'rd 2:100', 'route-target import 2:100', - 'route-target import 3:100', 'route-target export 2:100', 'route-target export 3:100'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_route_import(self): - set_module_args(dict(name='test_6', rd='3:100', route_import=['3:100', '4:100'])) - commands = ['vrf definition test_6', 'rd 3:100', 'route-target import 3:100', - 'route-target import 4:100'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_route_export(self): - set_module_args(dict(name='test_7', rd='4:100', route_export=['3:100', '4:100'])) - commands = ['vrf definition test_7', 'rd 4:100', 'route-target export 3:100', - 'route-target export 4:100'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_route_both_mixed(self): - set_module_args(dict(name='test_8', rd='5:100', route_both=['3:100', '4:100'], route_export=['3:100', '4:100'])) - self.execute_module(changed=True) - - def test_ios_vrf_route_both_ipv4(self): - set_module_args(dict(name='test_9', rd='168.0.0.9:100', route_both_ipv4=['168.0.0.9:100', '3:100'])) - commands = ['vrf definition test_9', 'address-family ipv4', 'exit', 'rd 168.0.0.9:100', 'address-family ipv4', - 'route-target import 168.0.0.9:100', 'route-target import 3:100', 'exit-address-family', 'address-family ipv4', - 'route-target export 168.0.0.9:100', 'route-target export 3:100', 'exit-address-family'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_route_import_ipv4(self): - set_module_args(dict(name='test_10', rd='168.0.0.10:100', route_import_ipv4=['168.0.0.10:100', '3:100'])) - commands = ['vrf definition test_10', 'address-family ipv4', 'exit', 'rd 168.0.0.10:100', 'address-family ipv4', - 'route-target import 168.0.0.10:100', 'route-target import 3:100', 'exit-address-family'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_route_export_ipv4(self): - set_module_args(dict(name='test_11', rd='168.0.0.11:100', route_export_ipv4=['168.0.0.11:100', '3:100'])) - commands = ['vrf definition test_11', 'address-family ipv4', 'exit', 'rd 168.0.0.11:100', 'address-family ipv4', - 'route-target export 168.0.0.11:100', 'route-target export 3:100', 'exit-address-family'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_route_both_ipv4_mixed(self): - set_module_args(dict(name='test_12', rd='168.0.0.12:100', route_both_ipv4=['168.0.0.12:100', '3:100'], route_export_ipv4=['168.0.0.15:100', '6:100'])) - self.execute_module(changed=True) - - def test_ios_vrf_route_both_ipv6(self): - set_module_args(dict(name='test_13', rd='2:100', route_both_ipv6=['2:100', '168.0.0.13:100'])) - commands = ['vrf definition test_13', 'address-family ipv6', 'exit', 'rd 2:100', 'address-family ipv6', - 'route-target import 2:100', 'route-target import 168.0.0.13:100', 'exit-address-family', 'address-family ipv6', - 'route-target export 2:100', 'route-target export 168.0.0.13:100', 'exit-address-family'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_route_import_ipv6(self): - set_module_args(dict(name='test_14', rd='3:100', route_import_ipv6=['3:100', '168.0.0.14:100'])) - commands = ['vrf definition test_14', 'address-family ipv6', 'exit', 'rd 3:100', 'address-family ipv6', - 'route-target import 3:100', 'route-target import 168.0.0.14:100', 'exit-address-family'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_route_export_ipv6(self): - set_module_args(dict(name='test_15', rd='4:100', route_export_ipv6=['168.0.0.15:100', '4:100'])) - commands = ['vrf definition test_15', 'address-family ipv6', 'exit', 'rd 4:100', 'address-family ipv6', - 'route-target export 168.0.0.15:100', 'route-target export 4:100', 'exit-address-family'] - self.execute_module(changed=True, commands=commands, sort=False) - - def test_ios_vrf_route_both_ipv6_mixed(self): - set_module_args(dict(name='test_16', rd='5:100', route_both_ipv6=['168.0.0.9:100', '4:100'], route_export_ipv6=['168.0.0.12:100', '6:100'])) - self.execute_module(changed=True) - - def test_ios_vrf_route_both_ipv6_mixed_idempotent(self): - set_module_args(dict(name='test_17', rd='2:100', route_import_ipv6=['168.0.0.14:100'], route_both_ipv6=['2:100', '168.0.0.13:100'], - route_export_ipv6=['168.0.0.15:100', '4:100'])) - self.execute_module(changed=False, commands=[], sort=False) - - def test_ios_vrf_route_both_ipv4_mixed_idempotent(self): - set_module_args(dict(name='test_18', rd='168.0.0.9:100', route_import_ipv4=['168.0.0.10:600'], route_export_ipv4=['168.0.0.10:100'], - route_both_ipv4=['168.0.0.9:100', '3:100'])) - self.execute_module(changed=False, commands=[], sort=False) - - def test_ios_vrf_all_route_both_idempotent(self): - set_module_args(dict(name='test_19', rd='10:700', route_both=['2:100', '2:101'], route_export=['2:102', '2:103'], route_import=['2:104', '2:105'], - route_both_ipv4=['2:100', '2:101'], route_export_ipv4=['2:102', '2:103'], route_import_ipv4=['2:104', '2:105'], - route_both_ipv6=['2:100', '2:101'], route_export_ipv6=['2:102', '2:103'], route_import_ipv6=['2:104', '2:105'])) - self.execute_module(changed=False, commands=[], sort=False) diff --git a/test/units/plugins/cliconf/fixtures/ios/show_version b/test/units/plugins/cliconf/fixtures/ios/show_version deleted file mode 100644 index eadd3d3ad1f..00000000000 --- a/test/units/plugins/cliconf/fixtures/ios/show_version +++ /dev/null @@ -1,54 +0,0 @@ -Cisco IOS XE Software, Version 16.06.01 -Cisco IOS Software [Everest], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.6.1, RELEASE SOFTWARE (fc2) -Technical Support: http://www.cisco.com/techsupport -Copyright (c) 1986-2017 by Cisco Systems, Inc. -Compiled Sat 22-Jul-17 05:51 by mcpre - - -Cisco IOS-XE software, Copyright (c) 2005-2017 by cisco Systems, Inc. -All rights reserved. Certain components of Cisco IOS-XE software are -licensed under the GNU General Public License ("GPL") Version 2.0. The -software code licensed under GPL Version 2.0 is free software that comes -with ABSOLUTELY NO WARRANTY. You can redistribute and/or modify such -GPL code under the terms of GPL Version 2.0. For more details, see the -documentation or "License Notice" file accompanying the IOS-XE software, -or the applicable URL provided on the flyer accompanying the IOS-XE -software. - - -ROM: IOS-XE ROMMON - -an-csr-01 uptime is 1 day, 16 hours, 15 minutes -Uptime for this control processor is 1 day, 16 hours, 16 minutes -System returned to ROM by reload -System image file is "bootflash:packages.conf" -Last reload reason: Reload Command - - - -This product contains cryptographic features and is subject to United -States and local country laws governing import, export, transfer and -use. Delivery of Cisco cryptographic products does not imply -third-party authority to import, export, distribute or use encryption. -Importers, exporters, distributors and users are responsible for -compliance with U.S. and local country laws. By using this product you -agree to comply with applicable laws and regulations. If you are unable -to comply with U.S. and local laws, return this product immediately. - -A summary of U.S. laws governing Cisco cryptographic products may be found at: -http://www.cisco.com/wwl/export/crypto/tool/stqrg.html - -If you require further assistance please contact us by sending email to -export@cisco.com. - -License Level: ax -License Type: Default. No valid license found. -Next reload license Level: ax - -cisco CSR1000V (VXE) processor (revision VXE) with 1225511K/3075K bytes of memory. -Processor board ID 9I5BX4UHSO4 -3 Gigabit Ethernet interfaces -32768K bytes of non-volatile configuration memory. -3018776K bytes of physical memory. -16162815K bytes of virtual hard disk at bootflash:. -0K bytes of WebUI ODM Files at webui:. diff --git a/test/units/plugins/cliconf/fixtures/nos/show_chassis b/test/units/plugins/cliconf/fixtures/nos/show_chassis deleted file mode 100644 index af51cbaff78..00000000000 --- a/test/units/plugins/cliconf/fixtures/nos/show_chassis +++ /dev/null @@ -1,30 +0,0 @@ - -Chassis Name: BR-VDX6740 -switchType: 131 - -FAN Unit: 1 -Time Awake: 0 days - -FAN Unit: 2 -Time Awake: 0 days - -POWER SUPPLY Unit: 1 -Factory Part Num: 23-1000043-01 -Factory Serial Num: -Time Awake: 0 days - -POWER SUPPLY Unit: 2 -Factory Part Num: 23-1000043-01 -Factory Serial Num: -Time Awake: 0 days - -CHASSIS/WWN Unit: 1 -Power Consume Factor: 0 -Factory Part Num: 40-1000927-06 -Factory Serial Num: CPL2541K01E -Manufacture: Day: 11 Month: 8 Year: 14 -Update: Day: 18 Month: 7 Year: 2018 -Time Alive: 1116 days -Time Awake: 0 days - -Airflow direction : Port side INTAKE diff --git a/test/units/plugins/cliconf/fixtures/nos/show_running-config b/test/units/plugins/cliconf/fixtures/nos/show_running-config deleted file mode 100644 index 8a4f631fe2b..00000000000 --- a/test/units/plugins/cliconf/fixtures/nos/show_running-config +++ /dev/null @@ -1,549 +0,0 @@ -diag post rbridge-id 104 enable -ntp server 10.10.10.1 use-vrf mgmt-vrf -logging raslog console INFO -logging auditlog class SECURITY -logging auditlog class CONFIGURATION -logging auditlog class FIRMWARE -logging syslog-facility local LOG_LOCAL7 -logging syslog-client localip CHASSIS_IP -switch-attributes 104 - chassis-name VDX6740 - host-name LEAF4 -! -no support autoupload enable -line vty - exec-timeout 10 -! -zoning enabled-configuration cfg-name "" -zoning enabled-configuration default-zone-access allaccess -zoning enabled-configuration cfg-action cfg-save -dpod 104/0/1 - reserve -! -dpod 104/0/2 -! -dpod 104/0/3 -! -dpod 104/0/4 -! -dpod 104/0/5 -! -dpod 104/0/6 -! -dpod 104/0/7 -! -dpod 104/0/8 -! -dpod 104/0/9 -! -dpod 104/0/10 -! -dpod 104/0/11 -! -dpod 104/0/12 -! -dpod 104/0/13 -! -dpod 104/0/14 -! -dpod 104/0/15 -! -dpod 104/0/16 -! -dpod 104/0/17 -! -dpod 104/0/18 -! -dpod 104/0/19 -! -dpod 104/0/20 -! -dpod 104/0/21 -! -dpod 104/0/22 -! -dpod 104/0/23 -! -dpod 104/0/24 -! -dpod 104/0/25 -! -dpod 104/0/26 -! -dpod 104/0/27 -! -dpod 104/0/28 -! -dpod 104/0/29 -! -dpod 104/0/30 -! -dpod 104/0/31 -! -dpod 104/0/32 -! -dpod 104/0/33 -! -dpod 104/0/34 -! -dpod 104/0/35 -! -dpod 104/0/36 -! -dpod 104/0/37 -! -dpod 104/0/38 -! -dpod 104/0/39 -! -dpod 104/0/40 -! -dpod 104/0/41 -! -dpod 104/0/42 -! -dpod 104/0/43 -! -dpod 104/0/44 -! -dpod 104/0/45 -! -dpod 104/0/46 -! -dpod 104/0/47 -! -dpod 104/0/48 -! -dpod 104/0/49 -! -dpod 104/0/50 -! -dpod 104/0/51 -! -dpod 104/0/52 -! -role name admin desc Administrator -role name user desc User -aaa authentication login local -aaa accounting exec default start-stop none -aaa accounting commands default start-stop none -service password-encryption -username admin password "BwrsDbB+tABWGWpINOVKoQ==\n" encryption-level 7 role admin desc Administrator -username user password "BwrsDbB+tABWGWpINOVKoQ==\n" encryption-level 7 role user desc User -ip access-list extended test - seq 10 permit ip host 1.1.1.1 any log -! -snmp-server contact "Field Support." -snmp-server location "End User Premise." -snmp-server sys-descr "Extreme VDX Switch." -snmp-server enable trap -snmp-server community private groupname admin -snmp-server community public groupname user -snmp-server view All 1 included -snmp-server group admin v1 read All write All notify All -snmp-server group public v1 read All -snmp-server group public v2c read All -snmp-server group user v1 read All -snmp-server group user v2c read All -hardware - connector-group 104/0/1 - speed LowMixed - ! - connector-group 104/0/3 - speed LowMixed - ! - connector-group 104/0/5 - speed LowMixed - ! - connector-group 104/0/6 - speed LowMixed - ! -! -cee-map default - precedence 1 - priority-group-table 1 weight 40 pfc on - priority-group-table 15.0 pfc off - priority-group-table 15.1 pfc off - priority-group-table 15.2 pfc off - priority-group-table 15.3 pfc off - priority-group-table 15.4 pfc off - priority-group-table 15.5 pfc off - priority-group-table 15.6 pfc off - priority-group-table 15.7 pfc off - priority-group-table 2 weight 60 pfc off - priority-table 2 2 2 1 2 2 2 15.0 - remap fabric-priority priority 0 - remap lossless-priority priority 0 -! -fcoe - fabric-map default - vlan 1002 - san-mode local - priority 3 - virtual-fabric 128 - fcmap 0E:FC:00 - advertisement interval 8000 - keep-alive timeout - ! -! -interface Vlan 1 -! -fabric route mcast rbridge-id 104 -! -protocol lldp - advertise dcbx-fcoe-app-tlv - advertise dcbx-fcoe-logical-link-tlv - advertise dcbx-tlv - advertise bgp-auto-nbr-tlv - advertise optional-tlv management-address - advertise optional-tlv system-name - system-description Extreme-VDX-VCS 120 -! -vlan dot1q tag native -port-profile UpgradedVlanProfile - vlan-profile - switchport - switchport mode trunk - switchport trunk allowed vlan all - ! -! -port-profile default - vlan-profile - switchport - switchport mode trunk - switchport trunk native-vlan 1 - ! -! -port-profile-domain default - port-profile UpgradedVlanProfile -! -class-map cee -! -class-map default -! -rbridge-id 104 - switch-attributes chassis-name VDX6740 - switch-attributes host-name LEAF4 - vrf mgmt-vrf - address-family ipv4 unicast - ip route 0.0.0.0/0 10.26.0.1 - ! - address-family ipv6 unicast - ! - ! - system-monitor fan threshold marginal-threshold 1 down-threshold 2 - system-monitor fan alert state removed action raslog - system-monitor power threshold marginal-threshold 1 down-threshold 2 - system-monitor power alert state removed action raslog - system-monitor temp threshold marginal-threshold 1 down-threshold 2 - system-monitor cid-card threshold marginal-threshold 1 down-threshold 2 - system-monitor cid-card alert state none action none - system-monitor sfp alert state none action none - system-monitor compact-flash threshold marginal-threshold 1 down-threshold 0 - system-monitor MM threshold marginal-threshold 1 down-threshold 0 - system-monitor LineCard threshold marginal-threshold 1 down-threshold 2 - system-monitor LineCard alert state none action none - system-monitor SFM threshold marginal-threshold 1 down-threshold 2 - resource-monitor cpu enable - resource-monitor memory enable threshold 100 action raslog - resource-monitor process memory enable alarm 500 critical 600 - no protocol vrrp - no protocol vrrp-extended - hardware-profile tcam default - hardware-profile route-table default maximum_paths 8 openflow off - hardware-profile kap default - fabric neighbor-discovery - clock timezone America/Los_Angeles - ag - enable - counter reliability 25 - timeout fnm 120 - pg 0 - modes lb - rename pg0 - ! - ! - telnet server use-vrf default-vrf - telnet server use-vrf mgmt-vrf - ssh server key rsa 2048 - ssh server key ecdsa 256 - ssh server key dsa - ssh server use-vrf default-vrf - ssh server use-vrf mgmt-vrf - http server use-vrf default-vrf - http server use-vrf mgmt-vrf - fcoe - fcoe-enodes 0 - ! -! -interface Management 104/0 - no tcp burstrate - ip icmp echo-reply - no ip address dhcp - ip address 10.26.7.226/17 - ipv6 icmpv6 echo-reply - no ipv6 address autoconfig - no ipv6 address dhcp - vrf forwarding mgmt-vrf - no shutdown -! -interface TenGigabitEthernet 104/0/1 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/2 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/3 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/4 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/5 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/6 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/7 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/8 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/9 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/10 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/11 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/12 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/13 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/14 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/15 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/16 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/17 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/18 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/19 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/20 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/21 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/22 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/23 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/24 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/25 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/26 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/27 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/28 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/29 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/30 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/31 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/32 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/33 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/34 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/35 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/36 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/37 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/38 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/39 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/40 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/41 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/42 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/43 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/44 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/45 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/46 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/47 - fabric isl enable - fabric trunk enable - no shutdown -! -interface TenGigabitEthernet 104/0/48 - fabric isl enable - fabric trunk enable - no shutdown -! -interface FortyGigabitEthernet 104/0/49 - fabric isl enable - fabric trunk enable - no shutdown -! -interface FortyGigabitEthernet 104/0/50 - fabric isl enable - fabric trunk enable - no shutdown -! -interface FortyGigabitEthernet 104/0/51 - fabric isl enable - fabric trunk enable - no shutdown -! -interface FortyGigabitEthernet 104/0/52 - fabric isl enable - fabric trunk enable - no shutdown -! diff --git a/test/units/plugins/cliconf/fixtures/nos/show_version b/test/units/plugins/cliconf/fixtures/nos/show_version deleted file mode 100644 index 1accd8191e7..00000000000 --- a/test/units/plugins/cliconf/fixtures/nos/show_version +++ /dev/null @@ -1,17 +0,0 @@ -Network Operating System Software -Network Operating System Version: 7.2.0 -Copyright (c) 1995-2017 Brocade Communications Systems, Inc. -Firmware name: 7.2.0 -Build Time: 10:52:47 Jul 10, 2017 -Install Time: 01:32:03 Jan 5, 2018 -Kernel: 2.6.34.6 - -BootProm: 1.0.1 -Control Processor: e500mc with 4096 MB of memory - -Slot Name Primary/Secondary Versions Status ---------------------------------------------------------------------------- -SW/0 NOS 7.2.0 ACTIVE* - 7.2.0 -SW/1 NOS 7.2.0 STANDBY - 7.2.0 diff --git a/test/units/plugins/cliconf/fixtures/slxos/show_chassis b/test/units/plugins/cliconf/fixtures/slxos/show_chassis deleted file mode 100644 index 1f7f0c51b36..00000000000 --- a/test/units/plugins/cliconf/fixtures/slxos/show_chassis +++ /dev/null @@ -1,40 +0,0 @@ - -Chassis Name: BR-SLX9140 -switchType: 3001 - -FAN Unit: 1 -Time Awake: 36 days - -FAN Unit: 2 -Time Awake: 36 days - -FAN Unit: 3 -Time Awake: 36 days - -FAN Unit: 5 -Time Awake: 36 days - -FAN Unit: 6 -Time Awake: 36 days - -POWER SUPPLY Unit: 1 -Factory Part Num: 11-1111111-11 -Factory Serial Num: ASERIALNUMB -Time Awake: 36 days - -POWER SUPPLY Unit: 2 -Factory Part Num: 11-1111111-11 -Factory Serial Num: ASERIALNUMB -Time Awake: 36 days - -CHASSIS/WWN Unit: 1 -Power Consume Factor: 0 -Factory Part Num: 11-1111111-11 -Factory Serial Num: ASERIALNUMB -Manufacture: Day: 12 Month: 1 Year: 2017 -Update: Day: 5 Month: 4 Year: 2018 -Time Alive: 277 days -Time Awake: 36 days - -Airflow direction : Port side INTAKE - diff --git a/test/units/plugins/cliconf/fixtures/slxos/show_running-config b/test/units/plugins/cliconf/fixtures/slxos/show_running-config deleted file mode 100644 index b2e540d97e9..00000000000 --- a/test/units/plugins/cliconf/fixtures/slxos/show_running-config +++ /dev/null @@ -1,624 +0,0 @@ -root enable -host-table aging-mode conversational -clock timezone Europe/Warsaw -hardware - profile tcam default - profile overlay-visibility default - profile route-table default maximum_paths 8 - system-mode default -! -http server use-vrf default-vrf -http server use-vrf mgmt-vrf -node-id 1 -! -ntp server 172.16.10.2 use-vrf mgmt-vrf -! -logging raslog console INFO -logging syslog-server 10.1.5.11 use-vrf mgmt-vrf -! -logging auditlog class SECURITY -logging auditlog class CONFIGURATION -logging auditlog class FIRMWARE -logging syslog-facility local LOG_LOCAL0 -logging syslog-client localip CHASSIS_IP -switch-attributes chassis-name SLX9140-LEAF2 -switch-attributes host-name DC2LEAF2 -no support autoupload enable -support ffdc -resource-monitor cpu enable threshold 90 action raslog -resource-monitor memory enable threshold 100 action raslog -resource-monitor process memory enable alarm 1000 critical 1200 -system-monitor fan threshold marginal-threshold 1 down-threshold 2 -system-monitor fan alert state removed action raslog -system-monitor power threshold marginal-threshold 1 down-threshold 2 -system-monitor power alert state removed action raslog -system-monitor temp threshold marginal-threshold 1 down-threshold 2 -system-monitor cid-card threshold marginal-threshold 1 down-threshold 2 -system-monitor cid-card alert state none action none -system-monitor compact-flash threshold marginal-threshold 1 down-threshold 0 -system-monitor MM threshold marginal-threshold 1 down-threshold 0 -system-monitor LineCard threshold marginal-threshold 1 down-threshold 2 -system-monitor LineCard alert state none action none -system-monitor SFM threshold marginal-threshold 1 down-threshold 2 -telemetry server use-vrf mgmt-vrf - transport tcp - port 50051 - activate -! -telemetry profile system-utilization default_system_utilization_statistics - interval 60 - add total-system-memory - add total-used-memory - add total-free-memory - add cached-memory - add buffers - add user-free-memory - add kernel-free-memory - add total-swap-memory - add total-free-swap-memory - add total-used-swap-memory - add user-process - add system-process - add niced-process - add iowait - add hw-interrupt - add sw-interrupt - add idle-state - add steal-time - add uptime -! -telemetry profile interface default_interface_statistics - interval 30 - add out-pkts - add in-pkts - add out-unicast-pkts - add in-unicast-pkts - add out-broadcast-pkts - add in-broadcast-pkts - add out-multicast-pkts - add in-multicast-pkts - add out-pkts-per-second - add in-pkts-per-second - add out-bandwidth - add in-bandwidth - add out-octets - add in-octets - add out-errors - add in-errors - add out-crc-errors - add in-crc-errors - add out-discards - add in-discards -! -line vty - exec-timeout 10 -! -threshold-monitor Buffer limit 70 -vrf mgmt-vrf - address-family ipv4 unicast - ip route 0.0.0.0/0 172.168.192.1 - ! - address-family ipv6 unicast - ! -! -ssh server key rsa 2048 -ssh server key ecdsa 256 -ssh server key dsa -ssh server use-vrf default-vrf -ssh server use-vrf mgmt-vrf -telnet server use-vrf default-vrf -telnet server use-vrf mgmt-vrf -role name admin desc Administrator -role name user desc User -aaa authentication login local -aaa accounting exec default start-stop none -aaa accounting commands default start-stop none -service password-encryption -username admin password "AINTNOPARTYLIKEAHOTELPARTYCAUSEAHOTELPARTYDONTSLEEPNOONEWOULDEVERACTUALLYTYPETHISWHYAREYOUHERE\n" encryption-level 7 role admin desc Administrator -cee-map default - precedence 1 - priority-group-table 1 weight 40 pfc on - priority-group-table 15.0 pfc off - priority-group-table 15.1 pfc off - priority-group-table 15.2 pfc off - priority-group-table 15.3 pfc off - priority-group-table 15.4 pfc off - priority-group-table 15.5 pfc off - priority-group-table 15.6 pfc off - priority-group-table 15.7 pfc off - priority-group-table 2 weight 60 pfc off - priority-table 2 2 2 1 2 2 2 15.0 - remap lossless-priority priority 0 -! -mac access-list extended M1 - seq 10 permit any any -! -vlan 1 - ip igmp snooping startup-query-interval 100 - ipv6 mld snooping startup-query-interval 100 -! -vlan 100 -! -vlan 200 -! -vlan 1001 - router-interface Ve 1001 - description Thomas-Test-Cluster -! -qos map cos-mutation all-zero-map - map cos 0 to cos 0 - map cos 1 to cos 0 - map cos 2 to cos 0 - map cos 3 to cos 0 - map cos 4 to cos 0 - map cos 5 to cos 0 - map cos 6 to cos 0 - map cos 7 to cos 0 -! -qos map cos-mutation default - map cos 0 to cos 0 - map cos 1 to cos 1 - map cos 2 to cos 2 - map cos 3 to cos 3 - map cos 4 to cos 4 - map cos 5 to cos 5 - map cos 6 to cos 6 - map cos 7 to cos 7 -! -qos map cos-traffic-class all-zero-map - map cos 0 to traffic-class 0 - map cos 1 to traffic-class 0 - map cos 2 to traffic-class 0 - map cos 3 to traffic-class 0 - map cos 4 to traffic-class 0 - map cos 5 to traffic-class 0 - map cos 6 to traffic-class 0 - map cos 7 to traffic-class 0 -! -qos map cos-traffic-class default - map cos 0 to traffic-class 1 - map cos 1 to traffic-class 0 - map cos 2 to traffic-class 2 - map cos 3 to traffic-class 3 - map cos 4 to traffic-class 4 - map cos 5 to traffic-class 5 - map cos 6 to traffic-class 6 - map cos 7 to traffic-class 7 -! -qos map cos-dscp all-zero-map - map cos 0 to dscp 0 - map cos 1 to dscp 0 - map cos 2 to dscp 0 - map cos 3 to dscp 0 - map cos 4 to dscp 0 - map cos 5 to dscp 0 - map cos 6 to dscp 0 - map cos 7 to dscp 0 -! -qos map cos-dscp default - map cos 0 to dscp 0 - map cos 1 to dscp 8 - map cos 2 to dscp 16 - map cos 3 to dscp 24 - map cos 4 to dscp 32 - map cos 5 to dscp 40 - map cos 6 to dscp 48 - map cos 7 to dscp 56 -! -qos map traffic-class-cos all-zero-map - map traffic-class 0 to cos 0 - map traffic-class 1 to cos 0 - map traffic-class 2 to cos 0 - map traffic-class 3 to cos 0 - map traffic-class 4 to cos 0 - map traffic-class 5 to cos 0 - map traffic-class 6 to cos 0 - map traffic-class 7 to cos 0 -! -qos map traffic-class-cos default - map traffic-class 0 to cos 0 - map traffic-class 1 to cos 1 - map traffic-class 2 to cos 2 - map traffic-class 3 to cos 3 - map traffic-class 4 to cos 4 - map traffic-class 5 to cos 5 - map traffic-class 6 to cos 6 - map traffic-class 7 to cos 7 -! -qos map traffic-class-mutation all-zero-map - map traffic-class 0 to traffic-class 0 - map traffic-class 1 to traffic-class 0 - map traffic-class 2 to traffic-class 0 - map traffic-class 3 to traffic-class 0 - map traffic-class 4 to traffic-class 0 - map traffic-class 5 to traffic-class 0 - map traffic-class 6 to traffic-class 0 - map traffic-class 7 to traffic-class 0 -! -qos map traffic-class-mutation default - map traffic-class 0 to traffic-class 0 - map traffic-class 1 to traffic-class 1 - map traffic-class 2 to traffic-class 2 - map traffic-class 3 to traffic-class 3 - map traffic-class 4 to traffic-class 4 - map traffic-class 5 to traffic-class 5 - map traffic-class 6 to traffic-class 6 - map traffic-class 7 to traffic-class 7 -! -qos map traffic-class-dscp all-zero-map - map traffic-class 0 to dscp 0 - map traffic-class 1 to dscp 0 - map traffic-class 2 to dscp 0 - map traffic-class 3 to dscp 0 - map traffic-class 4 to dscp 0 - map traffic-class 5 to dscp 0 - map traffic-class 6 to dscp 0 - map traffic-class 7 to dscp 0 -! -qos map traffic-class-dscp default - map traffic-class 0 to dscp 0 - map traffic-class 1 to dscp 8 - map traffic-class 2 to dscp 16 - map traffic-class 3 to dscp 24 - map traffic-class 4 to dscp 32 - map traffic-class 5 to dscp 40 - map traffic-class 6 to dscp 48 - map traffic-class 7 to dscp 56 -! -qos map dscp-mutation all-zero-map - map dscp 0-63 to dscp 0 -! -qos map dscp-mutation default - map dscp 0 to dscp 0 - map dscp 1 to dscp 1 - map dscp 10 to dscp 10 - map dscp 11 to dscp 11 - map dscp 12 to dscp 12 - map dscp 13 to dscp 13 - map dscp 14 to dscp 14 - map dscp 15 to dscp 15 - map dscp 16 to dscp 16 - map dscp 17 to dscp 17 - map dscp 18 to dscp 18 - map dscp 19 to dscp 19 - map dscp 2 to dscp 2 - map dscp 20 to dscp 20 - map dscp 21 to dscp 21 - map dscp 22 to dscp 22 - map dscp 23 to dscp 23 - map dscp 24 to dscp 24 - map dscp 25 to dscp 25 - map dscp 26 to dscp 26 - map dscp 27 to dscp 27 - map dscp 28 to dscp 28 - map dscp 29 to dscp 29 - map dscp 3 to dscp 3 - map dscp 30 to dscp 30 - map dscp 31 to dscp 31 - map dscp 32 to dscp 32 - map dscp 33 to dscp 33 - map dscp 34 to dscp 34 - map dscp 35 to dscp 35 - map dscp 36 to dscp 36 - map dscp 37 to dscp 37 - map dscp 38 to dscp 38 - map dscp 39 to dscp 39 - map dscp 4 to dscp 4 - map dscp 40 to dscp 40 - map dscp 41 to dscp 41 - map dscp 42 to dscp 42 - map dscp 43 to dscp 43 - map dscp 44 to dscp 44 - map dscp 45 to dscp 45 - map dscp 46 to dscp 46 - map dscp 47 to dscp 47 - map dscp 48 to dscp 48 - map dscp 49 to dscp 49 - map dscp 5 to dscp 5 - map dscp 50 to dscp 50 - map dscp 51 to dscp 51 - map dscp 52 to dscp 52 - map dscp 53 to dscp 53 - map dscp 54 to dscp 54 - map dscp 55 to dscp 55 - map dscp 56 to dscp 56 - map dscp 57 to dscp 57 - map dscp 58 to dscp 58 - map dscp 59 to dscp 59 - map dscp 6 to dscp 6 - map dscp 60 to dscp 60 - map dscp 61 to dscp 61 - map dscp 62 to dscp 62 - map dscp 63 to dscp 63 - map dscp 7 to dscp 7 - map dscp 8 to dscp 8 - map dscp 9 to dscp 9 -! -qos map dscp-traffic-class all-zero-map - map dscp 0-63 to traffic-class 0 -! -qos map dscp-traffic-class default - map dscp 0-7 to traffic-class 0 - map dscp 16-23 to traffic-class 2 - map dscp 24-31 to traffic-class 3 - map dscp 32-39 to traffic-class 4 - map dscp 40-47 to traffic-class 5 - map dscp 48-55 to traffic-class 6 - map dscp 56-63 to traffic-class 7 - map dscp 8-15 to traffic-class 1 -! -qos map dscp-cos all-zero-map - map dscp 0-63 to cos 0 -! -qos map dscp-cos default - map dscp 0-7 to cos 0 - map dscp 16-23 to cos 2 - map dscp 24-31 to cos 3 - map dscp 32-39 to cos 4 - map dscp 40-47 to cos 5 - map dscp 48-55 to cos 6 - map dscp 56-63 to cos 7 - map dscp 8-15 to cos 1 -! -protocol lldp - advertise optional-tlv management-address - system-description Brocade BR-SLX9140 Router -! -vlan dot1q tag native -police-remark-profile default -! -class-map BD-100 -! -class-map C1 - match access-group M1 -! -class-map cee -! -class-map default -! -policy-map P1 - class C1 - police cir 1000000 - ! -! -policy-map P2 - class default - police cir 12121212 - ! -! -no protocol vrrp -no protocol vrrp-extended -router bgp - local-as 65301 - capability as4-enable - bfd interval 300 min-rx 300 multiplier 3 - neighbor leaf_group peer-group - neighbor leaf_group remote-as 65500 - neighbor leaf_group bfd - neighbor 10.220.4.3 remote-as 65500 - neighbor 10.220.4.3 peer-group leaf_group - address-family ipv4 unicast - network 172.32.252.5/32 - maximum-paths 8 - ! - address-family ipv6 unicast - ! - address-family l2vpn evpn - ! -! -interface Loopback 1 - ip address 172.16.128.6/32 - no shutdown -! -interface Loopback 2 - ip address 172.16.129.5/32 - no shutdown -! -interface Management 0 - no tcp burstrate - no shutdown - vrf forwarding mgmt-vrf - ip address dhcp -! -interface Ethernet 0/1 - speed 25000 - fec mode disabled - switchport - switchport mode access - switchport access vlan 1 - no shutdown -! -interface Ethernet 0/2 - no shutdown -! -interface Ethernet 0/3 - speed 25000 - fec mode RS-FEC - no shutdown -! -interface Ethernet 0/4 - shutdown -! -interface Ethernet 0/5 - service-policy in P1 - no shutdown -! -interface Ethernet 0/6 - mtu 1548 - description L2 Interface - no shutdown -! -interface Ethernet 0/7 - mtu 1548 - description L2 Interface - no shutdown -! -interface Ethernet 0/8 - switchport - switchport mode trunk - switchport trunk allowed vlan add 100,200 - switchport trunk tag native-vlan - shutdown -! -interface Ethernet 0/9 - shutdown -! -interface Ethernet 0/10 - no shutdown -! -interface Ethernet 0/11 - no shutdown -! -interface Ethernet 0/12 - no shutdown -! -interface Ethernet 0/13 - no shutdown -! -interface Ethernet 0/14 - no shutdown -! -interface Ethernet 0/15 - shutdown -! -interface Ethernet 0/16 - shutdown -! -interface Ethernet 0/17 - shutdown -! -interface Ethernet 0/18 - shutdown -! -interface Ethernet 0/19 - shutdown -! -interface Ethernet 0/20 - shutdown -! -interface Ethernet 0/21 - shutdown -! -interface Ethernet 0/22 - shutdown -! -interface Ethernet 0/23 - shutdown -! -interface Ethernet 0/24 - shutdown -! -interface Ethernet 0/25 - shutdown -! -interface Ethernet 0/26 - shutdown -! -interface Ethernet 0/27 - shutdown -! -interface Ethernet 0/28 - shutdown -! -interface Ethernet 0/29 - shutdown -! -interface Ethernet 0/30 - shutdown -! -interface Ethernet 0/31 - shutdown -! -interface Ethernet 0/32 - shutdown -! -interface Ethernet 0/33 - shutdown -! -interface Ethernet 0/34 - shutdown -! -interface Ethernet 0/35 - shutdown -! -interface Ethernet 0/36 - shutdown -! -interface Ethernet 0/37 - shutdown -! -interface Ethernet 0/38 - shutdown -! -interface Ethernet 0/39 - shutdown -! -interface Ethernet 0/40 - shutdown -! -interface Ethernet 0/41 - shutdown -! -interface Ethernet 0/42 - shutdown -! -interface Ethernet 0/43 - shutdown -! -interface Ethernet 0/44 - shutdown -! -interface Ethernet 0/45 - shutdown -! -interface Ethernet 0/46 - shutdown -! -interface Ethernet 0/47 - shutdown -! -interface Ethernet 0/48 - shutdown -! -interface Ethernet 0/49 - shutdown -! -interface Ethernet 0/50 - fec mode RS-FEC - no shutdown -! -interface Ethernet 0/51 - fec mode RS-FEC - no shutdown -! -interface Ethernet 0/52 - fec mode RS-FEC - no shutdown -! -interface Ethernet 0/53 - fec mode RS-FEC - no shutdown -! -interface Ethernet 0/54 - fec mode disabled - no shutdown -! -interface Port-channel 200 - switchport - switchport mode access - switchport access vlan 200 - shutdown -! -interface Port-channel 1024 - insight enable - no shutdown -! -monitor session 1 - source ethernet 0/1 destination port-channel 1024 direction both -! -monitor session 2 -! -bridge-domain 100 p2mp -! -cluster MCT1 1 -! diff --git a/test/units/plugins/cliconf/fixtures/slxos/show_startup-config b/test/units/plugins/cliconf/fixtures/slxos/show_startup-config deleted file mode 100644 index b2e540d97e9..00000000000 --- a/test/units/plugins/cliconf/fixtures/slxos/show_startup-config +++ /dev/null @@ -1,624 +0,0 @@ -root enable -host-table aging-mode conversational -clock timezone Europe/Warsaw -hardware - profile tcam default - profile overlay-visibility default - profile route-table default maximum_paths 8 - system-mode default -! -http server use-vrf default-vrf -http server use-vrf mgmt-vrf -node-id 1 -! -ntp server 172.16.10.2 use-vrf mgmt-vrf -! -logging raslog console INFO -logging syslog-server 10.1.5.11 use-vrf mgmt-vrf -! -logging auditlog class SECURITY -logging auditlog class CONFIGURATION -logging auditlog class FIRMWARE -logging syslog-facility local LOG_LOCAL0 -logging syslog-client localip CHASSIS_IP -switch-attributes chassis-name SLX9140-LEAF2 -switch-attributes host-name DC2LEAF2 -no support autoupload enable -support ffdc -resource-monitor cpu enable threshold 90 action raslog -resource-monitor memory enable threshold 100 action raslog -resource-monitor process memory enable alarm 1000 critical 1200 -system-monitor fan threshold marginal-threshold 1 down-threshold 2 -system-monitor fan alert state removed action raslog -system-monitor power threshold marginal-threshold 1 down-threshold 2 -system-monitor power alert state removed action raslog -system-monitor temp threshold marginal-threshold 1 down-threshold 2 -system-monitor cid-card threshold marginal-threshold 1 down-threshold 2 -system-monitor cid-card alert state none action none -system-monitor compact-flash threshold marginal-threshold 1 down-threshold 0 -system-monitor MM threshold marginal-threshold 1 down-threshold 0 -system-monitor LineCard threshold marginal-threshold 1 down-threshold 2 -system-monitor LineCard alert state none action none -system-monitor SFM threshold marginal-threshold 1 down-threshold 2 -telemetry server use-vrf mgmt-vrf - transport tcp - port 50051 - activate -! -telemetry profile system-utilization default_system_utilization_statistics - interval 60 - add total-system-memory - add total-used-memory - add total-free-memory - add cached-memory - add buffers - add user-free-memory - add kernel-free-memory - add total-swap-memory - add total-free-swap-memory - add total-used-swap-memory - add user-process - add system-process - add niced-process - add iowait - add hw-interrupt - add sw-interrupt - add idle-state - add steal-time - add uptime -! -telemetry profile interface default_interface_statistics - interval 30 - add out-pkts - add in-pkts - add out-unicast-pkts - add in-unicast-pkts - add out-broadcast-pkts - add in-broadcast-pkts - add out-multicast-pkts - add in-multicast-pkts - add out-pkts-per-second - add in-pkts-per-second - add out-bandwidth - add in-bandwidth - add out-octets - add in-octets - add out-errors - add in-errors - add out-crc-errors - add in-crc-errors - add out-discards - add in-discards -! -line vty - exec-timeout 10 -! -threshold-monitor Buffer limit 70 -vrf mgmt-vrf - address-family ipv4 unicast - ip route 0.0.0.0/0 172.168.192.1 - ! - address-family ipv6 unicast - ! -! -ssh server key rsa 2048 -ssh server key ecdsa 256 -ssh server key dsa -ssh server use-vrf default-vrf -ssh server use-vrf mgmt-vrf -telnet server use-vrf default-vrf -telnet server use-vrf mgmt-vrf -role name admin desc Administrator -role name user desc User -aaa authentication login local -aaa accounting exec default start-stop none -aaa accounting commands default start-stop none -service password-encryption -username admin password "AINTNOPARTYLIKEAHOTELPARTYCAUSEAHOTELPARTYDONTSLEEPNOONEWOULDEVERACTUALLYTYPETHISWHYAREYOUHERE\n" encryption-level 7 role admin desc Administrator -cee-map default - precedence 1 - priority-group-table 1 weight 40 pfc on - priority-group-table 15.0 pfc off - priority-group-table 15.1 pfc off - priority-group-table 15.2 pfc off - priority-group-table 15.3 pfc off - priority-group-table 15.4 pfc off - priority-group-table 15.5 pfc off - priority-group-table 15.6 pfc off - priority-group-table 15.7 pfc off - priority-group-table 2 weight 60 pfc off - priority-table 2 2 2 1 2 2 2 15.0 - remap lossless-priority priority 0 -! -mac access-list extended M1 - seq 10 permit any any -! -vlan 1 - ip igmp snooping startup-query-interval 100 - ipv6 mld snooping startup-query-interval 100 -! -vlan 100 -! -vlan 200 -! -vlan 1001 - router-interface Ve 1001 - description Thomas-Test-Cluster -! -qos map cos-mutation all-zero-map - map cos 0 to cos 0 - map cos 1 to cos 0 - map cos 2 to cos 0 - map cos 3 to cos 0 - map cos 4 to cos 0 - map cos 5 to cos 0 - map cos 6 to cos 0 - map cos 7 to cos 0 -! -qos map cos-mutation default - map cos 0 to cos 0 - map cos 1 to cos 1 - map cos 2 to cos 2 - map cos 3 to cos 3 - map cos 4 to cos 4 - map cos 5 to cos 5 - map cos 6 to cos 6 - map cos 7 to cos 7 -! -qos map cos-traffic-class all-zero-map - map cos 0 to traffic-class 0 - map cos 1 to traffic-class 0 - map cos 2 to traffic-class 0 - map cos 3 to traffic-class 0 - map cos 4 to traffic-class 0 - map cos 5 to traffic-class 0 - map cos 6 to traffic-class 0 - map cos 7 to traffic-class 0 -! -qos map cos-traffic-class default - map cos 0 to traffic-class 1 - map cos 1 to traffic-class 0 - map cos 2 to traffic-class 2 - map cos 3 to traffic-class 3 - map cos 4 to traffic-class 4 - map cos 5 to traffic-class 5 - map cos 6 to traffic-class 6 - map cos 7 to traffic-class 7 -! -qos map cos-dscp all-zero-map - map cos 0 to dscp 0 - map cos 1 to dscp 0 - map cos 2 to dscp 0 - map cos 3 to dscp 0 - map cos 4 to dscp 0 - map cos 5 to dscp 0 - map cos 6 to dscp 0 - map cos 7 to dscp 0 -! -qos map cos-dscp default - map cos 0 to dscp 0 - map cos 1 to dscp 8 - map cos 2 to dscp 16 - map cos 3 to dscp 24 - map cos 4 to dscp 32 - map cos 5 to dscp 40 - map cos 6 to dscp 48 - map cos 7 to dscp 56 -! -qos map traffic-class-cos all-zero-map - map traffic-class 0 to cos 0 - map traffic-class 1 to cos 0 - map traffic-class 2 to cos 0 - map traffic-class 3 to cos 0 - map traffic-class 4 to cos 0 - map traffic-class 5 to cos 0 - map traffic-class 6 to cos 0 - map traffic-class 7 to cos 0 -! -qos map traffic-class-cos default - map traffic-class 0 to cos 0 - map traffic-class 1 to cos 1 - map traffic-class 2 to cos 2 - map traffic-class 3 to cos 3 - map traffic-class 4 to cos 4 - map traffic-class 5 to cos 5 - map traffic-class 6 to cos 6 - map traffic-class 7 to cos 7 -! -qos map traffic-class-mutation all-zero-map - map traffic-class 0 to traffic-class 0 - map traffic-class 1 to traffic-class 0 - map traffic-class 2 to traffic-class 0 - map traffic-class 3 to traffic-class 0 - map traffic-class 4 to traffic-class 0 - map traffic-class 5 to traffic-class 0 - map traffic-class 6 to traffic-class 0 - map traffic-class 7 to traffic-class 0 -! -qos map traffic-class-mutation default - map traffic-class 0 to traffic-class 0 - map traffic-class 1 to traffic-class 1 - map traffic-class 2 to traffic-class 2 - map traffic-class 3 to traffic-class 3 - map traffic-class 4 to traffic-class 4 - map traffic-class 5 to traffic-class 5 - map traffic-class 6 to traffic-class 6 - map traffic-class 7 to traffic-class 7 -! -qos map traffic-class-dscp all-zero-map - map traffic-class 0 to dscp 0 - map traffic-class 1 to dscp 0 - map traffic-class 2 to dscp 0 - map traffic-class 3 to dscp 0 - map traffic-class 4 to dscp 0 - map traffic-class 5 to dscp 0 - map traffic-class 6 to dscp 0 - map traffic-class 7 to dscp 0 -! -qos map traffic-class-dscp default - map traffic-class 0 to dscp 0 - map traffic-class 1 to dscp 8 - map traffic-class 2 to dscp 16 - map traffic-class 3 to dscp 24 - map traffic-class 4 to dscp 32 - map traffic-class 5 to dscp 40 - map traffic-class 6 to dscp 48 - map traffic-class 7 to dscp 56 -! -qos map dscp-mutation all-zero-map - map dscp 0-63 to dscp 0 -! -qos map dscp-mutation default - map dscp 0 to dscp 0 - map dscp 1 to dscp 1 - map dscp 10 to dscp 10 - map dscp 11 to dscp 11 - map dscp 12 to dscp 12 - map dscp 13 to dscp 13 - map dscp 14 to dscp 14 - map dscp 15 to dscp 15 - map dscp 16 to dscp 16 - map dscp 17 to dscp 17 - map dscp 18 to dscp 18 - map dscp 19 to dscp 19 - map dscp 2 to dscp 2 - map dscp 20 to dscp 20 - map dscp 21 to dscp 21 - map dscp 22 to dscp 22 - map dscp 23 to dscp 23 - map dscp 24 to dscp 24 - map dscp 25 to dscp 25 - map dscp 26 to dscp 26 - map dscp 27 to dscp 27 - map dscp 28 to dscp 28 - map dscp 29 to dscp 29 - map dscp 3 to dscp 3 - map dscp 30 to dscp 30 - map dscp 31 to dscp 31 - map dscp 32 to dscp 32 - map dscp 33 to dscp 33 - map dscp 34 to dscp 34 - map dscp 35 to dscp 35 - map dscp 36 to dscp 36 - map dscp 37 to dscp 37 - map dscp 38 to dscp 38 - map dscp 39 to dscp 39 - map dscp 4 to dscp 4 - map dscp 40 to dscp 40 - map dscp 41 to dscp 41 - map dscp 42 to dscp 42 - map dscp 43 to dscp 43 - map dscp 44 to dscp 44 - map dscp 45 to dscp 45 - map dscp 46 to dscp 46 - map dscp 47 to dscp 47 - map dscp 48 to dscp 48 - map dscp 49 to dscp 49 - map dscp 5 to dscp 5 - map dscp 50 to dscp 50 - map dscp 51 to dscp 51 - map dscp 52 to dscp 52 - map dscp 53 to dscp 53 - map dscp 54 to dscp 54 - map dscp 55 to dscp 55 - map dscp 56 to dscp 56 - map dscp 57 to dscp 57 - map dscp 58 to dscp 58 - map dscp 59 to dscp 59 - map dscp 6 to dscp 6 - map dscp 60 to dscp 60 - map dscp 61 to dscp 61 - map dscp 62 to dscp 62 - map dscp 63 to dscp 63 - map dscp 7 to dscp 7 - map dscp 8 to dscp 8 - map dscp 9 to dscp 9 -! -qos map dscp-traffic-class all-zero-map - map dscp 0-63 to traffic-class 0 -! -qos map dscp-traffic-class default - map dscp 0-7 to traffic-class 0 - map dscp 16-23 to traffic-class 2 - map dscp 24-31 to traffic-class 3 - map dscp 32-39 to traffic-class 4 - map dscp 40-47 to traffic-class 5 - map dscp 48-55 to traffic-class 6 - map dscp 56-63 to traffic-class 7 - map dscp 8-15 to traffic-class 1 -! -qos map dscp-cos all-zero-map - map dscp 0-63 to cos 0 -! -qos map dscp-cos default - map dscp 0-7 to cos 0 - map dscp 16-23 to cos 2 - map dscp 24-31 to cos 3 - map dscp 32-39 to cos 4 - map dscp 40-47 to cos 5 - map dscp 48-55 to cos 6 - map dscp 56-63 to cos 7 - map dscp 8-15 to cos 1 -! -protocol lldp - advertise optional-tlv management-address - system-description Brocade BR-SLX9140 Router -! -vlan dot1q tag native -police-remark-profile default -! -class-map BD-100 -! -class-map C1 - match access-group M1 -! -class-map cee -! -class-map default -! -policy-map P1 - class C1 - police cir 1000000 - ! -! -policy-map P2 - class default - police cir 12121212 - ! -! -no protocol vrrp -no protocol vrrp-extended -router bgp - local-as 65301 - capability as4-enable - bfd interval 300 min-rx 300 multiplier 3 - neighbor leaf_group peer-group - neighbor leaf_group remote-as 65500 - neighbor leaf_group bfd - neighbor 10.220.4.3 remote-as 65500 - neighbor 10.220.4.3 peer-group leaf_group - address-family ipv4 unicast - network 172.32.252.5/32 - maximum-paths 8 - ! - address-family ipv6 unicast - ! - address-family l2vpn evpn - ! -! -interface Loopback 1 - ip address 172.16.128.6/32 - no shutdown -! -interface Loopback 2 - ip address 172.16.129.5/32 - no shutdown -! -interface Management 0 - no tcp burstrate - no shutdown - vrf forwarding mgmt-vrf - ip address dhcp -! -interface Ethernet 0/1 - speed 25000 - fec mode disabled - switchport - switchport mode access - switchport access vlan 1 - no shutdown -! -interface Ethernet 0/2 - no shutdown -! -interface Ethernet 0/3 - speed 25000 - fec mode RS-FEC - no shutdown -! -interface Ethernet 0/4 - shutdown -! -interface Ethernet 0/5 - service-policy in P1 - no shutdown -! -interface Ethernet 0/6 - mtu 1548 - description L2 Interface - no shutdown -! -interface Ethernet 0/7 - mtu 1548 - description L2 Interface - no shutdown -! -interface Ethernet 0/8 - switchport - switchport mode trunk - switchport trunk allowed vlan add 100,200 - switchport trunk tag native-vlan - shutdown -! -interface Ethernet 0/9 - shutdown -! -interface Ethernet 0/10 - no shutdown -! -interface Ethernet 0/11 - no shutdown -! -interface Ethernet 0/12 - no shutdown -! -interface Ethernet 0/13 - no shutdown -! -interface Ethernet 0/14 - no shutdown -! -interface Ethernet 0/15 - shutdown -! -interface Ethernet 0/16 - shutdown -! -interface Ethernet 0/17 - shutdown -! -interface Ethernet 0/18 - shutdown -! -interface Ethernet 0/19 - shutdown -! -interface Ethernet 0/20 - shutdown -! -interface Ethernet 0/21 - shutdown -! -interface Ethernet 0/22 - shutdown -! -interface Ethernet 0/23 - shutdown -! -interface Ethernet 0/24 - shutdown -! -interface Ethernet 0/25 - shutdown -! -interface Ethernet 0/26 - shutdown -! -interface Ethernet 0/27 - shutdown -! -interface Ethernet 0/28 - shutdown -! -interface Ethernet 0/29 - shutdown -! -interface Ethernet 0/30 - shutdown -! -interface Ethernet 0/31 - shutdown -! -interface Ethernet 0/32 - shutdown -! -interface Ethernet 0/33 - shutdown -! -interface Ethernet 0/34 - shutdown -! -interface Ethernet 0/35 - shutdown -! -interface Ethernet 0/36 - shutdown -! -interface Ethernet 0/37 - shutdown -! -interface Ethernet 0/38 - shutdown -! -interface Ethernet 0/39 - shutdown -! -interface Ethernet 0/40 - shutdown -! -interface Ethernet 0/41 - shutdown -! -interface Ethernet 0/42 - shutdown -! -interface Ethernet 0/43 - shutdown -! -interface Ethernet 0/44 - shutdown -! -interface Ethernet 0/45 - shutdown -! -interface Ethernet 0/46 - shutdown -! -interface Ethernet 0/47 - shutdown -! -interface Ethernet 0/48 - shutdown -! -interface Ethernet 0/49 - shutdown -! -interface Ethernet 0/50 - fec mode RS-FEC - no shutdown -! -interface Ethernet 0/51 - fec mode RS-FEC - no shutdown -! -interface Ethernet 0/52 - fec mode RS-FEC - no shutdown -! -interface Ethernet 0/53 - fec mode RS-FEC - no shutdown -! -interface Ethernet 0/54 - fec mode disabled - no shutdown -! -interface Port-channel 200 - switchport - switchport mode access - switchport access vlan 200 - shutdown -! -interface Port-channel 1024 - insight enable - no shutdown -! -monitor session 1 - source ethernet 0/1 destination port-channel 1024 direction both -! -monitor session 2 -! -bridge-domain 100 p2mp -! -cluster MCT1 1 -! diff --git a/test/units/plugins/cliconf/fixtures/slxos/show_version b/test/units/plugins/cliconf/fixtures/slxos/show_version deleted file mode 100644 index 0d648378ac6..00000000000 --- a/test/units/plugins/cliconf/fixtures/slxos/show_version +++ /dev/null @@ -1,18 +0,0 @@ -SLX-OS Operating System Software -SLX-OS Operating System Version: 17s.1.02 -Copyright (c) 1995-2018 Brocade Communications Systems, Inc. -Firmware name: 17s.1.02 -Build Time: 00:06:59 Sep 28, 2017 -Install Time: 15:58:29 Feb 9, 2018 -Kernel: 2.6.34.6 -Host Version: Ubuntu 14.04 LTS -Host Kernel: Linux 3.14.17 - -Control Processor: QEMU Virtual CPU version 2.0.0 - -System Uptime: 34days 4hrs 41mins 53secs - -Slot Name Primary/Secondary Versions Status ---------------------------------------------------------------------------- -SW/0 SLX-OS 17s.1.02 ACTIVE* - 17s.1.02 diff --git a/test/units/plugins/cliconf/test_ios.py b/test/units/plugins/cliconf/test_ios.py deleted file mode 100644 index 44650b84b89..00000000000 --- a/test/units/plugins/cliconf/test_ios.py +++ /dev/null @@ -1,133 +0,0 @@ -# -# (c) 2019 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 . -# -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from os import path -import json - -from mock import MagicMock - -from units.compat import unittest -from ansible.plugins.cliconf import ios -from ansible.module_utils._text import to_bytes - - -b_FIXTURE_DIR = b'%s/fixtures/ios' % ( - to_bytes(path.dirname(path.abspath(__file__)), errors='surrogate_or_strict') -) - - -def _connection_side_effect(*args, **kwargs): - try: - if args: - value = args[0] - else: - value = kwargs.get('command') - - fixture_path = path.abspath( - b'%s/%s' % (b_FIXTURE_DIR, b'_'.join(value.split(b' '))) - ) - with open(fixture_path, 'rb') as file_desc: - return file_desc.read() - except (OSError, IOError): - if args: - value = args[0] - return value - elif kwargs.get('command'): - value = kwargs.get('command') - return value - - return 'Nope' - - -class TestPluginCLIConfIOS(unittest.TestCase): - """ Test class for IOS CLI Conf Methods - """ - def setUp(self): - self._mock_connection = MagicMock() - self._mock_connection.send.side_effect = _connection_side_effect - self._cliconf = ios.Cliconf(self._mock_connection) - self.maxDiff = None - - def tearDown(self): - pass - - def test_get_device_info(self): - """ Test get_device_info - """ - device_info = self._cliconf.get_device_info() - - mock_device_info = {'network_os': 'ios', - 'network_os_model': 'CSR1000V', - 'network_os_version': '16.06.01', - 'network_os_hostname': 'an-csr-01', - 'network_os_image': 'bootflash:packages.conf' - } - - self.assertEqual(device_info, mock_device_info) - - def test_get_capabilities(self): - """ Test get_capabilities - """ - capabilities = json.loads(self._cliconf.get_capabilities()) - mock_capabilities = { - 'network_api': 'cliconf', - 'rpc': [ - 'get_config', - 'edit_config', - 'get_capabilities', - 'get', - 'enable_response_logging', - 'disable_response_logging', - 'edit_banner', - 'get_diff', - 'run_commands', - 'get_defaults_flag' - ], - 'device_operations': { - 'supports_diff_replace': True, - 'supports_commit': False, - 'supports_rollback': False, - 'supports_defaults': True, - 'supports_onbox_diff': False, - 'supports_commit_comment': False, - 'supports_multiline_delimiter': True, - 'supports_diff_match': True, - 'supports_diff_ignore_lines': True, - 'supports_generate_diff': True, - 'supports_replace': False - }, - 'device_info': { - 'network_os_hostname': 'an-csr-01', - 'network_os_image': 'bootflash:packages.conf', - 'network_os_model': 'CSR1000V', - 'network_os_version': '16.06.01', - 'network_os': 'ios' - }, - 'format': ['text'], - 'diff_match': ['line', 'strict', 'exact', 'none'], - 'diff_replace': ['line', 'block'], - 'output': [] - } - - self.assertEqual( - mock_capabilities, - capabilities - )