From 411fb2ed1fd63489ad36f8400794df8c5b957844 Mon Sep 17 00:00:00 2001 From: rohitthakur2590 Date: Thu, 20 Mar 2025 11:16:14 +0530 Subject: [PATCH] update setup Signed-off-by: rohitthakur2590 --- ansible_collections/ansible.cfg | 11 + ansible_collections/device_facts.yml | 11 + ansible_collections/inventory | 9 + .../juniper/device/meta/runtime.yml | 9 +- .../juniper/device/plugins/action/junos.py | 172 + .../plugins/module_utils/netconf/__init__.py | 0 .../plugins/module_utils/netconf/junos.py | 283 + .../plugins/module_utils/network/__init__.py | 0 .../module_utils/network/junos/__init__.py | 0 .../network/junos/argspec/__init__.py | 0 .../junos/argspec/acl_interfaces/__init__.py | 0 .../argspec/acl_interfaces/acl_interfaces.py | 80 + .../network/junos/argspec/acls/__init__.py | 0 .../network/junos/argspec/acls/acls.py | 211 + .../argspec/bgp_address_family/__init__.py | 0 .../bgp_address_family/bgp_address_family.py | 894 ++ .../junos/argspec/bgp_global/__init__.py | 0 .../junos/argspec/bgp_global/bgp_global.py | 1272 ++ .../network/junos/argspec/facts/__init__.py | 0 .../network/junos/argspec/facts/facts.py | 29 + .../junos/argspec/hostname/__init__.py | 0 .../junos/argspec/hostname/hostname.py | 56 + .../junos/argspec/interfaces/__init__.py | 0 .../junos/argspec/interfaces/interfaces.py | 86 + .../junos/argspec/l2_interfaces/__init__.py | 0 .../argspec/l2_interfaces/l2_interfaces.py | 75 + .../junos/argspec/l3_interfaces/__init__.py | 0 .../argspec/l3_interfaces/l3_interfaces.py | 55 + .../network/junos/argspec/lacp/__init__.py | 0 .../network/junos/argspec/lacp/lacp.py | 64 + .../junos/argspec/lacp_interfaces/__init__.py | 0 .../lacp_interfaces/lacp_interfaces.py | 79 + .../junos/argspec/lag_interfaces/__init__.py | 0 .../argspec/lag_interfaces/lag_interfaces.py | 77 + .../junos/argspec/lldp_global/__init__.py | 0 .../junos/argspec/lldp_global/lldp_global.py | 64 + .../junos/argspec/lldp_interfaces/__init__.py | 0 .../lldp_interfaces/lldp_interfaces.py | 63 + .../junos/argspec/logging_global/__init__.py | 0 .../argspec/logging_global/logging_global.py | 1380 ++ .../junos/argspec/ntp_global/__init__.py | 0 .../junos/argspec/ntp_global/ntp_global.py | 133 + .../junos/argspec/ospf_interfaces/__init__.py | 0 .../ospf_interfaces/ospf_interfaces.py | 142 + .../network/junos/argspec/ospfv2/__init__.py | 0 .../network/junos/argspec/ospfv2/ospfv2.py | 159 + .../network/junos/argspec/ospfv3/__init__.py | 0 .../network/junos/argspec/ospfv3/ospfv3.py | 125 + .../junos/argspec/prefix_lists/__init__.py | 0 .../argspec/prefix_lists/prefix_lists.py | 63 + .../argspec/routing_instances/__init__.py | 0 .../routing_instances/routing_instances.py | 124 + .../junos/argspec/routing_options/__init__.py | 0 .../routing_options/routing_options.py | 69 + .../argspec/security_policies/__init__.py | 0 .../security_policies/security_policies.py | 822 ++ .../security_policies_global/__init__.py | 0 .../security_policies_global.py | 129 + .../junos/argspec/security_zones/__init__.py | 0 .../argspec/security_zones/security_zones.py | 192 + .../junos/argspec/snmp_server/__init__.py | 0 .../junos/argspec/snmp_server/snmp_server.py | 700 + .../junos/argspec/static_routes/__init__.py | 0 .../argspec/static_routes/static_routes.py | 90 + .../network/junos/argspec/vlans/__init__.py | 0 .../network/junos/argspec/vlans/vlans.py | 65 + .../network/junos/facts/__init__.py | 0 .../junos/facts/acl_interfaces/__init__.py | 0 .../facts/acl_interfaces/acl_interfaces.py | 164 + .../network/junos/facts/acls/__init__.py | 0 .../network/junos/facts/acls/acls.py | 245 + .../facts/bgp_address_family/__init__.py | 0 .../bgp_address_family/bgp_address_family.py | 741 + .../junos/facts/bgp_global/__init__.py | 0 .../junos/facts/bgp_global/bgp_global.py | 1089 ++ .../module_utils/network/junos/facts/facts.py | 203 + .../network/junos/facts/hostname/__init__.py | 0 .../network/junos/facts/hostname/hostname.py | 137 + .../junos/facts/interfaces/__init__.py | 0 .../junos/facts/interfaces/interfaces.py | 179 + .../junos/facts/l2_interfaces/__init__.py | 0 .../facts/l2_interfaces/l2_interfaces.py | 157 + .../junos/facts/l3_interfaces/__init__.py | 0 .../facts/l3_interfaces/l3_interfaces.py | 189 + .../network/junos/facts/lacp/__init__.py | 0 .../network/junos/facts/lacp/lacp.py | 118 + .../junos/facts/lacp_interfaces/__init__.py | 0 .../facts/lacp_interfaces/lacp_interfaces.py | 146 + .../junos/facts/lag_interfaces/__init__.py | 0 .../facts/lag_interfaces/lag_interfaces.py | 193 + .../network/junos/facts/legacy/__init__.py | 0 .../network/junos/facts/legacy/base.py | 230 + .../junos/facts/lldp_global/__init__.py | 0 .../junos/facts/lldp_global/lldp_global.py | 115 + .../junos/facts/lldp_interfaces/__init__.py | 0 .../facts/lldp_interfaces/lldp_interfaces.py | 115 + .../junos/facts/logging_global/__init__.py | 0 .../facts/logging_global/logging_global.py | 428 + .../junos/facts/ntp_global/__init__.py | 0 .../junos/facts/ntp_global/ntp_global.py | 319 + .../junos/facts/ospf_interfaces/__init__.py | 0 .../facts/ospf_interfaces/ospf_interfaces.py | 269 + .../network/junos/facts/ospfv2/__init__.py | 0 .../network/junos/facts/ospfv2/ospfv2.py | 322 + .../network/junos/facts/ospfv3/__init__.py | 0 .../network/junos/facts/ospfv3/ospfv3.py | 284 + .../junos/facts/prefix_lists/__init__.py | 0 .../junos/facts/prefix_lists/prefix_lists.py | 167 + .../junos/facts/routing_instances/__init__.py | 0 .../routing_instances/routing_instances.py | 266 + .../junos/facts/routing_options/__init__.py | 0 .../facts/routing_options/routing_options.py | 149 + .../junos/facts/security_policies/__init__.py | 0 .../security_policies/security_policies.py | 527 + .../security_policies_global/__init__.py | 0 .../security_policies_global.py | 244 + .../junos/facts/security_zones/__init__.py | 0 .../facts/security_zones/security_zones.py | 336 + .../junos/facts/snmp_server/__init__.py | 0 .../junos/facts/snmp_server/snmp_server.py | 850 ++ .../junos/facts/static_routes/__init__.py | 0 .../facts/static_routes/static_routes.py | 179 + .../network/junos/facts/vlans/__init__.py | 0 .../network/junos/facts/vlans/vlans.py | 123 + .../module_utils/network/junos/junos.py | 536 + .../network/junos/utils/__init__.py | 0 .../module_utils/network/junos/utils/utils.py | 51 + .../plugins/modules/junos_acl_interfaces.py | 364 + .../device/plugins/modules/junos_acls.py | 363 + .../device/plugins/modules/junos_banner.py | 194 + .../modules/junos_bgp_address_family.py | 2009 +++ .../plugins/modules/junos_bgp_global.py | 1867 +++ .../device/plugins/modules/junos_command.py | 480 + .../device/plugins/modules/junos_config.py | 537 + .../device/plugins/modules/junos_facts.py | 146 + .../device/plugins/modules/junos_hostname.py | 361 + .../plugins/modules/junos_interfaces.py | 966 ++ .../plugins/modules/junos_l2_interfaces.py | 1062 ++ .../plugins/modules/junos_l3_interfaces.py | 1026 ++ .../device/plugins/modules/junos_lacp.py | 304 + .../plugins/modules/junos_lacp_interfaces.py | 966 ++ .../plugins/modules/junos_lag_interfaces.py | 893 ++ .../plugins/modules/junos_lldp_global.py | 331 + .../plugins/modules/junos_lldp_interfaces.py | 359 + .../plugins/modules/junos_logging_global.py | 1743 +++ .../device/plugins/modules/junos_netconf.py | 193 + .../plugins/modules/junos_ntp_global.py | 1019 ++ .../plugins/modules/junos_ospf_interfaces.py | 612 + .../device/plugins/modules/junos_ospfv2.py | 1173 ++ .../device/plugins/modules/junos_ospfv3.py | 753 + .../device/plugins/modules/junos_package.py | 291 + .../device/plugins/modules/junos_ping.py | 290 + .../plugins/modules/junos_prefix_lists.py | 658 + .../modules/junos_routing_instances.py | 801 ++ .../plugins/modules/junos_routing_options.py | 402 + .../device/plugins/modules/junos_rpc.py | 177 + .../device/plugins/modules/junos_scp.py | 239 + .../modules/junos_security_policies.py | 2705 ++++ .../modules/junos_security_policies_global.py | 994 ++ .../plugins/modules/junos_security_zones.py | 2002 +++ .../plugins/modules/junos_snmp_server.py | 1584 +++ .../plugins/modules/junos_static_routes.py | 513 + .../device/plugins/modules/junos_system.py | 207 + .../device/plugins/modules/junos_user.py | 457 + .../device/plugins/modules/junos_vlans.py | 467 + .../device/plugins/modules/junos_vrf.py | 342 + .../junipernetworks/junos/.ansible-lint | 5 + .../junipernetworks/junos/.flake8 | 67 + .../junos/.github/dependabot.yml | 9 + .../junos/.github/release-drafter.yml | 3 + .../junos/.github/workflows/check_label.yml | 11 + .../junos/.github/workflows/codecoverage.yml | 15 + .../junos/.github/workflows/draft_release.yml | 18 + .../junos/.github/workflows/release.yml | 14 + .../junos/.github/workflows/tests.yml | 52 + .../junipernetworks/junos/.gitignore | 2 + .../junipernetworks/junos/.isort.cfg | 6 + .../junos/.pre-commit-config.yaml | 56 + .../junipernetworks/junos/.prettierignore | 23 + .../junipernetworks/junos/.yamllint | 15 + .../junipernetworks/junos/CHANGELOG.rst | 618 + .../junipernetworks/junos/LICENSE | 674 + .../junipernetworks/junos/README.md | 187 + .../junipernetworks/junos/bindep.txt | 7 + .../junos/changelogs/.plugin-cache.yaml | 226 + .../junos/changelogs/changelog.yaml | 687 + .../junos/changelogs/config.yaml | 32 + .../junos/changelogs/fragments/.keep | 0 .../junos/changelogs/fragments/0-readme.yml | 3 + .../changelogs/fragments/adds_support.yaml | 3 + .../changelogs/fragments/ignore_219.yaml | 3 + .../junos/changelogs/fragments/libssh.yaml | 3 + .../junipernetworks/junos/codecov.yml | 15 + ...orks.junos.junos_acl_interfaces_module.rst | 508 + ...unipernetworks.junos.junos_acls_module.rst | 1277 ++ ...ipernetworks.junos.junos_banner_module.rst | 212 + ....junos.junos_bgp_address_family_module.rst | 7712 +++++++++++ ...networks.junos.junos_bgp_global_module.rst | 11520 ++++++++++++++++ .../junipernetworks.junos.junos_cliconf.rst | 80 + ...pernetworks.junos.junos_command_module.rst | 319 + ...ipernetworks.junos.junos_config_module.rst | 533 + ...nipernetworks.junos.junos_facts_module.rst | 162 + ...ernetworks.junos.junos_hostname_module.rst | 419 + ...networks.junos.junos_interfaces_module.rst | 1175 ++ ...works.junos.junos_l2_interfaces_module.rst | 1213 ++ ...works.junos.junos_l3_interfaces_module.rst | 1175 ++ ...rks.junos.junos_lacp_interfaces_module.rst | 1100 ++ ...unipernetworks.junos.junos_lacp_module.rst | 375 + ...orks.junos.junos_lag_interfaces_module.rst | 987 ++ ...etworks.junos.junos_lldp_global_module.rst | 444 + ...rks.junos.junos_lldp_interfaces_module.rst | 427 + ...orks.junos.junos_logging_global_module.rst | 5615 ++++++++ .../junipernetworks.junos.junos_netconf.rst | 76 + ...pernetworks.junos.junos_netconf_module.rst | 146 + ...networks.junos.junos_ntp_global_module.rst | 1551 +++ ...rks.junos.junos_ospf_interfaces_module.rst | 1223 ++ ...ipernetworks.junos.junos_ospfv2_module.rst | 1995 +++ ...ipernetworks.junos.junos_ospfv3_module.rst | 1346 ++ ...pernetworks.junos.junos_package_module.rst | 424 + ...unipernetworks.junos.junos_ping_module.rst | 366 + ...tworks.junos.junos_prefix_lists_module.rst | 654 + ...s.junos.junos_routing_instances_module.rst | 1318 ++ ...rks.junos.junos_routing_options_module.rst | 537 + ...junipernetworks.junos.junos_rpc_module.rst | 219 + ...junipernetworks.junos.junos_scp_module.rst | 376 + ....junos_security_policies_global_module.rst | 1446 ++ ...s.junos.junos_security_policies_module.rst | 7392 ++++++++++ ...orks.junos.junos_security_zones_module.rst | 2842 ++++ ...etworks.junos.junos_snmp_server_module.rst | 6131 ++++++++ ...works.junos.junos_static_routes_module.rst | 714 + ...ipernetworks.junos.junos_system_module.rst | 228 + ...unipernetworks.junos.junos_user_module.rst | 447 + ...nipernetworks.junos.junos_vlans_module.rst | 570 + ...junipernetworks.junos.junos_vrf_module.rst | 465 + .../junipernetworks/junos/galaxy.yml | 14 + .../junipernetworks/junos/meta/runtime.yml | 92 + .../junos/meta/runtime.yml_bkp | 89 + .../junipernetworks/junos/pyproject.toml | 7 + .../junipernetworks/junos/requirements.txt | 6 + .../junos/test-requirements.txt | 7 + .../junipernetworks/junos/tests/.gitignore | 1 + .../junipernetworks/junos/tests/config.yml | 3 + .../tests/integration/target-prefixes.network | 1 + .../junos_acl_interfaces/defaults/main.yaml | 3 + .../junos_acl_interfaces/meta/main.yaml | 3 + .../junos_acl_interfaces/tasks/main.yaml | 5 + .../junos_acl_interfaces/tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 20 + .../tests/netconf/_reset_config.yaml | 18 + .../tests/netconf/deleted.yaml | 64 + .../tests/netconf/empty_config.yaml | 55 + .../tests/netconf/gathered.yaml | 50 + .../tests/netconf/merged.yaml | 58 + .../tests/netconf/overridden.yaml | 51 + .../tests/netconf/replaced.yaml | 51 + .../targets/junos_acls/defaults/main.yaml | 3 + .../targets/junos_acls/meta/main.yaml | 3 + .../targets/junos_acls/tasks/main.yaml | 4 + .../targets/junos_acls/tasks/netconf.yaml | 20 + .../tests/netconf/_reset_config.yaml | 19 + .../tests/netconf/config_policy.yaml | 14 + .../junos_acls/tests/netconf/deleted.yaml | 166 + .../tests/netconf/empty_config.yaml | 66 + .../tests/netconf/fixtures/parsed.cfg | 45 + .../junos_acls/tests/netconf/gathered.yaml | 100 + .../junos_acls/tests/netconf/idempotent.yaml | 79 + .../junos_acls/tests/netconf/merged.yaml | 106 + .../junos_acls/tests/netconf/overridden.yaml | 49 + .../junos_acls/tests/netconf/parsed.yaml | 44 + .../junos_acls/tests/netconf/rendered.yaml | 35 + .../junos_acls/tests/netconf/replaced.yaml | 105 + .../tests/netconf/reset_policy_config.yaml | 16 + .../targets/junos_banner/defaults/main.yaml | 3 + .../targets/junos_banner/meta/main.yml | 3 + .../targets/junos_banner/tasks/main.yaml | 3 + .../targets/junos_banner/tasks/netconf.yaml | 21 + .../junos_banner/tests/netconf/basic.yaml | 205 + .../defaults/main.yaml | 3 + .../junos_bgp_address_family/meta/main.yml | 3 + .../junos_bgp_address_family/tasks/main.yaml | 5 + .../tasks/netconf.yaml | 20 + .../tests/netconf/_reset_config.yaml | 13 + .../tests/netconf/deleted.yaml | 136 + .../tests/netconf/empty_config.yaml | 70 + .../tests/netconf/fixtures/parsed.cfg | 120 + .../tests/netconf/gathered.yaml | 149 + .../tests/netconf/merged.yaml | 155 + .../tests/netconf/overridden.yaml | 131 + .../tests/netconf/parsed.yaml | 84 + .../tests/netconf/rendered.yaml | 83 + .../tests/netconf/replaced.yaml | 177 + .../junos_bgp_global/defaults/main.yaml | 3 + .../targets/junos_bgp_global/meta/main.yml | 3 + .../targets/junos_bgp_global/tasks/main.yaml | 5 + .../junos_bgp_global/tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 35 + .../tests/netconf/_reset_config.yaml | 37 + .../tests/netconf/deleted.yaml | 34 + .../tests/netconf/empty_config.yaml | 54 + .../tests/netconf/fixtures/parsed.cfg | 47 + .../tests/netconf/gathered.yaml | 30 + .../tests/netconf/merged.yaml | 129 + .../tests/netconf/overridden.yaml | 51 + .../tests/netconf/parsed.yaml | 52 + .../tests/netconf/purged.yaml | 34 + .../tests/netconf/rendered.yaml | 41 + .../tests/netconf/replaced.yaml | 51 + .../junos_bgp_global/tests/netconf/rtt.yml | 92 + .../targets/junos_bgp_global/vars/main.yaml | 119 + .../targets/junos_command/defaults/main.yaml | 3 + .../targets/junos_command/meta/main.yml | 3 + .../targets/junos_command/tasks/cli.yaml | 19 + .../targets/junos_command/tasks/main.yaml | 14 + .../junos_command/tasks/netconf_json.yaml | 21 + .../junos_command/tasks/netconf_text.yaml | 21 + .../junos_command/tasks/netconf_xml.yaml | 21 + .../junos_command/tests/cli/cli_commmand.yaml | 69 + .../tests/netconf_json/bad_operator.yaml | 27 + .../tests/netconf_json/contains.yaml | 28 + .../tests/netconf_json/equal.yaml | 44 + .../tests/netconf_json/greaterthan.yaml | 46 + .../netconf_json/greaterthanorequal.yaml | 46 + .../tests/netconf_json/lessthan.yaml | 46 + .../tests/netconf_json/lessthanorequal.yaml | 46 + .../tests/netconf_json/notequal.yaml | 46 + .../tests/netconf_json/output.yaml | 67 + .../tests/netconf_text/bad_operator.yaml | 28 + .../tests/netconf_text/contains.yaml | 27 + .../tests/netconf_text/invalid.yaml | 41 + .../tests/netconf_text/no_config.yaml | 26 + .../tests/netconf_text/output.yaml | 78 + .../tests/netconf_text/timeout.yaml | 26 + .../tests/netconf_xml/bad_operator.yaml | 28 + .../tests/netconf_xml/contains.yaml | 28 + .../tests/netconf_xml/equal.yaml | 40 + .../tests/netconf_xml/greaterthan.yaml | 46 + .../tests/netconf_xml/greaterthanorequal.yaml | 46 + .../tests/netconf_xml/invalid.yaml | 38 + .../tests/netconf_xml/lessthan.yaml | 46 + .../tests/netconf_xml/lessthanorequal.yaml | 46 + .../tests/netconf_xml/notequal.yaml | 44 + .../tests/netconf_xml/output.yaml | 66 + .../tests/netconf_xml/timeout.yaml | 23 + .../targets/junos_config/defaults/main.yaml | 2 + .../targets/junos_config/meta/main.yml | 3 + .../junos_config/tasks/cli_config.yaml | 19 + .../targets/junos_config/tasks/main.yaml | 12 + .../targets/junos_config/tasks/netconf.yaml | 21 + .../junos_config/tasks/redirection.yaml | 19 + .../junos_config/templates/basic/config.j2 | 9 + .../junos_config/templates/basic/config.set | 1 + .../junos_config/templates/basic/config.xml | 15 + .../tests/cli_config/cli_backup.yaml | 110 + .../tests/cli_config/cli_basic.yaml | 65 + .../tests/cli_config/cli_replace.yaml | 65 + .../junos_config/tests/netconf/backup.yaml | 32 + .../tests/netconf/bad_action.yaml | 17 + .../junos_config/tests/netconf/invalid.yaml | 27 + .../junos_config/tests/netconf/multiple.yaml | 43 + .../junos_config/tests/netconf/single.yaml | 72 + .../junos_config/tests/netconf/src_basic.yaml | 96 + .../tests/netconf/src_invalid.yaml | 18 + .../tests/redirection/shortname.yaml | 47 + .../targets/junos_facts/defaults/main.yaml | 3 + .../targets/junos_facts/meta/main.yml | 3 + .../targets/junos_facts/tasks/main.yaml | 3 + .../targets/junos_facts/tasks/netconf.yaml | 21 + .../junos_facts/tests/netconf/facts.yaml | 128 + .../tests/netconf/network_facts.yaml | 124 + .../targets/junos_hostname/defaults/main.yaml | 3 + .../targets/junos_hostname/meta/main.yml | 3 + .../targets/junos_hostname/tasks/main.yaml | 5 + .../targets/junos_hostname/tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 13 + .../tests/netconf/_reset_config.yaml | 13 + .../junos_hostname/tests/netconf/deleted.yaml | 33 + .../tests/netconf/empty_config.yaml | 66 + .../tests/netconf/fixtures/parsed.cfg | 156 + .../tests/netconf/gathered.yaml | 29 + .../junos_hostname/tests/netconf/merged.yaml | 59 + .../tests/netconf/overridden.yaml | 46 + .../junos_hostname/tests/netconf/parsed.yaml | 23 + .../tests/netconf/rendered.yaml | 26 + .../tests/netconf/replaced.yaml | 45 + .../junos_hostname/tests/netconf/rtt.yml | 60 + .../targets/junos_hostname/vars/main.yaml | 12 + .../junos_interfaces/defaults/main.yaml | 3 + .../targets/junos_interfaces/meta/main.yaml | 3 + .../targets/junos_interfaces/tasks/main.yaml | 5 + .../junos_interfaces/tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 15 + .../tests/netconf/_remove_config.yaml | 21 + .../tests/netconf/deleted.yaml | 105 + .../tests/netconf/fixtures/parsed.cfg | 53 + .../tests/netconf/gathered.yaml | 77 + .../tests/netconf/groups.yaml | 59 + .../tests/netconf/merged.yaml | 94 + .../tests/netconf/overridden.yaml | 73 + .../tests/netconf/parsed.yaml | 42 + .../tests/netconf/rendered.yaml | 29 + .../tests/netconf/replaced.yaml | 86 + .../junos_interfaces/tests/netconf/rtt.yaml | 105 + .../junos_l2_interfaces/defaults/main.yaml | 3 + .../junos_l2_interfaces/meta/main.yaml | 3 + .../junos_l2_interfaces/tasks/main.yaml | 5 + .../junos_l2_interfaces/tasks/netconf.yaml | 20 + .../tests/netconf/_base_config.yaml | 18 + .../tests/netconf/_remove_config.yaml | 22 + .../tests/netconf/deleted.yaml | 90 + .../tests/netconf/fixtures/parsed.cfg | 53 + .../tests/netconf/gathered.yaml | 61 + .../tests/netconf/merged.yaml | 67 + .../tests/netconf/overridden.yaml | 71 + .../tests/netconf/parsed.yaml | 38 + .../tests/netconf/rendered.yaml | 63 + .../tests/netconf/replaced.yaml | 67 + .../junos_l2_interfaces/tests/netconf/rtt.yml | 59 + .../junos_l3_interfaces/defaults/main.yaml | 3 + .../junos_l3_interfaces/meta/main.yaml | 3 + .../junos_l3_interfaces/tasks/main.yaml | 5 + .../junos_l3_interfaces/tasks/netconf.yaml | 19 + .../tests/netconf/fixtures/parsed.cfg | 56 + .../tests/netconf/junos_l3_interfaces.yml | 133 + .../tests/netconf/parsed.yaml | 45 + .../tests/netconf/rendered.yaml | 65 + .../targets/junos_lacp/defaults/main.yaml | 3 + .../targets/junos_lacp/meta/main.yml | 3 + .../targets/junos_lacp/tasks/main.yaml | 5 + .../targets/junos_lacp/tasks/netconf.yaml | 20 + .../tests/netconf/_remove_config.yaml | 15 + .../junos_lacp/tests/netconf/deleted.yaml | 47 + .../tests/netconf/fixtures/parsed.cfg | 16 + .../junos_lacp/tests/netconf/gathered.yaml | 37 + .../junos_lacp/tests/netconf/merged.yaml | 45 + .../junos_lacp/tests/netconf/parsed.yaml | 25 + .../junos_lacp/tests/netconf/rendered.yaml | 24 + .../junos_lacp/tests/netconf/replaced.yaml | 50 + .../targets/junos_lacp/tests/netconf/rtt.yaml | 58 + .../junos_lacp_interfaces/defaults/main.yaml | 3 + .../junos_lacp_interfaces/meta/main.yaml | 2 + .../junos_lacp_interfaces/tasks/main.yaml | 5 + .../junos_lacp_interfaces/tasks/netconf.yaml | 20 + .../tests/netconf/_base_config.yaml | 20 + .../tests/netconf/_remove_config.yaml | 21 + .../tests/netconf/deleted.yaml | 110 + .../tests/netconf/fixtures/parsed.cfg | 130 + .../tests/netconf/gathered.yaml | 59 + .../tests/netconf/merged.yaml | 65 + .../tests/netconf/overridden.yml | 85 + .../tests/netconf/parsed.yaml | 35 + .../tests/netconf/rendered.yaml | 33 + .../tests/netconf/replaced.yaml | 117 + .../tests/netconf/rtt.yaml | 81 + .../junos_lag_interfaces/defaults/main.yaml | 3 + .../junos_lag_interfaces/meta/main.yaml | 3 + .../junos_lag_interfaces/tasks/main.yaml | 5 + .../junos_lag_interfaces/tasks/netconf.yaml | 20 + .../tests/netconf/_base_config.yaml | 16 + .../tests/netconf/_remove_config.yaml | 20 + .../tests/netconf/deleted.yaml | 101 + .../tests/netconf/fixtures/parsed.cfg | 235 + .../tests/netconf/gathered.yaml | 70 + .../tests/netconf/merged.yaml | 79 + .../tests/netconf/overridden.yaml | 72 + .../tests/netconf/parsed.yaml | 56 + .../tests/netconf/rendered.yaml | 36 + .../tests/netconf/replaced.yaml | 84 + .../junos_lldp_global/defaults/main.yaml | 3 + .../targets/junos_lldp_global/meta/main.yml | 3 + .../targets/junos_lldp_global/tasks/main.yaml | 5 + .../junos_lldp_global/tasks/netconf.yaml | 20 + .../tests/netconf/_remove_config.yaml | 15 + .../tests/netconf/deleted.yaml | 65 + .../tests/netconf/fixtures/parsed.cfg | 28 + .../tests/netconf/gathered.yaml | 56 + .../tests/netconf/merged.yaml | 66 + .../tests/netconf/parsed.yaml | 27 + .../tests/netconf/rendered.yaml | 26 + .../tests/netconf/replaced.yaml | 78 + .../junos_lldp_global/tests/netconf/rtt.yaml | 83 + .../junos_lldp_interfaces/defaults/main.yaml | 3 + .../junos_lldp_interfaces/meta/main.yaml | 3 + .../junos_lldp_interfaces/tasks/main.yaml | 5 + .../junos_lldp_interfaces/tasks/netconf.yaml | 20 + .../tests/netconf/_remove_config.yaml | 15 + .../tests/netconf/deleted.yaml | 95 + .../tests/netconf/fixtures/parsed.cfg | 24 + .../tests/netconf/gathered.yaml | 58 + .../tests/netconf/merged.yaml | 66 + .../tests/netconf/overridden.yaml | 69 + .../tests/netconf/parsed.yaml | 28 + .../tests/netconf/rendered.yaml | 26 + .../tests/netconf/replaced.yaml | 73 + .../tests/netconf/rtt.yaml | 78 + .../junos_logging_global/defaults/main.yaml | 3 + .../junos_logging_global/meta/main.yml | 3 + .../junos_logging_global/tasks/main.yaml | 5 + .../junos_logging_global/tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 12 + .../tests/netconf/_reset_config.yaml | 12 + .../tests/netconf/backups/empty_config.yaml | 49 + .../tests/netconf/deleted.yaml | 99 + .../tests/netconf/empty_config.yaml | 61 + .../tests/netconf/fixtures/parsed.cfg | 152 + .../tests/netconf/gathered.yaml | 99 + .../tests/netconf/merged.yaml | 136 + .../tests/netconf/overridden.yaml | 175 + .../tests/netconf/parsed.yaml | 20 + .../tests/netconf/rendered.yaml | 29 + .../tests/netconf/replaced.yaml | 175 + .../tests/netconf/rtt.yml | 141 + .../junos_logging_global/vars/main.yaml | 206 + .../targets/junos_net_put/defaults/main.yaml | 3 + .../targets/junos_net_put/tasks/cli.yaml | 22 + .../targets/junos_net_put/tasks/main.yaml | 3 + .../junos_net_put/tests/junos_net_put.yaml | 63 + .../targets/junos_netconf/defaults/main.yaml | 3 + .../targets/junos_netconf/tasks/cli.yaml | 21 + .../targets/junos_netconf/tasks/main.yaml | 3 + .../junos_netconf/tests/cli/changeport.yaml | 123 + .../junos_netconf/tests/cli/netconf.yaml | 133 + .../tests/utils/junos_command.yaml | 6 + .../junos_ntp_global/defaults/main.yaml | 3 + .../targets/junos_ntp_global/meta/main.yml | 3 + .../targets/junos_ntp_global/tasks/main.yaml | 5 + .../junos_ntp_global/tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 14 + .../tests/netconf/_populate_config.yaml | 21 + .../tests/netconf/_reset_config.yaml | 12 + .../tests/netconf/backups/empty_config.yaml | 49 + .../tests/netconf/deleted.yaml | 26 + .../tests/netconf/empty_config.yaml | 60 + .../tests/netconf/fixtures/parsed.cfg | 156 + .../tests/netconf/gathered.yaml | 25 + .../tests/netconf/merged.yaml | 101 + .../tests/netconf/overridden.yaml | 47 + .../tests/netconf/parsed.yaml | 20 + .../tests/netconf/rendered.yaml | 30 + .../tests/netconf/replaced.yaml | 47 + .../junos_ntp_global/tests/netconf/rtt.yml | 105 + .../targets/junos_ntp_global/vars/main.yaml | 104 + .../junos_ospf_interfaces/defaults/main.yaml | 3 + .../junos_ospf_interfaces/meta/main.yaml | 3 + .../junos_ospf_interfaces/tasks/main.yaml | 4 + .../junos_ospf_interfaces/tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 20 + .../tests/netconf/_reset_config.yaml | 11 + .../tests/netconf/deleted.yaml | 63 + .../tests/netconf/empty_config.yaml | 50 + .../netconf/fixtures/parse_ospf_router_id.cfg | 23 + .../tests/netconf/fixtures/parsed.cfg | 20 + .../tests/netconf/gathered.yaml | 39 + .../tests/netconf/merged.yaml | 175 + .../tests/netconf/merged_update.yaml | 66 + .../tests/netconf/overridden.yaml | 69 + .../tests/netconf/parsed.yaml | 57 + .../tests/netconf/rendered.yaml | 31 + .../tests/netconf/replaced.yaml | 46 + .../targets/junos_ospfv2/defaults/main.yaml | 3 + .../targets/junos_ospfv2/meta/main.yaml | 3 + .../targets/junos_ospfv2/tasks/main.yaml | 4 + .../targets/junos_ospfv2/tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 18 + .../tests/netconf/_reset_config.yaml | 11 + .../junos_ospfv2/tests/netconf/deleted.yaml | 25 + .../tests/netconf/empty_config.yaml | 61 + .../tests/netconf/fixtures/parsed.cfg | 32 + .../junos_ospfv2/tests/netconf/gathered.yaml | 50 + .../junos_ospfv2/tests/netconf/merged.yaml | 57 + .../tests/netconf/overridden.yaml | 64 + .../junos_ospfv2/tests/netconf/parsed.yaml | 38 + .../junos_ospfv2/tests/netconf/rendered.yaml | 38 + .../junos_ospfv2/tests/netconf/replaced.yaml | 38 + .../junos_ospfv2/tests/netconf/rtt.yaml | 73 + .../targets/junos_ospfv3/defaults/main.yaml | 3 + .../targets/junos_ospfv3/meta/main.yaml | 3 + .../targets/junos_ospfv3/tasks/main.yaml | 4 + .../targets/junos_ospfv3/tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 18 + .../tests/netconf/_reset_config.yaml | 11 + .../junos_ospfv3/tests/netconf/deleted.yaml | 56 + .../tests/netconf/empty_config.yaml | 49 + .../tests/netconf/fixtures/parsed.cfg | 34 + .../junos_ospfv3/tests/netconf/gathered.yaml | 38 + .../junos_ospfv3/tests/netconf/merged.yaml | 57 + .../tests/netconf/overridden.yaml | 64 + .../junos_ospfv3/tests/netconf/parsed.yaml | 40 + .../junos_ospfv3/tests/netconf/rendered.yaml | 38 + .../junos_ospfv3/tests/netconf/replaced.yaml | 41 + .../junos_prefix_lists/defaults/main.yaml | 3 + .../targets/junos_prefix_lists/meta/main.yml | 3 + .../junos_prefix_lists/tasks/main.yaml | 5 + .../junos_prefix_lists/tasks/netconf.yaml | 20 + .../tests/netconf/_reset_config.yaml | 10 + .../tests/netconf/deleted.yaml | 78 + .../tests/netconf/empty_config.yaml | 62 + .../tests/netconf/fixtures/parsed.cfg | 21 + .../tests/netconf/gathered.yaml | 56 + .../tests/netconf/merged.yaml | 93 + .../tests/netconf/overridden.yaml | 70 + .../tests/netconf/parsed.yaml | 30 + .../tests/netconf/rendered.yaml | 34 + .../tests/netconf/replaced.yaml | 72 + .../defaults/main.yaml | 3 + .../junos_routing_instances/meta/main.yml | 3 + .../junos_routing_instances/tasks/main.yaml | 5 + .../tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 12 + .../tests/netconf/_reset_config.yaml | 12 + .../tests/netconf/deleted.yaml | 84 + .../tests/netconf/empty_config.yaml | 62 + .../tests/netconf/fixtures/parsed.cfg | 30 + .../tests/netconf/gathered.yaml | 65 + .../tests/netconf/merged.yaml | 71 + .../tests/netconf/overridden.yaml | 111 + .../tests/netconf/parsed.yaml | 39 + .../tests/netconf/rendered.yaml | 37 + .../tests/netconf/replaced.yaml | 87 + .../junos_routing_options/defaults/main.yaml | 3 + .../junos_routing_options/meta/main.yml | 3 + .../junos_routing_options/tasks/main.yaml | 5 + .../junos_routing_options/tasks/netconf.yaml | 20 + .../tests/netconf/_populate_config.yaml | 8 + .../tests/netconf/_reset_config.yaml | 12 + .../tests/netconf/deleted.yaml | 25 + .../tests/netconf/empty_config.yaml | 61 + .../tests/netconf/fixtures/parsed.cfg | 14 + .../tests/netconf/gathered.yaml | 24 + .../tests/netconf/merged.yaml | 59 + .../tests/netconf/overridden.yaml | 44 + .../tests/netconf/parsed.yaml | 20 + .../tests/netconf/rendered.yaml | 27 + .../tests/netconf/replaced.yaml | 44 + .../tests/netconf/rtt.yml | 65 + .../junos_routing_options/vars/main.yaml | 21 + .../targets/junos_rpc/defaults/main.yaml | 3 + .../targets/junos_rpc/meta/main.yml | 3 + .../targets/junos_rpc/tasks/main.yaml | 3 + .../targets/junos_rpc/tasks/netconf.yaml | 21 + .../targets/junos_rpc/tests/netconf/rpc.yaml | 69 + .../defaults/main.yaml | 3 + .../junos_security_policies/meta/main.yml | 3 + .../junos_security_policies/tasks/main.yaml | 5 + .../tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 37 + .../tests/netconf/_populate_config.yaml | 53 + .../tests/netconf/_reset_config.yaml | 22 + .../tests/netconf/deleted.yaml | 27 + .../tests/netconf/empty_config.yaml | 61 + .../tests/netconf/fixtures/parsed.xml | 301 + .../tests/netconf/gathered.yaml | 25 + .../tests/netconf/merged.yaml | 171 + .../tests/netconf/overridden.yaml | 53 + .../tests/netconf/parsed.yaml | 23 + .../tests/netconf/rendered.yaml | 124 + .../tests/netconf/replaced.yaml | 53 + .../tests/netconf/rtt.yml | 197 + .../junos_security_policies/vars/main.yaml | 235 + .../defaults/main.yaml | 3 + .../meta/main.yml | 3 + .../tasks/main.yaml | 5 + .../tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 11 + .../tests/netconf/_populate_config.yaml | 22 + .../tests/netconf/_reset_config.yaml | 12 + .../tests/netconf/deleted.yaml | 26 + .../tests/netconf/empty_config.yaml | 61 + .../tests/netconf/fixtures/parsed.cfg | 42 + .../tests/netconf/gathered.yaml | 25 + .../tests/netconf/merged.yaml | 95 + .../tests/netconf/overridden.yaml | 65 + .../tests/netconf/parsed.yaml | 20 + .../tests/netconf/rendered.yaml | 44 + .../tests/netconf/replaced.yaml | 54 + .../tests/netconf/rtt.yml | 91 + .../vars/main.yaml | 65 + .../junos_security_zones/defaults/main.yaml | 3 + .../junos_security_zones/meta/main.yml | 3 + .../junos_security_zones/tasks/main.yaml | 5 + .../junos_security_zones/tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 18 + .../tests/netconf/_populate_config.yaml | 38 + .../tests/netconf/_reset_config.yaml | 16 + .../tests/netconf/deleted.yaml | 26 + .../tests/netconf/empty_config.yaml | 61 + .../tests/netconf/fixtures/parsed.cfg | 137 + .../tests/netconf/gathered.yaml | 23 + .../tests/netconf/merged.yaml | 143 + .../tests/netconf/overridden.yaml | 104 + .../tests/netconf/parsed.yaml | 18 + .../tests/netconf/rendered.yaml | 90 + .../tests/netconf/replaced.yaml | 104 + .../tests/netconf/rtt.yml | 184 + .../junos_security_zones/vars/main.yaml | 220 + .../targets/junos_smoke/defaults/main.yaml | 3 + .../targets/junos_smoke/meta/main.yml | 3 + .../targets/junos_smoke/tasks/cli.yaml | 28 + .../targets/junos_smoke/tasks/main.yaml | 8 + .../targets/junos_smoke/tasks/netconf.yaml | 19 + .../junos_smoke/tests/cli/caching.yaml | 52 + .../targets/junos_smoke/tests/cli/reboot.yaml | 22 + .../tests/netconf/common_utils.yaml | 24 + .../tests/netconf/module_utils_junos.yaml | 53 + .../junos_snmp_server/defaults/main.yaml | 3 + .../targets/junos_snmp_server/meta/main.yml | 3 + .../targets/junos_snmp_server/tasks/main.yaml | 5 + .../junos_snmp_server/tasks/netconf.yaml | 20 + .../tests/netconf/_initial_config.yaml | 14 + .../tests/netconf/_populate_config.yaml | 23 + .../tests/netconf/_reset_config.yaml | 12 + .../tests/netconf/backups/empty_config.yaml | 49 + .../tests/netconf/deleted.yaml | 26 + .../tests/netconf/empty_config.yaml | 60 + .../tests/netconf/fixtures/parsed.cfg | 62 + .../tests/netconf/gathered.yaml | 25 + .../tests/netconf/merged.yaml | 88 + .../tests/netconf/overridden.yaml | 57 + .../tests/netconf/parsed.yaml | 20 + .../tests/netconf/rendered.yaml | 30 + .../tests/netconf/replaced.yaml | 57 + .../junos_snmp_server/tests/netconf/rtt.yaml | 86 + .../targets/junos_snmp_server/vars/main.yaml | 101 + .../junos_static_routes/defaults/main.yaml | 3 + .../junos_static_routes/meta/main.yaml | 2 + .../junos_static_routes/tasks/main.yaml | 5 + .../junos_static_routes/tasks/netconf.yaml | 20 + .../tests/netconf/_base_config.yaml | 25 + .../tests/netconf/_remove_config.yaml | 18 + .../tests/netconf/deleted.yaml | 43 + .../tests/netconf/merged.yaml | 78 + .../tests/netconf/overridden.yaml | 57 + .../tests/netconf/replaced.yaml | 60 + .../integration/targets/junos_system/aliases | 0 .../targets/junos_system/defaults/main.yaml | 3 + .../targets/junos_system/meta/main.yml | 3 + .../targets/junos_system/tasks/main.yaml | 3 + .../targets/junos_system/tasks/netconf.yaml | 21 + .../junos_system/tests/netconf/basic.yaml | 370 + .../targets/junos_user/defaults/main.yaml | 3 + .../targets/junos_user/meta/main.yml | 3 + .../targets/junos_user/tasks/main.yaml | 3 + .../targets/junos_user/tasks/netconf.yaml | 21 + .../junos_user/tests/netconf/basic.yaml | 204 + .../targets/junos_vlans/defaults/main.yaml | 3 + .../targets/junos_vlans/meta/main.yaml | 2 + .../targets/junos_vlans/tasks/main.yaml | 5 + .../targets/junos_vlans/tasks/netconf.yaml | 20 + .../tests/netconf/_base_config.yaml | 13 + .../tests/netconf/_initial_config.yaml | 12 + .../tests/netconf/_remove_config.yaml | 12 + .../junos_vlans/tests/netconf/deleted.yaml | 39 + .../tests/netconf/empty_config.yaml | 65 + .../tests/netconf/fixtures/parsed.cfg | 17 + .../junos_vlans/tests/netconf/gathered.yaml | 35 + .../junos_vlans/tests/netconf/merged.yaml | 53 + .../junos_vlans/tests/netconf/overridden.yaml | 47 + .../junos_vlans/tests/netconf/parsed.yaml | 29 + .../junos_vlans/tests/netconf/rendered.yaml | 28 + .../junos_vlans/tests/netconf/replaced.yaml | 50 + .../targets/junos_vlans/tests/netconf/rtt.yml | 65 + .../targets/junos_vrf/defaults/main.yaml | 3 + .../targets/junos_vrf/meta/main.yml | 3 + .../targets/junos_vrf/tasks/main.yaml | 3 + .../targets/junos_vrf/tasks/netconf.yaml | 21 + .../junos_vrf/tests/netconf/basic.yaml | 320 + .../prepare_junos_tests/meta/main.yaml | 2 + .../prepare_junos_tests/tasks/main.yml | 4 + .../prepare_junos_tests/tasks/prepare.yml | 18 + .../junos/tests/sanity/ignore-2.14.txt | 1 + .../junos/tests/sanity/ignore-2.15.txt | 1 + .../junos/tests/sanity/ignore-2.16.txt | 1 + .../junos/tests/sanity/ignore-2.17.txt | 1 + .../junos/tests/sanity/ignore-2.18.txt | 1 + .../junos/tests/sanity/ignore-2.19.txt | 1 + .../junos/tests/unit/__init__.py | 0 .../junos/tests/unit/mock/__init__.py | 0 .../junos/tests/unit/mock/loader.py | 117 + .../junos/tests/unit/mock/path.py | 13 + .../junos/tests/unit/mock/procenv.py | 96 + .../junos/tests/unit/mock/vault_helper.py | 44 + .../junos/tests/unit/mock/yaml_helper.py | 177 + .../junos/tests/unit/modules/__init__.py | 0 .../junos/tests/unit/modules/conftest.py | 34 + .../tests/unit/modules/network/__init__.py | 0 .../unit/modules/network/junos/__init__.py | 0 .../network/junos/fixtures/__init__.py | 0 .../fixtures/get_configuration_rpc_reply.txt | 7 + .../get_configuration_rpc_reply_diff.txt | 12 + .../get_configuration_rpc_reply_json.txt | 190 + .../get_configuration_rpc_reply_set.txt | 7 + .../get_configuration_rpc_reply_text.txt | 9 + .../get_configuration_rpc_reply_xml.txt | 9 + .../fixtures/junos_bgp_address_family.cfg | 22 + .../junos_bgp_address_family_config.cfg | 137 + .../junos/fixtures/junos_bgp_global.cfg | 22 + .../fixtures/junos_bgp_global_config.cfg | 37 + .../network/junos/fixtures/junos_config.json | 25 + .../network/junos/fixtures/junos_config.set | 2 + .../network/junos/fixtures/junos_config.text | 8 + .../network/junos/fixtures/junos_config.xml | 9 + .../junos/fixtures/junos_hostname_config.cfg | 8 + .../junos/fixtures/junos_interfaces.cfg | 10 + .../fixtures/junos_interfaces_config.xml | 53 + .../junos/fixtures/junos_l2_interfaces.cfg | 31 + .../fixtures/junos_l2_interfaces_config.cfg | 53 + .../junos/fixtures/junos_l3_interfaces.cfg | 39 + .../fixtures/junos_logging_global_config.cfg | 66 + .../fixtures/junos_ntp_global_config.cfg | 20 + .../junos/fixtures/junos_ospf_interfaces.cfg | 6 + .../fixtures/junos_ospf_interfaces_config.cfg | 34 + .../network/junos/fixtures/junos_ospfv2.cfg | 6 + .../junos/fixtures/junos_ospfv2_config.cfg | 214 + .../network/junos/fixtures/junos_ospfv3.cfg | 6 + .../junos/fixtures/junos_ospfv3_config.cfg | 34 + .../junos_ping_ping_10.10.10.10_count_2 | 7 + ...ng_10.10.10.11_count_5_size_512_interval_2 | 11 + ..._10.10.10.12_count_5_do-not-fragment_rapid | 5 + .../junos_ping_ping_10.10.10.20_count_4 | 4 + .../fixtures/junos_prefix_lists_config.cfg | 21 + .../junos_routing_instances_config.cfg | 32 + .../fixtures/junos_routing_options_config.cfg | 13 + .../junos_security_policies_config.cfg | 172 + .../junos_security_policies_global_config.cfg | 41 + .../fixtures/junos_security_zones_config.cfg | 137 + .../fixtures/junos_snmp_server_config.cfg | 38 + .../junos/fixtures/junos_vlans_config.cfg | 11 + .../junos/fixtures/load_configuration_xml.txt | 6 + .../fixtures/show_chassis_hardware_xml.txt | 26 + .../show_chassis_routing-engine_xml.txt | 52 + .../fixtures/show_interfaces_details_xml.txt | 25 + .../junos/fixtures/show_system_memory_xml.txt | 20 + .../fixtures/show_system_storage_xml.txt | 20 + .../junos/fixtures/show_version_json.txt | 42 + .../junos/fixtures/show_version_text.txt | 8 + .../junos/fixtures/show_version_xml.txt | 12 + .../modules/network/junos/junos_module.py | 104 + .../junos/test_junos_bgp_address_family.py | 3090 +++++ .../network/junos/test_junos_bgp_global.py | 1190 ++ .../network/junos/test_junos_command.py | 182 + .../network/junos/test_junos_config.py | 237 + .../modules/network/junos/test_junos_facts.py | 171 + .../network/junos/test_junos_hostname.py | 148 + .../network/junos/test_junos_interfaces.py | 255 + .../network/junos/test_junos_l2_interfaces.py | 316 + .../network/junos/test_junos_l3_interfaces.py | 256 + .../junos/test_junos_logging_global.py | 1029 ++ .../network/junos/test_junos_netconf.py | 131 + .../network/junos/test_junos_ntp_global.py | 718 + .../junos/test_junos_ospf_interfaces.py | 344 + .../network/junos/test_junos_ospfv2.py | 811 ++ .../network/junos/test_junos_ospfv3.py | 403 + .../network/junos/test_junos_package.py | 92 + .../modules/network/junos/test_junos_ping.py | 168 + .../network/junos/test_junos_prefix_lists.py | 327 + .../junos/test_junos_routing_instances.py | 490 + .../junos/test_junos_routing_options.py | 211 + .../modules/network/junos/test_junos_rpc.py | 137 + .../modules/network/junos/test_junos_scp.py | 121 + .../junos/test_junos_security_policies.py | 1090 ++ .../test_junos_security_policies_global.py | 638 + .../junos/test_junos_security_zones.py | 1245 ++ .../network/junos/test_junos_snmp_server.py | 1083 ++ .../modules/network/junos/test_junos_vlans.py | 258 + .../junos/tests/unit/modules/utils.py | 55 + .../junos/tests/unit/plugins/__init__.py | 0 .../tests/unit/plugins/terminal/__init__.py | 0 .../tests/unit/plugins/terminal/test_junos.py | 59 + .../junos/tests/unit/requirements.txt | 42 + .../junipernetworks/junos/tox-ansible.ini | 10 + ansible_collections/junos_facts.yml | 11 + 870 files changed, 156294 insertions(+), 1 deletion(-) create mode 100644 ansible_collections/ansible.cfg create mode 100644 ansible_collections/device_facts.yml create mode 100644 ansible_collections/inventory create mode 100644 ansible_collections/juniper/device/plugins/action/junos.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/netconf/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/netconf/junos.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acl_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acl_interfaces/acl_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acls/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acls/acls.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_address_family/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_address_family/bgp_address_family.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_global/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_global/bgp_global.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/facts/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/facts/facts.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/hostname/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/hostname/hostname.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/interfaces/interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l2_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l2_interfaces/l2_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l3_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l3_interfaces/l3_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp/lacp.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp_interfaces/lacp_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lag_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lag_interfaces/lag_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_global/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_global/lldp_global.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_interfaces/lldp_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/logging_global/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/logging_global/logging_global.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ntp_global/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ntp_global/ntp_global.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospf_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospf_interfaces/ospf_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv2/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv2/ospfv2.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv3/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv3/ospfv3.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/prefix_lists/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/prefix_lists/prefix_lists.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_instances/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_instances/routing_instances.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_options/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_options/routing_options.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies/security_policies.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies_global/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies_global/security_policies_global.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_zones/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_zones/security_zones.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/snmp_server/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/snmp_server/snmp_server.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/static_routes/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/static_routes/static_routes.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/vlans/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/vlans/vlans.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acl_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acl_interfaces/acl_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acls/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acls/acls.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_address_family/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_address_family/bgp_address_family.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_global/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_global/bgp_global.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/facts.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/hostname/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/hostname/hostname.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/interfaces/interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l2_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l2_interfaces/l2_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l3_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l3_interfaces/l3_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp/lacp.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp_interfaces/lacp_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lag_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lag_interfaces/lag_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/legacy/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/legacy/base.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_global/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_global/lldp_global.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_interfaces/lldp_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/logging_global/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/logging_global/logging_global.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ntp_global/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ntp_global/ntp_global.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospf_interfaces/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospf_interfaces/ospf_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv2/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv2/ospfv2.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv3/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv3/ospfv3.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/prefix_lists/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/prefix_lists/prefix_lists.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_instances/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_instances/routing_instances.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_options/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_options/routing_options.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies/security_policies.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies_global/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies_global/security_policies_global.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_zones/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_zones/security_zones.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/snmp_server/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/snmp_server/snmp_server.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/static_routes/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/static_routes/static_routes.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/vlans/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/vlans/vlans.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/junos.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/utils/__init__.py create mode 100644 ansible_collections/juniper/device/plugins/module_utils/network/junos/utils/utils.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_acl_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_acls.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_banner.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_bgp_address_family.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_bgp_global.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_command.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_config.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_facts.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_hostname.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_l2_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_l3_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_lacp.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_lacp_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_lag_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_lldp_global.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_lldp_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_logging_global.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_netconf.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_ntp_global.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_ospf_interfaces.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_ospfv2.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_ospfv3.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_package.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_ping.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_prefix_lists.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_routing_instances.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_routing_options.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_rpc.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_scp.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_security_policies.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_security_policies_global.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_security_zones.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_snmp_server.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_static_routes.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_system.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_user.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_vlans.py create mode 100644 ansible_collections/juniper/device/plugins/modules/junos_vrf.py create mode 100644 ansible_collections/junipernetworks/junos/.ansible-lint create mode 100644 ansible_collections/junipernetworks/junos/.flake8 create mode 100644 ansible_collections/junipernetworks/junos/.github/dependabot.yml create mode 100644 ansible_collections/junipernetworks/junos/.github/release-drafter.yml create mode 100644 ansible_collections/junipernetworks/junos/.github/workflows/check_label.yml create mode 100644 ansible_collections/junipernetworks/junos/.github/workflows/codecoverage.yml create mode 100644 ansible_collections/junipernetworks/junos/.github/workflows/draft_release.yml create mode 100644 ansible_collections/junipernetworks/junos/.github/workflows/release.yml create mode 100644 ansible_collections/junipernetworks/junos/.github/workflows/tests.yml create mode 100644 ansible_collections/junipernetworks/junos/.gitignore create mode 100644 ansible_collections/junipernetworks/junos/.isort.cfg create mode 100644 ansible_collections/junipernetworks/junos/.pre-commit-config.yaml create mode 100644 ansible_collections/junipernetworks/junos/.prettierignore create mode 100644 ansible_collections/junipernetworks/junos/.yamllint create mode 100644 ansible_collections/junipernetworks/junos/CHANGELOG.rst create mode 100644 ansible_collections/junipernetworks/junos/LICENSE create mode 100644 ansible_collections/junipernetworks/junos/README.md create mode 100644 ansible_collections/junipernetworks/junos/bindep.txt create mode 100644 ansible_collections/junipernetworks/junos/changelogs/.plugin-cache.yaml create mode 100644 ansible_collections/junipernetworks/junos/changelogs/changelog.yaml create mode 100644 ansible_collections/junipernetworks/junos/changelogs/config.yaml create mode 100644 ansible_collections/junipernetworks/junos/changelogs/fragments/.keep create mode 100644 ansible_collections/junipernetworks/junos/changelogs/fragments/0-readme.yml create mode 100644 ansible_collections/junipernetworks/junos/changelogs/fragments/adds_support.yaml create mode 100644 ansible_collections/junipernetworks/junos/changelogs/fragments/ignore_219.yaml create mode 100644 ansible_collections/junipernetworks/junos/changelogs/fragments/libssh.yaml create mode 100644 ansible_collections/junipernetworks/junos/codecov.yml create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_acl_interfaces_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_acls_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_banner_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_bgp_address_family_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_bgp_global_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_cliconf.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_command_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_config_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_facts_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_hostname_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_interfaces_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_l2_interfaces_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_l3_interfaces_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lacp_interfaces_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lacp_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lag_interfaces_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lldp_global_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lldp_interfaces_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_logging_global_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_netconf.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_netconf_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ntp_global_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ospf_interfaces_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ospfv2_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ospfv3_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_package_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ping_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_prefix_lists_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_routing_instances_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_routing_options_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_rpc_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_scp_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_security_policies_global_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_security_policies_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_security_zones_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_snmp_server_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_static_routes_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_system_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_user_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_vlans_module.rst create mode 100644 ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_vrf_module.rst create mode 100644 ansible_collections/junipernetworks/junos/galaxy.yml create mode 100644 ansible_collections/junipernetworks/junos/meta/runtime.yml create mode 100644 ansible_collections/junipernetworks/junos/meta/runtime.yml_bkp create mode 100644 ansible_collections/junipernetworks/junos/pyproject.toml create mode 100644 ansible_collections/junipernetworks/junos/requirements.txt create mode 100644 ansible_collections/junipernetworks/junos/test-requirements.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/.gitignore create mode 100644 ansible_collections/junipernetworks/junos/tests/config.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/target-prefixes.network create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/config_policy.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/idempotent.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/reset_policy_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/tests/netconf/basic.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/purged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/rtt.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/vars/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/cli.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/netconf_json.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/netconf_text.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/netconf_xml.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/cli/cli_commmand.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/bad_operator.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/contains.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/equal.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/greaterthan.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/greaterthanorequal.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/lessthan.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/lessthanorequal.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/notequal.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/output.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/bad_operator.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/contains.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/invalid.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/no_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/output.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/timeout.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/bad_operator.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/contains.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/equal.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/greaterthan.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/greaterthanorequal.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/invalid.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/lessthan.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/lessthanorequal.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/notequal.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/output.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/timeout.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/cli_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/redirection.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/templates/basic/config.j2 create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/templates/basic/config.set create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/templates/basic/config.xml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/cli_config/cli_backup.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/cli_config/cli_basic.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/cli_config/cli_replace.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/backup.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/bad_action.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/invalid.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/multiple.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/single.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/src_basic.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/src_invalid.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/redirection/shortname.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tests/netconf/facts.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tests/netconf/network_facts.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/rtt.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/vars/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/_remove_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/groups.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/rtt.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/_base_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/_remove_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/rtt.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/junos_l3_interfaces.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/_remove_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/rtt.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/_base_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/_remove_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/overridden.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/rtt.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/_base_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/_remove_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/_remove_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/rtt.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/_remove_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/rtt.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/backups/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/rtt.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/vars/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/tasks/cli.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/tests/junos_net_put.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tasks/cli.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tests/cli/changeport.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tests/cli/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tests/utils/junos_command.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/_populate_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/backups/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/rtt.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/vars/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/fixtures/parse_ospf_router_id.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/merged_update.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/rtt.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/_populate_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/rtt.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/vars/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/tests/netconf/rpc.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/_populate_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/fixtures/parsed.xml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/rtt.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/vars/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/_populate_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/rtt.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/vars/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/_populate_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/rtt.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/vars/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tasks/cli.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/cli/caching.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/cli/reboot.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/netconf/common_utils.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/netconf/module_utils_junos.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/_populate_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/_reset_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/backups/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/rtt.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/vars/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/_base_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/_remove_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/aliases create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/tests/netconf/basic.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/tests/netconf/basic.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/_base_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/_initial_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/_remove_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/deleted.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/empty_config.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/fixtures/parsed.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/gathered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/merged.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/overridden.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/parsed.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/rendered.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/replaced.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/rtt.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/defaults/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/meta/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/tasks/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/tasks/netconf.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/tests/netconf/basic.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/prepare_junos_tests/meta/main.yaml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/prepare_junos_tests/tasks/main.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/integration/targets/prepare_junos_tests/tasks/prepare.yml create mode 100644 ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.14.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.15.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.16.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.17.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.18.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.19.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/__init__.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/mock/__init__.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/mock/loader.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/mock/path.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/mock/procenv.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/mock/vault_helper.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/mock/yaml_helper.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/__init__.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/conftest.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/__init__.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/__init__.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/__init__.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_diff.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_json.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_set.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_text.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_xml.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_address_family.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_address_family_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_global.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_global_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.json create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.set create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.text create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.xml create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_hostname_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_interfaces.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_interfaces_config.xml create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_l2_interfaces.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_l2_interfaces_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_l3_interfaces.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_logging_global_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ntp_global_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospf_interfaces.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospf_interfaces_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv2.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv2_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv3.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv3_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.10_count_2 create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.11_count_5_size_512_interval_2 create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.12_count_5_do-not-fragment_rapid create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.20_count_4 create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_prefix_lists_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_routing_instances_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_routing_options_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_security_policies_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_security_policies_global_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_security_zones_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_snmp_server_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_vlans_config.cfg create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/load_configuration_xml.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_chassis_hardware_xml.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_chassis_routing-engine_xml.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_interfaces_details_xml.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_system_memory_xml.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_system_storage_xml.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_version_json.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_version_text.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_version_xml.txt create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/junos_module.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_bgp_address_family.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_bgp_global.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_command.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_config.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_facts.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_hostname.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_interfaces.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_l2_interfaces.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_l3_interfaces.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_logging_global.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_netconf.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ntp_global.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ospf_interfaces.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ospfv2.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ospfv3.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_package.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ping.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_prefix_lists.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_routing_instances.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_routing_options.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_rpc.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_scp.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_security_policies.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_security_policies_global.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_security_zones.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_snmp_server.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_vlans.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/modules/utils.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/plugins/__init__.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/plugins/terminal/__init__.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/plugins/terminal/test_junos.py create mode 100644 ansible_collections/junipernetworks/junos/tests/unit/requirements.txt create mode 100644 ansible_collections/junipernetworks/junos/tox-ansible.ini create mode 100644 ansible_collections/junos_facts.yml diff --git a/ansible_collections/ansible.cfg b/ansible_collections/ansible.cfg new file mode 100644 index 00000000..9a88c6bf --- /dev/null +++ b/ansible_collections/ansible.cfg @@ -0,0 +1,11 @@ +[defaults] +INVENTORY = ./inventory +collections_path=/home/rothakur/juniperwork/ansible_collections/ansible-junos-stdlib/ansible_collections/ +host_key_checking = False +hash_behaviour=merge +no_log = False + +[persistent_connection] +command_timeout =300 +connect_timeout = 300 +connect_retry_timeout = 300 diff --git a/ansible_collections/device_facts.yml b/ansible_collections/device_facts.yml new file mode 100644 index 00000000..3d671886 --- /dev/null +++ b/ansible_collections/device_facts.yml @@ -0,0 +1,11 @@ +--- +- name: Test Junos Facts Module + hosts: junos + gather_facts: false + collections: + - juniper.device + tasks: + - name: Gather Junos Facts + junos_facts: + register: junos_facts_output + diff --git a/ansible_collections/inventory b/ansible_collections/inventory new file mode 100644 index 00000000..659acdba --- /dev/null +++ b/ansible_collections/inventory @@ -0,0 +1,9 @@ +[junos] + + +[junos:vars] +ansible_network_os=junos +ansible_ssh_user=ansible +ansible_ssh_pass=Ansible +ansible_connection=ansible.netcommon.netconf +ansible_network_cli_ssh_type=libssh diff --git a/ansible_collections/juniper/device/meta/runtime.yml b/ansible_collections/juniper/device/meta/runtime.yml index d15cfe2b..f54d9b25 100644 --- a/ansible_collections/juniper/device/meta/runtime.yml +++ b/ansible_collections/juniper/device/meta/runtime.yml @@ -1 +1,8 @@ -requires_ansible: ">=2.10" +requires_ansible: ">=2.15.0" +plugin_routing: + action: + junos_facts: + redirect: juniper.device.facts + modules: + junos_facts: + redirect: juniper.device.facts diff --git a/ansible_collections/juniper/device/plugins/action/junos.py b/ansible_collections/juniper/device/plugins/action/junos.py new file mode 100644 index 00000000..98044163 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/action/junos.py @@ -0,0 +1,172 @@ +# +# (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 copy +import sys + +from ansible.utils.display import Display +from ansible_collections.ansible.netcommon.plugins.action.network import ( + ActionModule as ActionNetworkModule, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + load_provider, +) + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + junos_provider_spec, +) +import q + + +display = Display() + +CLI_SUPPORTED_MODULES = ["junos_netconf", "junos_ping", "junos_command"] + + +class ActionModule(ActionNetworkModule): + q("-Inside Junos Action") + def run(self, tmp=None, task_vars=None): + q("Inside Junos Action") + + del tmp # tmp no longer has any effect + + module_name = self._task.action.split(".")[-1] + self._config_module = True if module_name in ["junos_config", "config"] else False + persistent_connection = self._play_context.connection.split(".")[-1] + warnings = [] + + if self._play_context.connection == "local": + provider = load_provider(junos_provider_spec, self._task.args) + pc = copy.deepcopy(self._play_context) + pc.network_os = "junipernetworks.junos.junos" + pc.remote_addr = provider["host"] or self._play_context.remote_addr + + if provider["transport"] == "cli" and module_name not in CLI_SUPPORTED_MODULES: + return { + "failed": True, + "msg": "Transport type '%s' is not valid for '%s' module. " + "Please see https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html" + % (provider["transport"], module_name), + } + + if module_name == "junos_netconf" or ( + provider["transport"] == "cli" and module_name == "junos_command" + ): + pc.connection = "ansible.netcommon.network_cli" + pc.port = int( + provider["port"] or self._play_context.port or 22, + ) + else: + pc.connection = "ansible.netcommon.netconf" + pc.port = int( + provider["port"] or self._play_context.port or 830, + ) + + 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 + + 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.network_os = "junos" + if pc.connection.split(".")[-1] == "netconf": + pc.connection = "netconf" + else: + pc.connection = "network_cli" + + 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, + ], + ) + elif persistent_connection in ("netconf", "network_cli"): + provider = self._task.args.get("provider", {}) + if any(provider.values()): + # for legacy reasons provider value is required for junos_facts(optional) and junos_package + # modules as it uses junos_eznc library to connect to remote host + if not ( + module_name == "junos_facts" + or module_name == "junos_package" + or module_name == "junos_scp" + ): + display.warning( + "provider is unnecessary when using %s and will be ignored" + % self._play_context.connection, + ) + del self._task.args["provider"] + + if ( + persistent_connection == "network_cli" and module_name not in CLI_SUPPORTED_MODULES + ) or (persistent_connection == "netconf" and module_name in CLI_SUPPORTED_MODULES[0:2]): + return { + "failed": True, + "msg": "Connection type '%s' is not valid for '%s' module. " + "Please see https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html" + % (self._play_context.connection, module_name), + } + 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 \ No newline at end of file diff --git a/ansible_collections/juniper/device/plugins/module_utils/netconf/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/netconf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/netconf/junos.py b/ansible_collections/juniper/device/plugins/module_utils/netconf/junos.py new file mode 100644 index 00000000..58bb0165 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/netconf/junos.py @@ -0,0 +1,283 @@ +# +# (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 (@ansible-network) +name: junos +short_description: Use junos netconf plugin to run netconf commands on Juniper JUNOS + platform +description: +- This junos plugin provides low level abstraction apis for sending and receiving + netconf commands from Juniper JUNOS network devices. +version_added: 1.0.0 +options: + ncclient_device_handler: + type: str + default: junos + description: + - Specifies the ncclient device handler name for Juniper junos network os. To + identify the ncclient device handler name refer ncclient library documentation. +""" + +import json +import re + +from ansible.errors import AnsibleConnectionFailure +from ansible.module_utils._text import to_native, to_text +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.plugin_utils.netconf_base import ( + NetconfBase, + ensure_ncclient, +) + + +try: + from ncclient import manager + from ncclient.operations import RPCError + from ncclient.transport.errors import SSHUnknownHostError + from ncclient.xml_ import new_ele, sub_ele, to_ele, to_xml + + HAS_NCCLIENT = True +except ( + ImportError, + AttributeError, +): # paramiko and gssapi are incompatible and raise AttributeError not ImportError + HAS_NCCLIENT = False + + +class Netconf(NetconfBase): + def get_text(self, ele, tag): + try: + return to_text( + ele.find(tag).text, + errors="surrogate_then_replace", + ).strip() + except AttributeError: + pass + + @ensure_ncclient + def get_device_info(self): + device_info = dict() + device_info["network_os"] = "junos" + ele = new_ele("get-software-information") + data = self.execute_rpc(to_xml(ele)) + reply = to_ele(data) + sw_info = reply.find(".//software-information") + + device_info["network_os_version"] = self.get_text( + sw_info, + "junos-version", + ) + device_info["network_os_hostname"] = self.get_text( + sw_info, + "host-name", + ) + device_info["network_os_model"] = self.get_text( + sw_info, + "product-model", + ) + + return device_info + + def execute_rpc(self, name): + """ + RPC to be execute on remote device + :param name: Name of rpc in string format + :return: Received rpc response from remote host + """ + return self.rpc(name) + + @ensure_ncclient + def load_configuration( + self, + format="xml", + action="merge", + target="candidate", + config=None, + ): + """ + Load given configuration on device + :param format: Format of configuration (xml, text, set) + :param action: Action to be performed (merge, replace, override, update) + :param target: The name of the configuration datastore being edited + :param config: The configuration to be loaded on remote host in string format + :return: Received rpc response from remote host in string format + """ + if config: + if format == "xml": + config = to_ele(config) + + try: + return self.m.load_configuration( + format=format, + action=action, + target=target, + config=config, + ).data_xml + except RPCError as exc: + raise Exception(to_xml(exc.xml)) + + def get_capabilities(self): + result = dict() + result["rpc"] = self.get_base_rpc() + [ + "commit", + "discard_changes", + "validate", + "lock", + "unlock", + "copy_copy", + "execute_rpc", + "load_configuration", + "get_configuration", + "command", + "reboot", + "halt", + ] + result["network_api"] = "netconf" + result["device_info"] = self.get_device_info() + result["server_capabilities"] = list(self.m.server_capabilities) + result["client_capabilities"] = list(self.m.client_capabilities) + result["session_id"] = self.m.session_id + result["device_operations"] = self.get_device_operations( + result["server_capabilities"], + ) + return json.dumps(result) + + @staticmethod + @ensure_ncclient + def guess_network_os(obj): + """ + Guess the remote network os name + :param obj: Netconf connection class object + :return: Network OS name + """ + try: + m = manager.connect( + host=obj._play_context.remote_addr, + port=obj._play_context.port or 830, + username=obj._play_context.remote_user, + password=obj._play_context.password, + key_filename=obj.key_filename, + hostkey_verify=obj.get_option("host_key_checking"), + look_for_keys=obj.get_option("look_for_keys"), + allow_agent=obj._play_context.allow_agent, + timeout=obj.get_option("persistent_connect_timeout"), + # We need to pass in the path to the ssh_config file when guessing + # the network_os so that a jumphost is correctly used if defined + ssh_config=obj._ssh_config, + ) + except SSHUnknownHostError as exc: + raise AnsibleConnectionFailure(to_native(exc)) + + guessed_os = None + for c in m.server_capabilities: + if re.search("junos", c): + guessed_os = "junos" + + m.close_session() + return guessed_os + + def get_configuration(self, format="xml", filter=None): + """ + Retrieve all or part of a specified configuration. + :param format: format in which configuration should be retrieved + :param filter: specifies the portion of the configuration to retrieve + as either xml string rooted in element + :return: Received rpc response from remote host in string format + """ + if filter is not None: + if not isinstance(filter, string_types): + raise AnsibleConnectionFailure( + "get configuration filter should be of type string," + " received value '%s' is of type '%s'" % (filter, type(filter)), + ) + filter = to_ele(filter) + + return self.m.get_configuration(format=format, filter=filter).data_xml + + def compare_configuration(self, rollback=0): + """ + Compare the candidate configuration with running configuration + by default. The candidate configuration can be compared with older + committed configuration by providing rollback id. + :param rollback: Rollback id of previously commited configuration + :return: Received rpc response from remote host in string format + """ + return self.m.compare_configuration(rollback=rollback).data_xml + + def halt(self): + """reboot the device""" + return self.m.halt().data_xml + + def reboot(self): + """reboot the device""" + return self.m.reboot().data_xml + + # Due to issue in ncclient commit() method for Juniper (https://github.com/ncclient/ncclient/issues/238) + # below commit() is a workaround which build's raw `commit-configuration` xml with required tags and uses + # ncclient generic rpc() method to execute rpc on remote host. + # Remove below method after the issue in ncclient is fixed. + @ensure_ncclient + def commit( + self, + confirmed=False, + timeout=None, + persist=None, + check=False, + comment=None, + synchronize=False, + at_time=None, + ): + """ + Commit the candidate configuration as the device's new current configuration. + Depends on the `:candidate` capability. + A confirmed commit (i.e. if *confirmed* is `True`) is reverted if there is no + followup commit within the *timeout* interval. If no timeout is specified the + confirm timeout defaults to 600 seconds (10 minutes). + A confirming commit may have the *confirmed* parameter but this is not required. + Depends on the `:confirmed-commit` capability. + :param confirmed: whether this is a confirmed commit + :param check: Check correctness of syntax + :param timeout: specifies the confirm timeout in seconds + :param comment: Message to write to commit log + :param synchronize: Synchronize commit on remote peers + :param at_time: Time at which to activate configuration changes + :return: Received rpc response from remote host + """ + obj = new_ele("commit-configuration") + if confirmed: + sub_ele(obj, "confirmed") + if check: + sub_ele(obj, "check") + if synchronize: + sub_ele(obj, "synchronize") + if at_time: + subele = sub_ele(obj, "at-time") + subele.text = str(at_time) + if comment: + subele = sub_ele(obj, "log") + subele.text = str(comment) + if timeout: + subele = sub_ele(obj, "confirm-timeout") + subele.text = str(timeout) + return self.rpc(obj) \ No newline at end of file diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acl_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acl_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acl_interfaces/acl_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acl_interfaces/acl_interfaces.py new file mode 100644 index 00000000..ae2303c0 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acl_interfaces/acl_interfaces.py @@ -0,0 +1,80 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2020 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 junos_acl_interfaces module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Acl_interfacesArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_acl_interfaces module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "access_groups": { + "elements": "dict", + "options": { + "acls": { + "elements": "dict", + "options": { + "direction": { + "choices": ["in", "out"], + "type": "str", + }, + "name": {"type": "str"}, + }, + "type": "list", + }, + "afi": {"choices": ["ipv4", "ipv6"], "type": "str"}, + }, + "type": "list", + }, + "name": {"type": "str"}, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "rendered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acls/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acls/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acls/acls.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acls/acls.py new file mode 100644 index 00000000..bf863326 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/acls/acls.py @@ -0,0 +1,211 @@ +# +# _*_ coding: utf_8 _*_ +# Copyright 2020 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 junos_acls module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class AclsArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_acls module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "type": "list", + "options": { + "afi": { + "required": True, + "choices": ["ipv4", "ipv6"], + "type": "str", + }, + "acls": { + "elements": "dict", + "type": "list", + "options": { + "name": {"required": True, "type": "str"}, + "aces": { + "elements": "dict", + "type": "list", + "options": { + "name": {"required": True, "type": "str"}, + "source": { + "type": "dict", + "options": { + "address": {"type": "raw"}, + "prefix_list": { + "elements": "dict", + "type": "list", + "options": { + "name": {"type": "str"}, + }, + }, + "port_protocol": { + "type": "dict", + "options": { + "eq": {"type": "str"}, + "range": { + "type": "dict", + "options": { + "start": { + "type": "int", + }, + "end": {"type": "int"}, + }, + }, + }, + }, + }, + }, + "destination": { + "type": "dict", + "options": { + "address": {"type": "raw"}, + "prefix_list": { + "elements": "dict", + "type": "list", + "options": { + "name": {"type": "str"}, + }, + }, + "port_protocol": { + "type": "dict", + "options": { + "eq": {"type": "str"}, + "range": { + "type": "dict", + "options": { + "start": { + "type": "int", + }, + "end": {"type": "int"}, + }, + }, + }, + }, + }, + }, + "protocol": {"type": "str"}, + "protocol_options": { + "type": "dict", + "options": { + "icmp": { + "type": "dict", + "options": { + "dod_host_prohibited": { + "type": "bool", + }, + "dod_net_prohibited": { + "type": "bool", + }, + "echo": {"type": "bool"}, + "echo_reply": {"type": "bool"}, + "host_tos_unreachable": { + "type": "bool", + }, + "host_redirect": { + "type": "bool", + }, + "host_tos_redirect": { + "type": "bool", + }, + "host_unknown": { + "type": "bool", + }, + "host_unreachable": { + "type": "bool", + }, + "net_redirect": { + "type": "bool", + }, + "net_tos_redirect": { + "type": "bool", + }, + "network_unknown": { + "type": "bool", + }, + "port_unreachable": { + "type": "bool", + }, + "protocol_unreachable": { + "type": "bool", + }, + "reassembly_timeout": { + "type": "bool", + }, + "redirect": {"type": "bool"}, + "router_advertisement": { + "type": "bool", + }, + "router_solicitation": { + "type": "bool", + }, + "source_route_failed": { + "type": "bool", + }, + "time_exceeded": { + "type": "bool", + }, + "ttl_exceeded": { + "type": "bool", + }, + }, + }, + }, + }, + "grant": { + "type": "str", + "choices": ["permit", "deny"], + }, + }, + }, + }, + }, + }, + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "parsed", + "gathered", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } + + +# pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_address_family/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_address_family/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_address_family/bgp_address_family.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_address_family/bgp_address_family.py new file mode 100644 index 00000000..950c6862 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_address_family/bgp_address_family.py @@ -0,0 +1,894 @@ +# +# -*- 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 junos_bgp_address_family module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Bgp_address_familyArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_bgp_address_family module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "options": { + "address_family": { + "elements": "dict", + "options": { + "af_type": { + "elements": "dict", + "options": { + "accepted_prefix_limit": { + "options": { + "forever": {"type": "bool"}, + "idle_timeout": {"type": "bool"}, + "idle_timeout_value": {"type": "int"}, + "limit_threshold": {"type": "int"}, + "maximum": {"type": "int"}, + "teardown": {"type": "bool"}, + }, + "type": "dict", + }, + "add_path": { + "options": { + "receive": {"type": "bool"}, + "send": { + "options": { + "include_backup_path": { + "type": "int", + }, + "multipath": {"type": "bool"}, + "path_count": { + "required": True, + "type": "int", + }, + "path_selection_mode": { + "options": { + "all_paths": { + "type": "bool", + }, + "equal_cost_paths": { + "type": "bool", + }, + }, + "type": "dict", + }, + "prefix_policy": { + "type": "str", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "aggregate_label": { + "options": { + "community": {"type": "str"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "aigp": { + "options": { + "disable": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "damping": {"type": "bool"}, + "defer_initial_multipath_build": { + "options": { + "maximum_delay": {"type": "int"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "delay_route_advertisements": { + "options": { + "max_delay_route_age": {"type": "int"}, + "max_delay_routing_uptime": { + "type": "int", + }, + "min_delay_inbound_convergence": { + "type": "int", + }, + "min_delay_routing_uptime": { + "type": "int", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "entropy_label": { + "options": { + "import": {"type": "str"}, + "no_next_hop_validation": { + "type": "bool", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "explicit_null": { + "options": { + "connected_only": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "extended_nexthop": {"type": "bool"}, + "extended_nexthop_color": {"type": "bool"}, + "graceful_restart_forwarding_state_bit": { + "choices": ["from-fib", "set"], + "type": "str", + }, + "legacy_redirect_ip_action": { + "options": { + "receive": {"type": "bool"}, + "send": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "local_ipv4_address": {"type": "str"}, + "loops": {"type": "int"}, + "no_install": {"type": "bool"}, + "no_validate": {"type": "str"}, + "output_queue_priority_expedited": { + "type": "bool", + }, + "output_queue_priority_priority": { + "type": "int", + }, + "per_group_label": {"type": "bool"}, + "per_prefix_label": {"type": "bool"}, + "prefix_limit": { + "options": { + "forever": {"type": "bool"}, + "idle_timeout": {"type": "bool"}, + "idle_timeout_value": {"type": "int"}, + "limit_threshold": {"type": "int"}, + "maximum": {"type": "int"}, + "teardown": {"type": "bool"}, + }, + "type": "dict", + }, + "resolve_vpn": {"type": "bool"}, + "rib": {"choices": ["inet.3"], "type": "str"}, + "ribgroup_name": {"type": "str"}, + "route_refresh_priority_expedited": { + "type": "bool", + }, + "route_refresh_priority_priority": { + "type": "int", + }, + "secondary_independent_resolution": { + "type": "bool", + }, + "set": {"type": "bool"}, + "strip_nexthop": {"type": "bool"}, + "topology": { + "elements": "dict", + "options": { + "community": { + "elements": "str", + "type": "list", + }, + "name": {"type": "str"}, + }, + "type": "list", + }, + "traffic_statistics": { + "options": { + "file": { + "options": { + "filename": {"type": "str"}, + "files": {"type": "int"}, + "no_world_readable": { + "type": "bool", + }, + "size": {"type": "int"}, + "world_readable": { + "type": "bool", + }, + }, + "type": "dict", + }, + "interval": {"type": "int"}, + "labeled_path": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "type": { + "choices": [ + "any", + "flow", + "labeled-unicast", + "multicast", + "segment-routing-te", + "unicast", + "signaling", + "auto-discovery-mspw", + "auto-discovery-only", + ], + "type": "str", + }, + "withdraw_priority_expedited": { + "type": "bool", + }, + "withdraw_priority_priority": {"type": "int"}, + }, + "type": "list", + }, + "afi": { + "choices": [ + "evpn", + "inet", + "inet-mdt", + "inet-mvpn", + "inet-vpn", + "inet6", + "inet6-mvpn", + "inet6-vpn", + "iso-vpn", + "l2vpn", + "route-target", + "traffic-engineering", + ], + "type": "str", + }, + }, + "type": "list", + }, + "groups": { + "elements": "dict", + "options": { + "address_family": { + "elements": "dict", + "options": { + "af_type": { + "elements": "dict", + "options": { + "accepted_prefix_limit": { + "options": { + "forever": {"type": "bool"}, + "idle_timeout": { + "type": "bool", + }, + "idle_timeout_value": { + "type": "int", + }, + "limit_threshold": { + "type": "int", + }, + "maximum": {"type": "int"}, + "teardown": {"type": "bool"}, + }, + "type": "dict", + }, + "add_path": { + "options": { + "receive": {"type": "bool"}, + "send": { + "options": { + "include_backup_path": { + "type": "int", + }, + "multipath": { + "type": "bool", + }, + "path_count": { + "required": True, + "type": "int", + }, + "path_selection_mode": { + "options": { + "all_paths": { + "type": "bool", + }, + "equal_cost_paths": { + "type": "bool", + }, + }, + "type": "dict", + }, + "prefix_policy": { + "type": "str", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "aggregate_label": { + "options": { + "community": {"type": "str"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "aigp": { + "options": { + "disable": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "damping": {"type": "bool"}, + "defer_initial_multipath_build": { + "options": { + "maximum_delay": { + "type": "int", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "delay_route_advertisements": { + "options": { + "max_delay_route_age": { + "type": "int", + }, + "max_delay_routing_uptime": { + "type": "int", + }, + "min_delay_inbound_convergence": { + "type": "int", + }, + "min_delay_routing_uptime": { + "type": "int", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "entropy_label": { + "options": { + "import": {"type": "str"}, + "no_next_hop_validation": { + "type": "bool", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "explicit_null": { + "options": { + "connected_only": { + "type": "bool", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "extended_nexthop": {"type": "bool"}, + "extended_nexthop_color": { + "type": "bool", + }, + "graceful_restart_forwarding_state_bit": { + "choices": ["from-fib", "set"], + "type": "str", + }, + "legacy_redirect_ip_action": { + "options": { + "receive": {"type": "bool"}, + "send": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "local_ipv4_address": {"type": "str"}, + "loops": {"type": "int"}, + "no_install": {"type": "bool"}, + "no_validate": {"type": "str"}, + "output_queue_priority_expedited": { + "type": "bool", + }, + "output_queue_priority_priority": { + "type": "int", + }, + "per_group_label": {"type": "bool"}, + "per_prefix_label": {"type": "bool"}, + "prefix_limit": { + "options": { + "forever": {"type": "bool"}, + "idle_timeout": { + "type": "bool", + }, + "idle_timeout_value": { + "type": "int", + }, + "limit_threshold": { + "type": "int", + }, + "maximum": {"type": "int"}, + "teardown": {"type": "bool"}, + }, + "type": "dict", + }, + "resolve_vpn": {"type": "bool"}, + "rib": { + "choices": ["inet.3"], + "type": "str", + }, + "ribgroup_name": {"type": "str"}, + "route_refresh_priority_expedited": { + "type": "bool", + }, + "route_refresh_priority_priority": { + "type": "int", + }, + "secondary_independent_resolution": { + "type": "bool", + }, + "set": {"type": "bool"}, + "strip_nexthop": {"type": "bool"}, + "topology": { + "elements": "dict", + "options": { + "community": { + "elements": "str", + "type": "list", + }, + "name": {"type": "str"}, + }, + "type": "list", + }, + "traffic_statistics": { + "options": { + "file": { + "options": { + "filename": { + "type": "str", + }, + "files": { + "type": "int", + }, + "no_world_readable": { + "type": "bool", + }, + "size": { + "type": "int", + }, + "world_readable": { + "type": "bool", + }, + }, + "type": "dict", + }, + "interval": {"type": "int"}, + "labeled_path": { + "type": "bool", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "type": { + "choices": [ + "any", + "flow", + "labeled-unicast", + "multicast", + "segment-routing-te", + "unicast", + "signaling", + "auto-discovery-mspw", + "auto-discovery-only", + ], + "type": "str", + }, + "withdraw_priority_expedited": { + "type": "bool", + }, + "withdraw_priority_priority": { + "type": "int", + }, + }, + "type": "list", + }, + "afi": { + "choices": [ + "evpn", + "inet", + "inet-mdt", + "inet-mvpn", + "inet-vpn", + "inet6", + "inet6-mvpn", + "inet6-vpn", + "iso-vpn", + "l2vpn", + "route-target", + "traffic-engineering", + ], + "type": "str", + }, + }, + "type": "list", + }, + "name": {"type": "str"}, + "neighbors": { + "elements": "dict", + "options": { + "address_family": { + "elements": "dict", + "options": { + "af_type": { + "elements": "dict", + "options": { + "accepted_prefix_limit": { + "options": { + "forever": { + "type": "bool", + }, + "idle_timeout": { + "type": "bool", + }, + "idle_timeout_value": { + "type": "int", + }, + "limit_threshold": { + "type": "int", + }, + "maximum": { + "type": "int", + }, + "teardown": { + "type": "bool", + }, + }, + "type": "dict", + }, + "add_path": { + "options": { + "receive": { + "type": "bool", + }, + "send": { + "options": { + "include_backup_path": { + "type": "int", + }, + "multipath": { + "type": "bool", + }, + "path_count": { + "required": True, + "type": "int", + }, + "path_selection_mode": { + "options": { + "all_paths": { + "type": "bool", + }, + "equal_cost_paths": { + "type": "bool", + }, + }, + "type": "dict", + }, + "prefix_policy": { + "type": "str", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "aggregate_label": { + "options": { + "community": { + "type": "str", + }, + "set": { + "type": "bool", + }, + }, + "type": "dict", + }, + "aigp": { + "options": { + "disable": { + "type": "bool", + }, + "set": { + "type": "bool", + }, + }, + "type": "dict", + }, + "damping": {"type": "bool"}, + "defer_initial_multipath_build": { + "options": { + "maximum_delay": { + "type": "int", + }, + "set": { + "type": "bool", + }, + }, + "type": "dict", + }, + "delay_route_advertisements": { + "options": { + "max_delay_route_age": { + "type": "int", + }, + "max_delay_routing_uptime": { + "type": "int", + }, + "min_delay_inbound_convergence": { + "type": "int", + }, + "min_delay_routing_uptime": { + "type": "int", + }, + "set": { + "type": "bool", + }, + }, + "type": "dict", + }, + "entropy_label": { + "options": { + "import": { + "type": "str", + }, + "no_next_hop_validation": { + "type": "bool", + }, + "set": { + "type": "bool", + }, + }, + "type": "dict", + }, + "explicit_null": { + "options": { + "connected_only": { + "type": "bool", + }, + "set": { + "type": "bool", + }, + }, + "type": "dict", + }, + "extended_nexthop": { + "type": "bool", + }, + "extended_nexthop_color": { + "type": "bool", + }, + "graceful_restart_forwarding_state_bit": { + "choices": [ + "from-fib", + "set", + ], + "type": "str", + }, + "legacy_redirect_ip_action": { + "options": { + "receive": { + "type": "bool", + }, + "send": { + "type": "bool", + }, + "set": { + "type": "bool", + }, + }, + "type": "dict", + }, + "local_ipv4_address": { + "type": "str", + }, + "loops": {"type": "int"}, + "no_install": {"type": "bool"}, + "no_validate": {"type": "str"}, + "output_queue_priority_expedited": { + "type": "bool", + }, + "output_queue_priority_priority": { + "type": "int", + }, + "per_group_label": { + "type": "bool", + }, + "per_prefix_label": { + "type": "bool", + }, + "prefix_limit": { + "options": { + "forever": { + "type": "bool", + }, + "idle_timeout": { + "type": "bool", + }, + "idle_timeout_value": { + "type": "int", + }, + "limit_threshold": { + "type": "int", + }, + "maximum": { + "type": "int", + }, + "teardown": { + "type": "bool", + }, + }, + "type": "dict", + }, + "resolve_vpn": { + "type": "bool", + }, + "rib": { + "choices": ["inet.3"], + "type": "str", + }, + "ribgroup_name": { + "type": "str", + }, + "route_refresh_priority_expedited": { + "type": "bool", + }, + "route_refresh_priority_priority": { + "type": "int", + }, + "secondary_independent_resolution": { + "type": "bool", + }, + "set": {"type": "bool"}, + "strip_nexthop": { + "type": "bool", + }, + "topology": { + "elements": "dict", + "options": { + "community": { + "elements": "str", + "type": "list", + }, + "name": { + "type": "str", + }, + }, + "type": "list", + }, + "traffic_statistics": { + "options": { + "file": { + "options": { + "filename": { + "type": "str", + }, + "files": { + "type": "int", + }, + "no_world_readable": { + "type": "bool", + }, + "size": { + "type": "int", + }, + "world_readable": { + "type": "bool", + }, + }, + "type": "dict", + }, + "interval": { + "type": "int", + }, + "labeled_path": { + "type": "bool", + }, + "set": { + "type": "bool", + }, + }, + "type": "dict", + }, + "type": { + "choices": [ + "any", + "flow", + "labeled-unicast", + "multicast", + "segment-routing-te", + "unicast", + "signaling", + "auto-discovery-mspw", + "auto-discovery-only", + ], + "type": "str", + }, + "withdraw_priority_expedited": { + "type": "bool", + }, + "withdraw_priority_priority": { + "type": "int", + }, + }, + "type": "list", + }, + "afi": { + "choices": [ + "evpn", + "inet", + "inet-mdt", + "inet-mvpn", + "inet-vpn", + "inet6", + "inet6-mvpn", + "inet6-vpn", + "iso-vpn", + "l2vpn", + "route-target", + "traffic-engineering", + ], + "type": "str", + }, + }, + "type": "list", + }, + "neighbor_address": {"type": "str"}, + }, + "type": "list", + }, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "rendered", + "gathered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_global/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_global/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_global/bgp_global.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_global/bgp_global.py new file mode 100644 index 00000000..63c4347b --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/bgp_global/bgp_global.py @@ -0,0 +1,1272 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2020 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 junos_bgp_global module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Bgp_globalArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_bgp_global module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "options": { + "accept_remote_nexthop": {"type": "bool"}, + "add_path_display_ipv4_address": {"type": "bool"}, + "advertise_bgp_static": { + "options": { + "policy": {"type": "str"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "advertise_external": { + "options": { + "conditional": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "advertise_from_main_vpn_tables": {"type": "bool"}, + "advertise_inactive": {"type": "bool"}, + "advertise_peer_as": {"type": "bool"}, + "as_number": {"type": "str"}, + "asdot_notation": {"type": "bool"}, + "authentication_algorithm": { + "choices": ["aes-128-cmac-96", "hmac-sha-1-96", "md5"], + "type": "str", + }, + "authentication_key": {"type": "str", "no_log": True}, + "authentication_key_chain": {"type": "str", "no_log": False}, + "bfd_liveness_detection": { + "options": { + "authentication": { + "options": { + "algorithm": { + "choices": [ + "keyed-md5", + "keyed-sha-1", + "meticulous-keyed-md5", + "meticulous-keyed-sha-1", + "simple-password", + ], + "type": "str", + }, + "key_chain": {"type": "str", "no_log": True}, + "loose_check": {"type": "bool"}, + }, + "type": "dict", + }, + "detection_time": { + "options": {"threshold": {"type": "int"}}, + "type": "dict", + }, + "holddown_interval": {"type": "int"}, + "minimum_interval": {"type": "int"}, + "minimum_receive_interval": {"type": "int"}, + "multiplier": {"type": "int"}, + "no_adaptation": {"type": "bool"}, + "session_mode": { + "choices": ["automatic", "multihop", "single-hop"], + "type": "str", + }, + "transmit_interval": { + "options": { + "minimum_interval": {"type": "int"}, + "threshold": {"type": "int"}, + }, + "type": "dict", + }, + "version": { + "choices": ["0", "1", "automatic"], + "type": "str", + }, + }, + "type": "dict", + }, + "bgp_error_tolerance": { + "options": { + "malformed_route_limit": {"type": "int"}, + "malformed_update_log_interval": {"type": "int"}, + "no_malformed_route_limit": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "bmp": { + "options": { + "monitor": {"type": "bool"}, + "route_monitoring": { + "options": { + "none": {"type": "bool"}, + "post_policy": {"type": "bool"}, + "post_policy_exclude_non_eligible": { + "type": "bool", + }, + "post_policy_exclude_non_feasible": { + "type": "bool", + }, + "pre_policy": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "cluster_id": {"type": "str"}, + "damping": {"type": "bool"}, + "description": {"type": "str"}, + "disable": {"type": "bool"}, + "egress_te": { + "options": { + "backup_path": {"type": "str"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "egress_te_backup_paths": { + "options": { + "templates": { + "elements": "dict", + "options": { + "ip_forward": { + "options": { + "rti_name": {"type": "str"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "path_name": {"required": True, "type": "str"}, + "peers": {"elements": "str", "type": "list"}, + "remote_nexthop": {"type": "str"}, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "egress_te_set_segment": { + "elements": "dict", + "options": { + "egress_te_backup_segment_label": {"type": "int"}, + "label": {"type": "int"}, + "name": {"required": True, "type": "str"}, + }, + "type": "list", + }, + "egress_te_sid_stats": {"type": "bool"}, + "enforce_first_as": {"type": "bool"}, + "export": {"type": "str"}, + "forwarding_context": {"type": "str"}, + "graceful_restart": { + "options": { + "disable": {"type": "bool"}, + "dont_help_shared_fate_bfd_down": {"type": "bool"}, + "forwarding_state_bit": { + "options": { + "as_rr_client": {"type": "bool"}, + "from_fib": {"type": "bool"}, + }, + "type": "dict", + }, + "long_lived": { + "options": { + "advertise_to_non_llgr_neighbor": { + "options": { + "omit_no_export": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "receiver_disable": {"type": "bool"}, + }, + "type": "dict", + }, + "restart_time": {"type": "int"}, + "set": {"type": "bool"}, + "stale_routes_time": {"type": "int"}, + }, + "type": "dict", + }, + "groups": { + "elements": "dict", + "options": { + "accept_remote_nexthop": {"type": "bool"}, + "add_path_display_ipv4_address": {"type": "bool"}, + "advertise_bgp_static": { + "options": { + "policy": {"type": "str"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "advertise_external": { + "options": { + "conditional": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "advertise_inactive": {"type": "bool"}, + "advertise_peer_as": {"type": "bool"}, + "allow": {"elements": "str", "type": "list"}, + "as_override": {"type": "bool"}, + "authentication_algorithm": { + "choices": [ + "aes-128-cmac-96", + "hmac-sha-1-96", + "md5", + ], + "type": "str", + }, + "authentication_key": {"type": "str", "no_log": True}, + "authentication_key_chain": { + "type": "str", + "no_log": False, + }, + "bfd_liveness_detection": { + "options": { + "authentication": { + "options": { + "algorithm": { + "choices": [ + "keyed-md5", + "keyed-sha-1", + "meticulous-keyed-md5", + "meticulous-keyed-sha-1", + "simple-password", + ], + "type": "str", + }, + "key_chain": { + "type": "str", + "no_log": True, + }, + "loose_check": {"type": "bool"}, + }, + "type": "dict", + }, + "detection_time": { + "options": {"threshold": {"type": "int"}}, + "type": "dict", + }, + "holddown_interval": {"type": "int"}, + "minimum_interval": {"type": "int"}, + "minimum_receive_interval": {"type": "int"}, + "multiplier": {"type": "int"}, + "no_adaptation": {"type": "bool"}, + "session_mode": { + "choices": [ + "automatic", + "multihop", + "single-hop", + ], + "type": "str", + }, + "transmit_interval": { + "options": { + "minimum_interval": {"type": "int"}, + "threshold": {"type": "int"}, + }, + "type": "dict", + }, + "version": { + "choices": ["0", "1", "automatic"], + "type": "str", + }, + }, + "type": "dict", + }, + "bgp_error_tolerance": { + "options": { + "malformed_route_limit": {"type": "int"}, + "malformed_update_log_interval": { + "type": "int", + }, + "no_malformed_route_limit": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "bmp": { + "options": { + "monitor": {"type": "bool"}, + "route_monitoring": { + "options": { + "none": {"type": "bool"}, + "post_policy": {"type": "bool"}, + "post_policy_exclude_non_eligible": { + "type": "bool", + }, + "post_policy_exclude_non_feasible": { + "type": "bool", + }, + "pre_policy": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "cluster_id": {"type": "str"}, + "damping": {"type": "bool"}, + "description": {"type": "str"}, + "egress_te": { + "options": { + "backup_path": {"type": "str"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "enforce_first_as": {"type": "bool"}, + "export": {"type": "str"}, + "forwarding_context": {"type": "str"}, + "graceful_restart": { + "options": { + "disable": {"type": "bool"}, + "dont_help_shared_fate_bfd_down": { + "type": "bool", + }, + "forwarding_state_bit": { + "options": { + "as_rr_client": {"type": "bool"}, + "from_fib": {"type": "bool"}, + }, + "type": "dict", + }, + "long_lived": { + "options": { + "advertise_to_non_llgr_neighbor": { + "options": { + "omit_no_export": { + "type": "bool", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "receiver_disable": {"type": "bool"}, + }, + "type": "dict", + }, + "restart_time": {"type": "int"}, + "set": {"type": "bool"}, + "stale_routes_time": {"type": "int"}, + }, + "type": "dict", + }, + "hold_time": {"type": "int"}, + "idle_after_switch_over": { + "options": { + "forever": {"type": "bool"}, + "timeout": {"type": "int"}, + }, + "type": "dict", + }, + "import": {"elements": "str", "type": "list"}, + "include_mp_next_hop": {"type": "bool"}, + "ipsec_sa": {"type": "str"}, + "keep": {"choices": ["all", "none"], "type": "str"}, + "local_address": {"type": "str"}, + "local_as": { + "options": { + "alias": {"type": "bool"}, + "as_num": {"required": True, "type": "str"}, + "loops": {"type": "int"}, + "no_prepend_global_as": {"type": "bool"}, + "private": {"type": "bool"}, + }, + "type": "dict", + }, + "local_interface": {"type": "str"}, + "local_preference": {"type": "str"}, + "log_updown": {"type": "bool"}, + "metric_out": { + "options": { + "igp": { + "options": { + "delay_med_update": {"type": "bool"}, + "metric_offset": {"type": "int"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "metric_value": {"type": "int"}, + "minimum_igp": { + "options": { + "metric_offset": {"type": "int"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "mtu_discovery": {"type": "bool"}, + "multihop": { + "options": { + "no_nexthop_change": {"type": "bool"}, + "set": {"type": "bool"}, + "ttl": {"type": "int"}, + }, + "type": "dict", + }, + "multipath": { + "options": { + "disable": {"type": "bool"}, + "multiple_as": {"type": "bool"}, + "multiple_as_disable": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "name": {"type": "str"}, + "neighbors": { + "elements": "dict", + "options": { + "accept_remote_nexthop": {"type": "bool"}, + "add_path_display_ipv4_address": { + "type": "bool", + }, + "advertise_bgp_static": { + "options": { + "policy": {"type": "str"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "advertise_external": { + "options": { + "conditional": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "advertise_inactive": {"type": "bool"}, + "advertise_peer_as": {"type": "bool"}, + "as_override": {"type": "bool"}, + "authentication_algorithm": { + "choices": [ + "aes-128-cmac-96", + "hmac-sha-1-96", + "md5", + ], + "type": "str", + }, + "authentication_key": { + "type": "str", + "no_log": True, + }, + "authentication_key_chain": { + "type": "str", + "no_log": False, + }, + "bfd_liveness_detection": { + "options": { + "authentication": { + "options": { + "algorithm": { + "choices": [ + "keyed-md5", + "keyed-sha-1", + "meticulous-keyed-md5", + "meticulous-keyed-sha-1", + "simple-password", + ], + "type": "str", + }, + "key_chain": { + "type": "str", + "no_log": False, + }, + "loose_check": { + "type": "bool", + }, + }, + "type": "dict", + }, + "detection_time": { + "options": { + "threshold": {"type": "int"}, + }, + "type": "dict", + }, + "holddown_interval": {"type": "int"}, + "minimum_interval": {"type": "int"}, + "minimum_receive_interval": { + "type": "int", + }, + "multiplier": {"type": "int"}, + "no_adaptation": {"type": "bool"}, + "session_mode": { + "choices": [ + "automatic", + "multihop", + "single-hop", + ], + "type": "str", + }, + "transmit_interval": { + "options": { + "minimum_interval": { + "type": "int", + }, + "threshold": {"type": "int"}, + }, + "type": "dict", + }, + "version": { + "choices": ["0", "1", "automatic"], + "type": "str", + }, + }, + "type": "dict", + }, + "bgp_error_tolerance": { + "options": { + "malformed_route_limit": { + "type": "int", + }, + "malformed_update_log_interval": { + "type": "int", + }, + "no_malformed_route_limit": { + "type": "bool", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "bmp": { + "options": { + "monitor": {"type": "bool"}, + "route_monitoring": { + "options": { + "none": {"type": "bool"}, + "post_policy": { + "type": "bool", + }, + "post_policy_exclude_non_eligible": { + "type": "bool", + }, + "post_policy_exclude_non_feasible": { + "type": "bool", + }, + "pre_policy": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "cluster_id": {"type": "str"}, + "damping": {"type": "bool"}, + "description": {"type": "str"}, + "egress_te": { + "options": { + "backup_path": {"type": "str"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "enforce_first_as": {"type": "bool"}, + "export": {"type": "str"}, + "forwarding_context": {"type": "str"}, + "graceful_restart": { + "options": { + "disable": {"type": "bool"}, + "dont_help_shared_fate_bfd_down": { + "type": "bool", + }, + "forwarding_state_bit": { + "options": { + "as_rr_client": { + "type": "bool", + }, + "from_fib": {"type": "bool"}, + }, + "type": "dict", + }, + "long_lived": { + "options": { + "advertise_to_non_llgr_neighbor": { + "options": { + "omit_no_export": { + "type": "bool", + }, + "set": { + "type": "bool", + }, + }, + "type": "dict", + }, + "receiver_disable": { + "type": "bool", + }, + }, + "type": "dict", + }, + "restart_time": {"type": "int"}, + "set": {"type": "bool"}, + "stale_routes_time": {"type": "int"}, + }, + "type": "dict", + }, + "hold_time": {"type": "int"}, + "idle_after_switch_over": { + "options": { + "forever": {"type": "bool"}, + "timeout": {"type": "int"}, + }, + "type": "dict", + }, + "import": {"elements": "str", "type": "list"}, + "include_mp_next_hop": {"type": "bool"}, + "ipsec_sa": {"type": "str"}, + "keep": { + "choices": ["all", "none"], + "type": "str", + }, + "local_address": {"type": "str"}, + "local_as": { + "options": { + "alias": {"type": "bool"}, + "as_num": { + "required": True, + "type": "str", + }, + "loops": {"type": "int"}, + "no_prepend_global_as": { + "type": "bool", + }, + "private": {"type": "bool"}, + }, + "type": "dict", + }, + "local_interface": {"type": "str"}, + "local_preference": {"type": "str"}, + "log_updown": {"type": "bool"}, + "metric_out": { + "options": { + "igp": { + "options": { + "delay_med_update": { + "type": "bool", + }, + "metric_offset": { + "type": "int", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "metric_value": {"type": "int"}, + "minimum_igp": { + "options": { + "metric_offset": { + "type": "int", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "mtu_discovery": {"type": "bool"}, + "multihop": { + "options": { + "no_nexthop_change": {"type": "bool"}, + "set": {"type": "bool"}, + "ttl": {"type": "int"}, + }, + "type": "dict", + }, + "multipath": { + "options": { + "disable": {"type": "bool"}, + "multiple_as": {"type": "bool"}, + "multiple_as_disable": { + "type": "bool", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "neighbor_address": {"type": "str"}, + "no_advertise_peer_as": {"type": "bool"}, + "no_aggregator_id": {"type": "bool"}, + "no_client_reflect": {"type": "bool"}, + "out_delay": {"type": "int"}, + "outbound_route_filter": { + "options": { + "bgp_orf_cisco_mode": {"type": "bool"}, + "prefix_based": { + "options": { + "accept": { + "options": { + "inet": { + "type": "bool", + }, + "inet6": { + "type": "bool", + }, + "set": { + "type": "bool", + }, + }, + "type": "dict", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "passive": {"type": "bool"}, + "peer_as": {"type": "str"}, + "preference": {"type": "str"}, + "remove_private": { + "options": { + "all": {"type": "bool"}, + "all_replace": {"type": "bool"}, + "all_replace_nearest": { + "type": "bool", + }, + "no_peer_loop_check": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "rfc6514_compliant_safi129": {"type": "bool"}, + "route_server_client": {"type": "bool"}, + "tcp_aggressive_transmission": { + "type": "bool", + }, + "tcp_mss": {"type": "int"}, + "traceoptions": { + "options": { + "file": { + "options": { + "filename": { + "required": True, + "type": "str", + }, + "files": {"type": "int"}, + "no_world_readable": { + "type": "bool", + }, + "size": {"type": "int"}, + "world_readable": { + "type": "bool", + }, + }, + "type": "dict", + }, + "flag": { + "elements": "dict", + "options": { + "detail": {"type": "bool"}, + "disable": {"type": "bool"}, + "filter": { + "options": { + "match_on_prefix": { + "type": "bool", + }, + "policy": { + "type": "str", + }, + "set": { + "type": "bool", + }, + }, + "type": "dict", + }, + "name": { + "choices": [ + "4byte-as", + "add-path", + "all", + "bfd", + "damping", + "egress-te", + "general", + "graceful-restart", + "keepalive", + "normal", + "nsr-synchronization", + "open", + "packets", + "policy", + "refresh", + "route", + "state", + "task", + "thread-io", + "thread-update-io", + "timer", + "update", + ], + "required": True, + "type": "str", + }, + "receive": {"type": "bool"}, + "send": {"type": "bool"}, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "ttl": {"type": "int"}, + "unconfigured_peer_graceful_restart": { + "type": "bool", + }, + "vpn_apply_export": {"type": "bool"}, + }, + "type": "list", + }, + "no_advertise_peer_as": {"type": "bool"}, + "no_aggregator_id": {"type": "bool"}, + "no_client_reflect": {"type": "bool"}, + "optimal_route_reflection": { + "options": { + "igp_backup": {"type": "str"}, + "igp_primary": {"type": "str"}, + }, + "type": "dict", + }, + "out_delay": {"type": "int"}, + "outbound_route_filter": { + "options": { + "bgp_orf_cisco_mode": {"type": "bool"}, + "prefix_based": { + "options": { + "accept": { + "options": { + "inet": {"type": "bool"}, + "inet6": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "passive": {"type": "bool"}, + "peer_as": {"type": "str"}, + "preference": {"type": "str"}, + "remove_private": { + "options": { + "all": {"type": "bool"}, + "all_replace": {"type": "bool"}, + "all_replace_nearest": {"type": "bool"}, + "no_peer_loop_check": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "rfc6514_compliant_safi129": {"type": "bool"}, + "route_server_client": {"type": "bool"}, + "tcp_aggressive_transmission": {"type": "bool"}, + "tcp_mss": {"type": "int"}, + "traceoptions": { + "options": { + "file": { + "options": { + "filename": { + "required": True, + "type": "str", + }, + "files": {"type": "int"}, + "no_world_readable": {"type": "bool"}, + "size": {"type": "int"}, + "world_readable": {"type": "bool"}, + }, + "type": "dict", + }, + "flag": { + "elements": "dict", + "options": { + "detail": {"type": "bool"}, + "disable": {"type": "bool"}, + "filter": { + "options": { + "match_on_prefix": { + "type": "bool", + }, + "policy": {"type": "str"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "name": { + "choices": [ + "4byte-as", + "add-path", + "all", + "bfd", + "damping", + "egress-te", + "general", + "graceful-restart", + "keepalive", + "normal", + "nsr-synchronization", + "open", + "packets", + "policy", + "refresh", + "route", + "state", + "task", + "thread-io", + "thread-update-io", + "timer", + "update", + ], + "required": True, + "type": "str", + }, + "receive": {"type": "bool"}, + "send": {"type": "bool"}, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "ttl": {"type": "int"}, + "type": { + "choices": ["external", "internal"], + "type": "str", + }, + "unconfigured_peer_graceful_restart": {"type": "bool"}, + "vpn_apply_export": {"type": "bool"}, + }, + "type": "list", + }, + "hold_time": {"type": "int"}, + "holddown_all_stale_labels": {"type": "bool"}, + "idle_after_switch_over": { + "options": { + "forever": {"type": "bool"}, + "timeout": {"type": "int"}, + }, + "type": "dict", + }, + "import": {"elements": "str", "type": "list"}, + "include_mp_next_hop": {"type": "bool"}, + "ipsec_sa": {"type": "str"}, + "keep": {"choices": ["all", "none"], "type": "str"}, + "local_address": {"type": "str"}, + "local_as": { + "options": { + "alias": {"type": "bool"}, + "as_num": {"required": True, "type": "str"}, + "loops": {"type": "int"}, + "no_prepend_global_as": {"type": "bool"}, + "private": {"type": "bool"}, + }, + "type": "dict", + }, + "local_interface": {"type": "str"}, + "local_preference": {"type": "str"}, + "log_updown": {"type": "bool"}, + "loops": {"type": "int"}, + "metric_out": { + "options": { + "igp": { + "options": { + "delay_med_update": {"type": "bool"}, + "metric_offset": {"type": "int"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "metric_value": {"type": "int"}, + "minimum_igp": { + "options": { + "metric_offset": {"type": "int"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "mtu_discovery": {"type": "bool"}, + "multihop": { + "options": { + "no_nexthop_change": {"type": "bool"}, + "set": {"type": "bool"}, + "ttl": {"type": "int"}, + }, + "type": "dict", + }, + "multipath": { + "options": { + "disable": {"type": "bool"}, + "multiple_as": {"type": "bool"}, + "multiple_as_disable": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "multipath_build_priority": { + "choices": ["low", "medium"], + "type": "str", + }, + "no_advertise_peer_as": {"type": "bool"}, + "no_aggregator_id": {"type": "bool"}, + "no_client_reflect": {"type": "bool"}, + "no_precision_timers": {"type": "bool"}, + "out_delay": {"type": "int"}, + "outbound_route_filter": { + "options": { + "bgp_orf_cisco_mode": {"type": "bool"}, + "prefix_based": { + "options": { + "accept": { + "options": { + "inet": {"type": "bool"}, + "inet6": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "output_queue_priority": { + "options": { + "defaults": { + "options": { + "high": { + "options": { + "expedited": {"type": "bool"}, + "priority": {"type": "int"}, + }, + "type": "dict", + }, + "low": { + "options": { + "expedited": {"type": "bool"}, + "priority": {"type": "int"}, + }, + "type": "dict", + }, + "medium": { + "options": { + "expedited": {"type": "bool"}, + "priority": {"type": "int"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "expedited_update_tokens": { + "type": "int", + "no_log": True, + }, + "priority_update_tokens": { + "elements": "dict", + "no_log": True, + "options": { + "priority": {"required": True, "type": "int"}, + "update_tokens": { + "required": True, + "type": "int", + "no_log": True, + }, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "passive": {"type": "bool"}, + "path_selection": { + "options": { + "always_compare_med": {"type": "bool"}, + "as_path_ignore": {"type": "bool"}, + "cisco_non_deterministic": {"type": "bool"}, + "external_router_id": {"type": "bool"}, + "l2vpn_use_bgp_rules": {"type": "bool"}, + "med_plus_igp": { + "options": { + "igp_multiplier": {"type": "int"}, + "med_multiplier": {"type": "int"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "peer_as": {"type": "str"}, + "precision_timers": {"type": "bool"}, + "preference": {"type": "str"}, + "remove_private": { + "options": { + "all": {"type": "bool"}, + "all_replace": {"type": "bool"}, + "all_replace_nearest": {"type": "bool"}, + "no_peer_loop_check": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "rfc6514_compliant_safi129": {"type": "bool"}, + "route_server_client": {"type": "bool"}, + "send_addpath_optimization": {"type": "bool"}, + "snmp_options": { + "options": { + "backward_traps_only_from_established": { + "type": "bool", + }, + "emit_inet_address_length_in_oid": {"type": "bool"}, + }, + "type": "dict", + }, + "sr_preference_override": {"type": "str"}, + "stale_labels_holddown_period": {"type": "int"}, + "tcp_aggressive_transmission": {"type": "bool"}, + "tcp_mss": {"type": "int"}, + "traceoptions": { + "options": { + "file": { + "options": { + "filename": {"required": True, "type": "str"}, + "files": {"type": "int"}, + "no_world_readable": {"type": "bool"}, + "size": {"type": "int"}, + "world_readable": {"type": "bool"}, + }, + "type": "dict", + }, + "flag": { + "elements": "dict", + "options": { + "detail": {"type": "bool"}, + "disable": {"type": "bool"}, + "filter": { + "options": { + "match_on_prefix": {"type": "bool"}, + "policy": {"type": "str"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "name": { + "choices": [ + "4byte-as", + "add-path", + "all", + "bfd", + "damping", + "egress-te", + "general", + "graceful-restart", + "keepalive", + "normal", + "nsr-synchronization", + "open", + "packets", + "policy", + "refresh", + "route", + "state", + "task", + "thread-io", + "thread-update-io", + "timer", + "update", + ], + "required": True, + "type": "str", + }, + "receive": {"type": "bool"}, + "send": {"type": "bool"}, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "traffic_statistics_labeled_path": { + "options": { + "file": { + "options": { + "filename": {"type": "str"}, + "files": {"type": "int"}, + "no_world_readable": {"type": "bool"}, + "size": {"type": "int"}, + "world_readable": {"type": "bool"}, + }, + "type": "dict", + }, + "interval": {"type": "int"}, + }, + "type": "dict", + }, + "ttl": {"type": "int"}, + "unconfigured_peer_graceful_restart": {"type": "bool"}, + "vpn_apply_export": {"type": "bool"}, + }, + "type": "dict", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "purged", + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "parsed", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/facts/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/facts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/facts/facts.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/facts/facts.py new file mode 100644 index 00000000..c3e4d9dc --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/facts/facts.py @@ -0,0 +1,29 @@ +# +# -*- 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 junos facts module. +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class FactsArgs(object): + """The arg spec for the junos facts module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "gather_subset": dict(default=["min"], type="list", elements="str"), + "config_format": dict( + default="text", + choices=["xml", "text", "set", "json"], + ), + "gather_network_resources": dict(type="list", elements="str"), + "available_network_resources": {"type": "bool", "default": False}, + } \ No newline at end of file diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/hostname/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/hostname/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/hostname/hostname.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/hostname/hostname.py new file mode 100644 index 00000000..84e70cfd --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/hostname/hostname.py @@ -0,0 +1,56 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# 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 junos_hostname module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class HostnameArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_hostname module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": {"options": {"hostname": {"type": "str"}}, "type": "dict"}, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "deleted", + "overridden", + "parsed", + "gathered", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/interfaces/interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/interfaces/interfaces.py new file mode 100644 index 00000000..bc152bd3 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/interfaces/interfaces.py @@ -0,0 +1,86 @@ +# +# -*- 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 junos_interfaces module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class InterfacesArgs(object): + """The arg spec for the junos_interfaces module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "description": {"type": "str"}, + "duplex": { + "choices": ["automatic", "full-duplex", "half-duplex"], + "type": "str", + }, + "enabled": {"default": True, "type": "bool"}, + "hold_time": { + "options": { + "down": {"type": "int"}, + "up": {"type": "int"}, + }, + "required_together": [["down", "up"]], + "type": "dict", + }, + "mtu": {"type": "int"}, + "name": {"required": True, "type": "str"}, + "speed": {"type": "str"}, + "units": { + "elements": "dict", + "options": { + "name": {"type": "int"}, + "description": {"type": "str"}, + }, + "type": "list", + }, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "rendered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l2_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l2_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l2_interfaces/l2_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l2_interfaces/l2_interfaces.py new file mode 100644 index 00000000..e2495ff2 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l2_interfaces/l2_interfaces.py @@ -0,0 +1,75 @@ +# +# -*- 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 junos_l2_interfaces module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class L2_interfacesArgs(object): + """The arg spec for the junos_l2_interfaces module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "access": { + "type": "dict", + "options": {"vlan": {"type": "str"}}, + }, + "name": {"required": True, "type": "str"}, + "trunk": { + "type": "dict", + "options": { + "allowed_vlans": {"elements": "str", "type": "list"}, + "native_vlan": {"type": "str"}, + }, + }, + "unit": {"type": "int"}, + "enhanced_layer": {"type": "bool"}, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "rendered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l3_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l3_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l3_interfaces/l3_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l3_interfaces/l3_interfaces.py new file mode 100644 index 00000000..ffa2edf2 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/l3_interfaces/l3_interfaces.py @@ -0,0 +1,55 @@ +# -*- 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 junos_l3_interfaces module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class L3_interfacesArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_l3_interfaces module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "ipv4": { + "elements": "dict", + "options": {"address": {"type": "str"}}, + "type": "list", + }, + "ipv6": { + "elements": "dict", + "options": {"address": {"type": "str"}}, + "type": "list", + }, + "name": {"required": True, "type": "str"}, + "unit": {"type": "int", "default": 0}, + "mtu": {"type": "int"}, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "parsed", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp/lacp.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp/lacp.py new file mode 100644 index 00000000..e666d5f9 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp/lacp.py @@ -0,0 +1,64 @@ +# +# -*- 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 junos_lacp module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class LacpArgs(object): + """The arg spec for the junos_lacp module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "type": "dict", + "options": { + "link_protection": { + "choices": ["revertive", "non-revertive"], + "type": "str", + }, + "system_priority": {"type": "int"}, + }, + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "deleted", + "gathered", + "rendered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp_interfaces/lacp_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp_interfaces/lacp_interfaces.py new file mode 100644 index 00000000..052a54b0 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lacp_interfaces/lacp_interfaces.py @@ -0,0 +1,79 @@ +# +# -*- 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 junos_lacp_interfaces module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Lacp_interfacesArgs(object): + """The arg spec for the junos_lacp_interfaces module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "force_up": {"type": "bool"}, + "name": {"type": "str"}, + "period": {"choices": ["fast", "slow"]}, + "port_priority": {"type": "int"}, + "sync_reset": { + "choices": ["disable", "enable"], + "type": "str", + }, + "system": { + "options": { + "mac": { + "type": "dict", + "options": {"address": {"type": "str"}}, + }, + "priority": {"type": "int"}, + }, + "type": "dict", + }, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "rendered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lag_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lag_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lag_interfaces/lag_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lag_interfaces/lag_interfaces.py new file mode 100644 index 00000000..bb1d0426 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lag_interfaces/lag_interfaces.py @@ -0,0 +1,77 @@ +# +# -*- 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 junos_lag_interfaces module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Lag_interfacesArgs(object): + """The arg spec for the junos_lag_interfaces module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "members": { + "elements": "dict", + "options": { + "link_type": {"choices": ["primary", "backup"]}, + "member": {"type": "str"}, + "ether_option_type": { + "choices": ["ether", "gigether"], + "default": "ether", + "type": "str", + }, + }, + "type": "list", + }, + "mode": {"choices": ["active", "passive"]}, + "name": {"required": True, "type": "str"}, + "link_protection": {"type": "bool"}, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "parsed", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_global/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_global/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_global/lldp_global.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_global/lldp_global.py new file mode 100644 index 00000000..8f25d4e1 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_global/lldp_global.py @@ -0,0 +1,64 @@ +# +# -*- 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 junos_lldp module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Lldp_globalArgs(object): + """The arg spec for the junos_lldp module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "options": { + "address": {"type": "str"}, + "enabled": {"type": "bool"}, + "hold_multiplier": {"type": "int"}, + "interval": {"type": "int"}, + "transmit_delay": {"type": "int"}, + }, + "type": "dict", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "deleted", + "gathered", + "rendered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_interfaces/lldp_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_interfaces/lldp_interfaces.py new file mode 100644 index 00000000..272302bf --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/lldp_interfaces/lldp_interfaces.py @@ -0,0 +1,63 @@ +# +# -*- 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 junos_lldp_interfaces module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Lldp_interfacesArgs(object): + """The arg spec for the junos_lldp_interfaces module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "enabled": {"type": "bool"}, + "name": {"required": True, "type": "str"}, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "deleted", + "overridden", + "gathered", + "rendered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/logging_global/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/logging_global/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/logging_global/logging_global.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/logging_global/logging_global.py new file mode 100644 index 00000000..a00263a5 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/logging_global/logging_global.py @@ -0,0 +1,1380 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# 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 junos_logging_global module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Logging_globalArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_logging_global module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "options": { + "allow_duplicates": {"type": "bool"}, + "archive": { + "options": { + "binary_data": {"type": "bool"}, + "file_size": {"type": "str"}, + "files": {"type": "int"}, + "no_binary_data": {"type": "bool"}, + "no_world_readable": {"type": "bool"}, + "set": {"type": "bool"}, + "world_readable": {"type": "bool"}, + }, + "type": "dict", + }, + "console": { + "options": { + "any": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "authorization": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "change_log": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "conflict_log": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "daemon": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "dfc": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "external": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "firewall": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "ftp": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "interactive_commands": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "kernel": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "ntp": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "pfe": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "security": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "user": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "files": { + "elements": "dict", + "options": { + "allow_duplicates": {"type": "bool"}, + "any": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "archive": { + "options": { + "archive_sites": { + "elements": "str", + "type": "list", + }, + "binary_data": {"type": "bool"}, + "file_size": {"type": "str"}, + "files": {"type": "int"}, + "no_binary_data": {"type": "bool"}, + "no_world_readable": {"type": "bool"}, + "set": {"type": "bool"}, + "start_time": {"type": "str"}, + "transfer_interval": {"type": "int"}, + "world_readable": {"type": "bool"}, + }, + "type": "dict", + }, + "authorization": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "change_log": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "conflict_log": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "daemon": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "dfc": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "explicit_priority": {"type": "bool"}, + "external": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "firewall": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "ftp": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "interactive_commands": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "kernel": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "match": {"type": "str"}, + "match_strings": {"elements": "str", "type": "list"}, + "name": {"type": "str"}, + "ntp": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "pfe": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "security": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "structured_data": { + "options": { + "brief": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "user": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + }, + "type": "list", + }, + "hosts": { + "elements": "dict", + "options": { + "allow_duplicates": {"type": "bool"}, + "any": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "authorization": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "change_log": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "conflict_log": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "daemon": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "dfc": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "exclude_hostname": {"type": "bool"}, + "explicit_priority": {"type": "bool"}, + "external": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "facility_override": {"type": "str"}, + "firewall": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "ftp": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "interactive_commands": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "kernel": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "log_prefix": {"type": "str"}, + "match": {"type": "str"}, + "match_strings": {"elements": "str", "type": "list"}, + "name": {"type": "str"}, + "ntp": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "pfe": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "port": {"type": "int"}, + "routing_instance": {"type": "str"}, + "security": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "source_address": {"type": "str"}, + "structured_data": { + "options": { + "brief": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "user": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + }, + "type": "list", + }, + "log_rotate_frequency": {"type": "int"}, + "routing_instance": {"type": "str"}, + "server": { + "options": { + "routing_instance": { + "options": { + "all": {"type": "bool"}, + "default": {"type": "bool"}, + "routing_instances": { + "elements": "dict", + "options": { + "disable": {"type": "bool"}, + "name": {"type": "str"}, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "source_address": {"type": "str"}, + "time_format": { + "options": { + "set": {"type": "bool"}, + "millisecond": {"type": "bool"}, + "year": {"type": "bool"}, + }, + "type": "dict", + }, + "users": { + "elements": "dict", + "options": { + "allow_duplicates": {"type": "bool"}, + "any": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "authorization": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "change_log": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "conflict_log": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "daemon": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "dfc": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "external": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "firewall": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "ftp": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "interactive_commands": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "kernel": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "match": {"type": "str"}, + "match_strings": {"elements": "str", "type": "list"}, + "name": {"type": "str"}, + "ntp": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "pfe": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "security": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + "user": { + "options": { + "level": { + "choices": [ + "alert", + "any", + "critical", + "emergency", + "error", + "info", + "none", + "notice", + "warning", + ], + "required": True, + "type": "str", + }, + }, + "type": "dict", + }, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "parsed", + "gathered", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ntp_global/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ntp_global/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ntp_global/ntp_global.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ntp_global/ntp_global.py new file mode 100644 index 00000000..d8fdf267 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ntp_global/ntp_global.py @@ -0,0 +1,133 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# 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 junos_ntp_global module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Ntp_globalArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_ntp_global module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "options": { + "authentication_keys": { + "elements": "dict", + "no_log": False, + "options": { + "algorithm": { + "choices": ["md5", "sha1", "sha256"], + "type": "str", + }, + "id": {"type": "int"}, + "key": {"type": "str", "no_log": True}, + }, + "type": "list", + }, + "boot_server": {"type": "str"}, + "broadcast_client": {"type": "bool"}, + "broadcasts": { + "elements": "dict", + "options": { + "address": {"type": "str"}, + "key": {"type": "str", "no_log": False}, + "routing_instance_name": {"type": "str"}, + "ttl": {"type": "int"}, + "version": {"type": "int"}, + }, + "type": "list", + }, + "interval_range": {"type": "int"}, + "multicast_client": {"type": "str"}, + "peers": { + "elements": "dict", + "options": { + "key_id": {"type": "int", "no_log": False}, + "peer": {"type": "str"}, + "prefer": {"type": "bool"}, + "version": {"type": "int"}, + }, + "type": "list", + }, + "servers": { + "elements": "dict", + "options": { + "key_id": {"type": "int"}, + "prefer": {"type": "bool"}, + "routing_instance": {"type": "str"}, + "server": {"type": "str"}, + "version": {"type": "int"}, + }, + "type": "list", + }, + "source_addresses": { + "elements": "dict", + "options": { + "routing_instance": {"type": "str"}, + "source_address": {"type": "str"}, + }, + "type": "list", + }, + "threshold": { + "options": { + "action": { + "choices": ["accept", "reject"], + "type": "str", + }, + "value": {"type": "int"}, + }, + "type": "dict", + }, + "trusted_keys": { + "type": "list", + "elements": "dict", + "no_log": False, + "options": {"key_id": {"type": "int"}}, + }, + }, + "type": "dict", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "deleted", + "overridden", + "parsed", + "gathered", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospf_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospf_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospf_interfaces/ospf_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospf_interfaces/ospf_interfaces.py new file mode 100644 index 00000000..be251564 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospf_interfaces/ospf_interfaces.py @@ -0,0 +1,142 @@ +# +# -*- 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 junos_ospf_interfaces module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Ospf_interfacesArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_ospf_interfaces module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "router_id": {"type": "str"}, + "address_family": { + "elements": "dict", + "options": { + "afi": { + "choices": ["ipv4", "ipv6"], + "required": True, + "type": "str", + }, + "processes": { + "options": { + "area": { + "options": {"area_id": {"type": "str"}}, + "type": "dict", + }, + "authentication": { + "options": { + "md5": { + "elements": "dict", + "options": { + "key_id": {"type": "int"}, + "key_value": { + "type": "str", + "no_log": True, + }, + "start_time": {"type": "str"}, + }, + "type": "list", + }, + "simple_password": { + "type": "str", + "no_log": True, + }, + }, + "type": "dict", + }, + "bandwidth_based_metrics": { + "elements": "dict", + "options": { + "bandwidth": { + "choices": ["1g", "10g"], + "type": "str", + }, + "metric": {"type": "int"}, + }, + "type": "list", + }, + "dead_interval": {"type": "int"}, + "demand_circuit": {"type": "bool"}, + "flood_reduction": {"type": "bool"}, + "hello_interval": {"type": "int"}, + "interface_type": { + "choices": ["nbma", "p2mp", "p2p"], + "type": "str", + }, + "ipsec_sa": {"type": "str"}, + "metric": {"type": "int"}, + "mtu": {"type": "int"}, + "no_advertise_adjacency_segment": { + "type": "bool", + }, + "no_eligible_backup": {"type": "bool"}, + "no_eligible_remote_backup": {"type": "bool"}, + "no_interface_state_traps": {"type": "bool"}, + "no_neighbor_down_notification": { + "type": "bool", + }, + "node_link_protection": {"type": "bool"}, + "poll_interval": {"type": "int"}, + "priority": {"type": "int"}, + "passive": {"type": "bool"}, + "retransmit_interval": {"type": "int"}, + "secondary": {"type": "bool"}, + "te_metric": {"type": "int"}, + "transit_delay": {"type": "int"}, + }, + "type": "dict", + }, + }, + "type": "list", + }, + "name": {"required": True, "type": "str"}, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "parsed", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv2/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv2/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv2/ospfv2.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv2/ospfv2.py new file mode 100644 index 00000000..c9372213 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv2/ospfv2.py @@ -0,0 +1,159 @@ +# Copyright (C) 2020 Red Hat, Inc. +# +# This program 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. +# +# This program 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 this program. If not, see . + + +""" +The arg spec for the junos_ospfv2 module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Ospfv2Args(object): # pylint: disable=R0903 + """The arg spec for the junos_ospfv2 module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "router_id": {"type": "str"}, + "areas": { + "elements": "dict", + "options": { + "area_id": {"required": True, "type": "str"}, + "area_range": {"type": "str"}, + "area_ranges": { + "type": "list", + "elements": "dict", + "options": { + "address": {"type": "str"}, + "exact": {"type": "bool"}, + "restrict": {"type": "bool"}, + "override_metric": {"type": "int"}, + }, + }, + "stub": { + "type": "dict", + "options": { + "default_metric": {"type": "int"}, + "set": {"type": "bool"}, + }, + }, + "interfaces": { + "elements": "dict", + "options": { + "authentication": { + "type": "dict", + "options": { + "type": {"type": "dict"}, + "password": { + "type": "str", + "no_log": False, + }, + "md5": { + "type": "list", + "elements": "dict", + "options": { + "key_id": {"type": "int"}, + "key": { + "type": "str", + "no_log": False, + }, + "start_time": {"type": "str"}, + }, + }, + }, + }, + "bandwidth_based_metrics": { + "elements": "dict", + "options": { + "bandwidth": { + "choices": ["1g", "10g"], + "type": "str", + }, + "metric": {"type": "int"}, + }, + "type": "list", + }, + "name": {"required": True, "type": "str"}, + "priority": {"type": "int"}, + "metric": {"type": "int"}, + "flood_reduction": {"type": "bool"}, + "passive": {"type": "bool"}, + "timers": { + "type": "dict", + "options": { + "dead_interval": {"type": "int"}, + "hello_interval": {"type": "int"}, + "poll_interval": {"type": "int"}, + "retransmit_interval": {"type": "int"}, + "transit_delay": {"type": "int"}, + }, + }, + }, + "type": "list", + }, + }, + "type": "list", + }, + "external_preference": {"type": "int"}, + "overload": { + "type": "dict", + "options": { + "timeout": {"type": "int"}, + "allow_route_leaking": {"type": "bool"}, + "as_external": {"type": "bool"}, + "stub_network": {"type": "bool"}, + }, + }, + "preference": {"type": "int"}, + "prefix_export_limit": {"type": "int"}, + "reference_bandwidth": { + "choices": ["1g", "10g"], + "type": "str", + }, + "rfc1583compatibility": {"type": "bool"}, + "spf_options": { + "type": "dict", + "options": { + "delay": {"type": "int"}, + "holddown": {"type": "int"}, + "rapid_runs": {"type": "int"}, + "no_ignore_our_externals": {"type": "bool"}, + }, + }, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "rendered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv3/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv3/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv3/ospfv3.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv3/ospfv3.py new file mode 100644 index 00000000..f08691e8 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/ospfv3/ospfv3.py @@ -0,0 +1,125 @@ +# Copyright (C) 2020 Red Hat, Inc. +# +# This program 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. +# +# This program 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 this program. If not, see . + + +""" +The arg spec for the junos_ospfv3 module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Ospfv3Args(object): # pylint: disable=R0903 + """The arg spec for the junos_ospfv3 module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "router_id": {"type": "str"}, + "areas": { + "elements": "dict", + "options": { + "area_id": {"required": True, "type": "str"}, + "area_range": {"type": "str"}, + "stub": { + "type": "dict", + "options": { + "default_metric": {"type": "int"}, + "set": {"type": "bool"}, + }, + }, + "interfaces": { + "elements": "dict", + "options": { + "authentication": { + "type": "dict", + "options": {"type": {"type": "dict"}}, + }, + "bandwidth_based_metrics": { + "elements": "dict", + "options": { + "bandwidth": { + "choices": ["1g", "10g"], + "type": "str", + }, + "metric": {"type": "int"}, + }, + "type": "list", + }, + "name": {"required": True, "type": "str"}, + "priority": {"type": "int"}, + "metric": {"type": "int"}, + "flood_reduction": {"type": "bool"}, + "passive": {"type": "bool"}, + "timers": { + "type": "dict", + "options": { + "dead_interval": {"type": "int"}, + "hello_interval": {"type": "int"}, + "poll_interval": {"type": "int"}, + "retransmit_interval": {"type": "int"}, + "transit_delay": {"type": "int"}, + }, + }, + }, + "type": "list", + }, + }, + "type": "list", + }, + "external_preference": {"type": "int"}, + "overload": { + "type": "dict", + "options": {"timeout": {"type": "int"}}, + }, + "preference": {"type": "int"}, + "prefix_export_limit": {"type": "int"}, + "reference_bandwidth": { + "choices": ["1g", "10g"], + "type": "str", + }, + "rfc1583compatibility": {"type": "bool"}, + "spf_options": { + "type": "dict", + "options": { + "delay": {"type": "int"}, + "holddown": {"type": "int"}, + "rapid_runs": {"type": "int"}, + }, + }, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "rendered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/prefix_lists/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/prefix_lists/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/prefix_lists/prefix_lists.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/prefix_lists/prefix_lists.py new file mode 100644 index 00000000..a85741c4 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/prefix_lists/prefix_lists.py @@ -0,0 +1,63 @@ +# +# -*- 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 junos_prefix_lists module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Prefix_listsArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_prefix_lists module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "address_prefixes": {"elements": "str", "type": "list"}, + "dynamic_db": {"type": "bool"}, + "name": {"type": "str", "required": True}, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "parsed", + "gathered", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_instances/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_instances/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_instances/routing_instances.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_instances/routing_instances.py new file mode 100644 index 00000000..5fc56942 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_instances/routing_instances.py @@ -0,0 +1,124 @@ +# +# -*- 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 junos_routing_instances module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Routing_instancesArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_routing_instances module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "connector_id_advertise": {"type": "bool"}, + "description": {"type": "str"}, + "egress_protection": { + "options": { + "context_identifier": {"type": "str"}, + "protector": {"type": "bool"}, + }, + "type": "dict", + }, + "instance_role": {"choices": ["access", "nni"], "type": "str"}, + "interfaces": { + "elements": "dict", + "options": { + "name": {"type": "str"}, + "protect_interface": {"type": "str"}, + }, + "type": "list", + }, + "bridge_domains": { + "elements": "dict", + "options": { + "name": {"type": "str"}, + "description": {"type": "str"}, + "domain_id": {"type": "int"}, + "service_id": {"type": "int"}, + "vlan_id": {"type": "int"}, + "enable_mac_move_action": {"type": "bool"}, + "mcae_mac_flush": {"type": "bool"}, + "no_irb_layer_2_copy": {"type": "bool"}, + "no_local_switching": {"type": "bool"}, + }, + "type": "list", + }, + "l2vpn_id": {"type": "str"}, + "name": {"type": "str"}, + "no_irb_layer_2_copy": {"type": "bool"}, + "no_local_switching": {"type": "bool"}, + "no_normalization": {"type": "bool"}, + "no_vrf_advertise": {"type": "bool"}, + "no_vrf_propagate_ttl": {"type": "bool"}, + "qualified_bum_pruning_mode": {"type": "bool"}, + "route_distinguisher": {"type": "str"}, + "routing_interface": {"elements": "str", "type": "list"}, + "type": { + "choices": [ + "evpn", + "evpn-vpws", + "forwarding", + "l2backhaul-vpn", + "l2vpn", + "layer2-control", + "mac-vrf", + "mpls-forwarding", + "mpls-internet-multicast", + "no-forwarding", + "virtual-router", + "virtual-switch", + "vpls", + "vrf", + ], + "type": "str", + }, + "vrf_exports": {"elements": "str", "type": "list"}, + "vrf_imports": {"elements": "str", "type": "list"}, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "parsed", + "gathered", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_options/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_options/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_options/routing_options.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_options/routing_options.py new file mode 100644 index 00000000..270d5a81 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/routing_options/routing_options.py @@ -0,0 +1,69 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# 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 junos_routing_options module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Routing_optionsArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_routing_options module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "options": { + "autonomous_system": { + "options": { + "as_number": {"type": "str", "required": True}, + "asdot_notation": {"type": "bool"}, + "loops": {"type": "int"}, + }, + "type": "dict", + }, + "router_id": {"type": "str"}, + }, + "type": "dict", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "deleted", + "overridden", + "parsed", + "gathered", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies/security_policies.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies/security_policies.py new file mode 100644 index 00000000..3c28c641 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies/security_policies.py @@ -0,0 +1,822 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2022 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +""" +The arg spec for the junos_security_policies module +""" + + +class Security_policiesArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_security_policies module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "options": { + "from_zones": { + "elements": "dict", + "options": { + "name": {"type": "str"}, + "to_zones": { + "elements": "dict", + "options": { + "name": {"type": "str"}, + "policies": { + "elements": "dict", + "options": { + "description": {"type": "str"}, + "match": { + "options": { + "application": { + "options": { + "any": { + "type": "bool", + }, + "names": { + "elements": "str", + "type": "list", + }, + }, + "type": "dict", + }, + "destination_address": { + "options": { + "addresses": { + "elements": "str", + "type": "list", + }, + "any": { + "type": "bool", + }, + "any_ipv4": { + "type": "bool", + }, + "any_ipv6": { + "type": "bool", + }, + }, + "type": "dict", + }, + "destination_address_excluded": { + "type": "bool", + }, + "dynamic_application": { + "options": { + "any": { + "type": "bool", + }, + "names": { + "elements": "str", + "type": "list", + }, + "none": { + "type": "bool", + }, + }, + "type": "dict", + }, + "from_zone": { + "options": { + "any": { + "type": "bool", + }, + "junos_host": { + "type": "bool", + }, + "names": { + "elements": "str", + "type": "list", + }, + }, + "type": "dict", + }, + "source_address": { + "options": { + "addresses": { + "elements": "str", + "type": "list", + }, + "any": { + "type": "bool", + }, + "any_ipv4": { + "type": "bool", + }, + "any_ipv6": { + "type": "bool", + }, + }, + "type": "dict", + }, + "source_address_excluded": { + "type": "bool", + }, + "source_end_user_profile": { + "type": "str", + }, + "source_identity": { + "options": { + "any": { + "type": "bool", + }, + "authenticated_user": { + "type": "bool", + }, + "names": { + "elements": "str", + "type": "list", + }, + "unauthenticated_user": { + "type": "bool", + }, + "unknown_user": { + "type": "bool", + }, + }, + "type": "dict", + }, + "to_zone": { + "options": { + "any": { + "type": "bool", + }, + "junos_host": { + "type": "bool", + }, + "names": { + "elements": "str", + "type": "list", + }, + }, + "type": "dict", + }, + "url_category": { + "options": { + "any": { + "type": "bool", + }, + "names": { + "elements": "str", + "type": "list", + }, + "none": { + "type": "bool", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "name": {"type": "str"}, + "scheduler_name": {"type": "str"}, + "then": { + "options": { + "count": {"type": "bool"}, + "deny": {"type": "bool"}, + "log": { + "options": { + "session_close": { + "type": "bool", + }, + "session_init": { + "type": "bool", + }, + }, + "type": "dict", + }, + "permit": { + "options": { + "application_services": { + "options": { + "advanced_anti_malware_policy": { + "type": "str", + }, + "application_firewalls": { + "elements": "dict", + "options": { + "rule_set": { + "type": "str", + }, + }, + "type": "list", + }, + "application_traffic_control_rule_set": { + "type": "str", + }, + "gprs_gtp_profile": { + "type": "str", + }, + "gprs_sctp_profile": { + "type": "str", + }, + "icap_redirect": { + "type": "str", + }, + "idp": { + "type": "bool", + }, + "idp_policy": { + "type": "str", + }, + "packet_capture": { + "type": "bool", + }, + "redirect_wx": { + "type": "bool", + }, + "reverse_redirect_wx": { + "type": "bool", + }, + "security_intelligence": { + "options": { + "add_destination_identity_to_feed": { + "type": "str", + }, + "add_destination_ip_to_feed": { + "type": "str", + }, + "add_source_identity_to_feed": { + "type": "str", + }, + "add_source_ip_to_feed": { + "type": "str", + }, + }, + "type": "dict", + }, + "security_intelligence_policy": { + "type": "str", + }, + "ssl_proxy": { + "options": { + "enable": { + "type": "bool", + }, + "profile_name": { + "type": "str", + }, + }, + "type": "dict", + }, + "uac_policy": { + "options": { + "captive_portal": { + "type": "str", + }, + "enable": { + "type": "bool", + }, + }, + "type": "dict", + }, + "utm_policy": { + "type": "str", + }, + }, + "type": "dict", + }, + "destination_address": { + "choices": [ + "drop-translated", + "drop-untranslated", + ], + "type": "str", + }, + "firewall_authentication": { + "options": { + "pass_through": { + "no_log": True, + "options": { + "access_profile": { + "type": "str", + }, + "auth_only_browser": { + "type": "bool", + }, + "auth_user_agent": { + "type": "str", + }, + "client_match": { + "type": "str", + }, + "ssl_termination_profile": { + "type": "str", + }, + "web_redirect": { + "type": "bool", + }, + "web_redirect_to_https": { + "type": "bool", + }, + }, + "type": "dict", + }, + "push_to_identity_management": { + "type": "bool", + }, + "user_firewall": { + "options": { + "access_profile": { + "type": "str", + }, + "auth_only_browser": { + "type": "bool", + }, + "auth_user_agent": { + "type": "str", + }, + "domain": { + "type": "str", + }, + "ssl_termination_profile": { + "type": "str", + }, + "web_redirect": { + "type": "bool", + }, + "web_redirect_to_https": { + "type": "bool", + }, + }, + "type": "dict", + }, + "web_authentication": { + "elements": "str", + "type": "list", + }, + }, + "type": "dict", + }, + "tcp_options": { + "options": { + "initial_tcp_mss": { + "type": "int", + }, + "reverse_tcp_mss": { + "type": "int", + }, + "sequence_check_required": { + "type": "bool", + }, + "syn_check_required": { + "type": "bool", + }, + "window_scale": { + "type": "bool", + }, + }, + "type": "dict", + }, + "tunnel": { + "options": { + "ipsec_vpn": { + "type": "str", + }, + "pair_policy": { + "type": "str", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "reject": { + "options": { + "enable": { + "type": "bool", + }, + "profile": { + "type": "str", + }, + "ssl_proxy": { + "options": { + "enable": { + "type": "bool", + }, + "profile_name": { + "type": "str", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + }, + "type": "list", + }, + }, + "type": "list", + }, + }, + "type": "list", + }, + "global": { + "options": { + "policies": { + "elements": "dict", + "options": { + "description": {"type": "str"}, + "match": { + "options": { + "application": { + "options": { + "any": {"type": "bool"}, + "names": { + "elements": "str", + "type": "list", + }, + }, + "type": "dict", + }, + "destination_address": { + "options": { + "addresses": { + "elements": "str", + "type": "list", + }, + "any": {"type": "bool"}, + "any_ipv4": {"type": "bool"}, + "any_ipv6": {"type": "bool"}, + }, + "type": "dict", + }, + "destination_address_excluded": { + "type": "bool", + }, + "dynamic_application": { + "options": { + "any": {"type": "bool"}, + "names": { + "elements": "str", + "type": "list", + }, + "none": {"type": "bool"}, + }, + "type": "dict", + }, + "from_zone": { + "options": { + "any": {"type": "bool"}, + "junos_host": {"type": "bool"}, + "names": { + "elements": "str", + "type": "list", + }, + }, + "type": "dict", + }, + "source_address": { + "options": { + "addresses": { + "elements": "str", + "type": "list", + }, + "any": {"type": "bool"}, + "any_ipv4": {"type": "bool"}, + "any_ipv6": {"type": "bool"}, + }, + "type": "dict", + }, + "source_address_excluded": { + "type": "bool", + }, + "source_end_user_profile": { + "type": "str", + }, + "source_identity": { + "options": { + "any": {"type": "bool"}, + "authenticated_user": { + "type": "bool", + }, + "names": { + "elements": "str", + "type": "list", + }, + "unauthenticated_user": { + "type": "bool", + }, + "unknown_user": { + "type": "bool", + }, + }, + "type": "dict", + }, + "to_zone": { + "options": { + "any": {"type": "bool"}, + "junos_host": {"type": "bool"}, + "names": { + "elements": "str", + "type": "list", + }, + }, + "type": "dict", + }, + "url_category": { + "options": { + "any": {"type": "bool"}, + "names": { + "elements": "str", + "type": "list", + }, + "none": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "name": {"type": "str"}, + "scheduler_name": {"type": "str"}, + "then": { + "options": { + "count": {"type": "bool"}, + "deny": {"type": "bool"}, + "log": { + "options": { + "session_close": { + "type": "bool", + }, + "session_init": { + "type": "bool", + }, + }, + "type": "dict", + }, + "permit": { + "options": { + "application_services": { + "options": { + "advanced_anti_malware_policy": { + "type": "str", + }, + "application_firewalls": { + "elements": "dict", + "options": { + "rule_set": { + "type": "str", + }, + }, + "type": "list", + }, + "application_traffic_control_rule_set": { + "type": "str", + }, + "gprs_gtp_profile": { + "type": "str", + }, + "gprs_sctp_profile": { + "type": "str", + }, + "icap_redirect": { + "type": "str", + }, + "idp": { + "type": "bool", + }, + "idp_policy": { + "type": "str", + }, + "packet_capture": { + "type": "bool", + }, + "redirect_wx": { + "type": "bool", + }, + "reverse_redirect_wx": { + "type": "bool", + }, + "security_intelligence": { + "options": { + "add_destination_identity_to_feed": { + "type": "str", + }, + "add_destination_ip_to_feed": { + "type": "str", + }, + "add_source_identity_to_feed": { + "type": "str", + }, + "add_source_ip_to_feed": { + "type": "str", + }, + }, + "type": "dict", + }, + "security_intelligence_policy": { + "type": "str", + }, + "ssl_proxy": { + "options": { + "enable": { + "type": "bool", + }, + "profile_name": { + "type": "str", + }, + }, + "type": "dict", + }, + "uac_policy": { + "options": { + "captive_portal": { + "type": "str", + }, + "enable": { + "type": "bool", + }, + }, + "type": "dict", + }, + "utm_policy": { + "type": "str", + }, + }, + "type": "dict", + }, + "destination_address": { + "choices": [ + "drop-translated", + "drop-untranslated", + ], + "type": "str", + }, + "firewall_authentication": { + "options": { + "pass_through": { + "no_log": True, + "options": { + "access_profile": { + "type": "str", + }, + "auth_only_browser": { + "type": "bool", + }, + "auth_user_agent": { + "type": "str", + }, + "client_match": { + "type": "str", + }, + "ssl_termination_profile": { + "type": "str", + }, + "web_redirect": { + "type": "bool", + }, + "web_redirect_to_https": { + "type": "bool", + }, + }, + "type": "dict", + }, + "push_to_identity_management": { + "type": "bool", + }, + "user_firewall": { + "options": { + "access_profile": { + "type": "str", + }, + "auth_only_browser": { + "type": "bool", + }, + "auth_user_agent": { + "type": "str", + }, + "domain": { + "type": "str", + }, + "ssl_termination_profile": { + "type": "str", + }, + "web_redirect": { + "type": "bool", + }, + "web_redirect_to_https": { + "type": "bool", + }, + }, + "type": "dict", + }, + "web_authentication": { + "elements": "str", + "type": "list", + }, + }, + "type": "dict", + }, + "tcp_options": { + "options": { + "initial_tcp_mss": { + "type": "int", + }, + "reverse_tcp_mss": { + "type": "int", + }, + "sequence_check_required": { + "type": "bool", + }, + "syn_check_required": { + "type": "bool", + }, + "window_scale": { + "type": "bool", + }, + }, + "type": "dict", + }, + "tunnel": { + "options": { + "ipsec_vpn": { + "type": "str", + }, + "pair_policy": { + "type": "str", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "reject": { + "options": { + "enable": {"type": "bool"}, + "profile": {"type": "str"}, + "ssl_proxy": { + "options": { + "enable": { + "type": "bool", + }, + "profile_name": { + "type": "str", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + }, + "type": "list", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "rendered", + "gathered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies_global/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies_global/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies_global/security_policies_global.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies_global/security_policies_global.py new file mode 100644 index 00000000..cac6c346 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_policies_global/security_policies_global.py @@ -0,0 +1,129 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2022 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 junos_security_policies_global module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Security_policies_globalArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_security_policies_global module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "options": { + "default_policy": { + "choices": ["deny-all", "permit-all"], + "type": "str", + }, + "policy_rematch": { + "options": { + "enable": {"type": "bool"}, + "extensive": {"type": "bool"}, + }, + "type": "dict", + }, + "policy_stats": { + "options": { + "enable": {"type": "bool"}, + "system_wide": {"type": "bool"}, + }, + "type": "dict", + }, + "pre_id_default_policy_action": { + "options": { + "log": { + "options": { + "session_close": {"type": "bool"}, + "session_init": {"type": "bool"}, + }, + "type": "dict", + }, + "session_timeout": { + "options": { + "icmp": {"type": "int"}, + "icmp6": {"type": "int"}, + "ospf": {"type": "int"}, + "others": {"type": "int"}, + "tcp": {"type": "int"}, + "udp": {"type": "int"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "traceoptions": { + "options": { + "file": { + "options": { + "files": {"type": "int"}, + "match": {"type": "str"}, + "no_world_readable": {"type": "bool"}, + "size": {"type": "str"}, + "world_readable": {"type": "bool"}, + }, + "type": "dict", + }, + "flag": { + "choices": [ + "all", + "configuration", + "compilation", + "ipc", + "lookup", + "routing-socket", + "rules", + ], + "type": "str", + }, + "no_remote_trace": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "rendered", + "gathered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_zones/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_zones/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_zones/security_zones.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_zones/security_zones.py new file mode 100644 index 00000000..9d9bc483 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/security_zones/security_zones.py @@ -0,0 +1,192 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2022 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 junos_security_zones module +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Security_zonesArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_security_zones module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "options": { + "functional_zone_management": { + "options": { + "description": {"type": "str"}, + "host_inbound_traffic": { + "options": { + "protocols": { + "elements": "dict", + "options": { + "except": {"type": "bool"}, + "name": {"type": "str"}, + }, + "type": "list", + }, + "system_services": { + "elements": "dict", + "options": { + "except": {"type": "bool"}, + "name": {"type": "str"}, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "interfaces": {"elements": "str", "type": "list"}, + "screen": {"type": "str"}, + }, + "type": "dict", + }, + "zones": { + "elements": "dict", + "options": { + "address_book": { + "options": { + "address_sets": { + "elements": "dict", + "options": { + "address_sets": { + "elements": "str", + "type": "list", + }, + "addresses": { + "elements": "str", + "type": "list", + }, + "description": {"type": "str"}, + "name": {"type": "str"}, + }, + "type": "list", + }, + "addresses": { + "elements": "dict", + "options": { + "description": {"type": "str"}, + "dns_name": { + "options": { + "ipv4_only": {"type": "bool"}, + "ipv6_only": {"type": "bool"}, + "name": {"type": "str"}, + }, + "type": "dict", + }, + "ip_prefix": {"type": "str"}, + "name": {"type": "str"}, + "range_address": { + "options": { + "from": {"type": "str"}, + "to": {"type": "str"}, + }, + "type": "dict", + }, + "wildcard_address": {"type": "str"}, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "advance_policy_based_routing_profile": { + "type": "str", + }, + "advanced_connection_tracking": { + "options": { + "mode": { + "choices": [ + "allow-any-host", + "allow-target-host", + "allow-target-host-port", + ], + "type": "str", + }, + "timeout": {"type": "int"}, + "track_all_policies_to_this_zone": { + "type": "bool", + }, + }, + "type": "dict", + }, + "application_tracking": {"type": "bool"}, + "description": {"type": "str"}, + "enable_reverse_reroute": {"type": "bool"}, + "host_inbound_traffic": { + "options": { + "protocols": { + "elements": "dict", + "options": { + "except": {"type": "bool"}, + "name": {"type": "str"}, + }, + "type": "list", + }, + "system_services": { + "elements": "dict", + "options": { + "except": {"type": "bool"}, + "name": {"type": "str"}, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "interfaces": {"elements": "str", "type": "list"}, + "name": {"type": "str"}, + "screen": {"type": "str"}, + "source_identity_log": {"type": "bool"}, + "tcp_rst": {"type": "bool"}, + "unidirectional_session_refreshing": {"type": "bool"}, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "rendered", + "gathered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/snmp_server/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/snmp_server/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/snmp_server/snmp_server.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/snmp_server/snmp_server.py new file mode 100644 index 00000000..d334f4ec --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/snmp_server/snmp_server.py @@ -0,0 +1,700 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# 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 junos_snmp_server module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Snmp_serverArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_snmp_server module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "options": { + "arp": { + "options": { + "host_name_resolution": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "client_lists": { + "elements": "dict", + "options": { + "addresses": { + "elements": "dict", + "options": { + "address": {"type": "str"}, + "restrict": {"type": "bool"}, + }, + "type": "list", + }, + "name": {"type": "str"}, + }, + "type": "list", + }, + "communities": { + "elements": "dict", + "options": { + "authorization": { + "choices": ["read-only", "read-write"], + "type": "str", + }, + "client_list_name": {"type": "str"}, + "clients": { + "elements": "dict", + "options": { + "address": {"type": "str"}, + "restrict": {"type": "bool"}, + }, + "type": "list", + }, + "logical_system": {"elements": "str", "type": "list"}, + "name": {"type": "str"}, + "routing_instances": { + "elements": "dict", + "options": { + "client_list_name": {"type": "str"}, + "clients": { + "elements": "dict", + "options": { + "address": {"type": "str"}, + "restrict": {"type": "bool"}, + }, + "type": "list", + }, + "name": {"type": "str"}, + }, + "type": "list", + }, + "view": {"type": "str"}, + }, + "type": "list", + }, + "contact": {"type": "str"}, + "customization": { + "options": {"ether_stats_ifd_only": {"type": "bool"}}, + "type": "dict", + }, + "description": {"type": "str"}, + "engine_id": { + "options": { + "local": {"type": "str"}, + "use_default_ip_address": {"type": "bool"}, + "use_mac_address": {"type": "bool"}, + }, + "type": "dict", + }, + "filter_duplicates": {"type": "bool"}, + "filter_interfaces": { + "options": { + "all_internal_interfaces": {"type": "bool"}, + "interfaces": {"elements": "str", "type": "list"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "health_monitor": { + "options": { + "falling_threshold": {"type": "int"}, + "idp": {"type": "bool"}, + "interval": {"type": "int"}, + "rising_threshold": {"type": "int"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "if_count_with_filter_interfaces": {"type": "bool"}, + "interfaces": {"elements": "str", "type": "list"}, + "location": {"type": "str"}, + "logical_system_trap_filter": {"type": "bool"}, + "name": {"type": "str"}, + "nonvolatile": { + "options": {"commit_delay": {"type": "int"}}, + "type": "dict", + }, + "proxies": { + "elements": "dict", + "options": { + "device_name": {"type": "str"}, + "logical_system": {"elements": "str", "type": "list"}, + "name": {"type": "str"}, + "routing_instances": { + "elements": "dict", + "options": { + "client_list_name": {"type": "str"}, + "clients": { + "elements": "dict", + "options": { + "address": {"type": "str"}, + "restrict": {"type": "bool"}, + }, + "type": "list", + }, + "name": {"type": "str"}, + }, + "type": "list", + }, + "version_v1": { + "options": { + "no_default_comm_to_v3_config": { + "type": "bool", + }, + "snmp_community": {"type": "str"}, + }, + "type": "dict", + }, + "version_v2c": { + "options": { + "no_default_comm_to_v3_config": { + "type": "bool", + }, + "snmp_community": {"type": "str"}, + }, + "type": "dict", + }, + "version_v3": { + "options": { + "context": {"type": "bool"}, + "security_name": {"type": "str"}, + }, + "type": "dict", + }, + }, + "type": "list", + }, + "rmon": { + "options": { + "alarms": { + "elements": "dict", + "options": { + "description": {"type": "str"}, + "falling_event_index": {"type": "int"}, + "falling_threshold": {"type": "int"}, + "falling_threshold_interval": {"type": "int"}, + "id": {"type": "str"}, + "interval": {"type": "int"}, + "request_type": { + "choices": [ + "get-next-request", + "get-request", + "walk-request", + ], + "type": "str", + }, + "rising_event_index": {"type": "int"}, + "rising_threshold": {"type": "int"}, + "sample_type": { + "choices": [ + "absolute-value", + "delta-value", + ], + "type": "str", + }, + "startup_alarm": { + "choices": [ + "falling-alarm", + "rising-alarm", + "rising-or-falling-alarm", + ], + "type": "str", + }, + "syslog_subtag": {"type": "str"}, + "variable": {"type": "str"}, + }, + "type": "list", + }, + "events": { + "elements": "dict", + "options": { + "community": {"type": "str"}, + "description": {"type": "str"}, + "id": {"type": "int"}, + "type": { + "choices": [ + "log", + "log-and-trap", + "none", + "snmptrap", + ], + "type": "str", + }, + }, + "type": "list", + }, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "routing_instance_access": { + "options": { + "access_lists": {"elements": "str", "type": "list"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + "snmp_v3": { + "options": { + "notify": { + "elements": "dict", + "options": { + "name": {"type": "str"}, + "tag": {"type": "str"}, + "type": {"type": "str"}, + }, + "type": "list", + }, + "notify_filter": { + "elements": "dict", + "options": { + "name": {"type": "str"}, + "oids": { + "elements": "dict", + "options": { + "exclude": {"type": "bool"}, + "include": {"type": "bool"}, + "oid": {"type": "str"}, + }, + "type": "list", + }, + }, + "type": "list", + }, + "snmp_community": { + "elements": "dict", + "options": { + "community_index": {"type": "str"}, + "community_name": {"type": "str"}, + "context": {"type": "str"}, + "security_name": {"type": "str"}, + "tag": {"type": "str"}, + }, + "type": "list", + }, + "target_addresses": { + "elements": "dict", + "options": { + "address": {"type": "str"}, + "address_mask": {"type": "str"}, + "logical_system": {"type": "str"}, + "name": {"type": "str"}, + "port": {"type": "int"}, + "retry_count": {"type": "int"}, + "routing_instance": {"type": "str"}, + "tag_list": {"type": "str"}, + "target_parameters": {"type": "str"}, + "timeout": {"type": "int"}, + }, + "type": "list", + }, + "target_parameters": { + "elements": "dict", + "options": { + "name": {"type": "str"}, + "notify_filter": {"type": "str"}, + "parameters": { + "options": { + "message_processing_model": { + "choices": ["v1", "v2c", "v3"], + "type": "str", + }, + "security_level": { + "choices": [ + "authentication", + "none", + "privacy", + ], + "type": "str", + }, + "security_model": { + "choices": ["usm", "v1", "v2c"], + "type": "str", + }, + "security_name": {"type": "str"}, + }, + "type": "dict", + }, + }, + "type": "list", + }, + "usm": { + "options": { + "local_engine": { + "options": { + "users": { + "elements": "dict", + "options": { + "authentication_md5": { + "options": { + "key": { + "type": "str", + "no_log": False, + }, + "password": { + "type": "str", + "no_log": False, + }, + }, + "type": "dict", + }, + "authentication_none": { + "type": "bool", + }, + "authentication_sha": { + "options": { + "key": { + "type": "str", + "no_log": False, + }, + "password": { + "type": "str", + "no_log": False, + }, + }, + "type": "dict", + }, + "name": {"type": "str"}, + "privacy_3des": { + "options": { + "key": { + "type": "str", + "no_log": False, + }, + "password": { + "type": "str", + "no_log": False, + }, + }, + "type": "dict", + }, + "privacy_aes128": { + "options": { + "key": { + "type": "str", + "no_log": False, + }, + "password": { + "type": "str", + "no_log": False, + }, + }, + "type": "dict", + }, + "privacy_des": { + "options": { + "key": { + "type": "str", + "no_log": False, + }, + "password": { + "type": "str", + "no_log": False, + }, + }, + "type": "dict", + }, + "privacy_none": { + "type": "bool", + }, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "remote_engine": { + "elements": "dict", + "options": { + "id": {"type": "str"}, + "users": { + "elements": "dict", + "options": { + "authentication_md5": { + "options": { + "key": { + "type": "str", + "no_log": False, + }, + "password": { + "type": "str", + "no_log": False, + }, + }, + "type": "dict", + }, + "authentication_none": { + "type": "bool", + }, + "authentication_sha": { + "options": { + "key": { + "type": "str", + "no_log": False, + }, + "password": { + "type": "str", + "no_log": False, + }, + }, + "type": "dict", + }, + "name": {"type": "str"}, + "privacy_3des": { + "options": { + "key": { + "type": "str", + "no_log": False, + }, + "password": { + "type": "str", + "no_log": False, + }, + }, + "type": "dict", + }, + "privacy_aes128": { + "options": { + "key": { + "type": "str", + "no_log": False, + }, + "password": { + "type": "str", + "no_log": False, + }, + }, + "type": "dict", + }, + "privacy_des": { + "options": { + "key": { + "type": "str", + "no_log": False, + }, + "password": { + "type": "str", + "no_log": False, + }, + }, + "type": "dict", + }, + "privacy_none": { + "type": "bool", + }, + }, + "type": "list", + }, + }, + "type": "list", + }, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "subagent": { + "options": { + "tcp": { + "options": { + "routing_instances_default": {"type": "bool"}, + "set": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "traceoptions": { + "options": { + "file": { + "options": { + "files": {"type": "int"}, + "match": {"type": "str"}, + "no_world_readable": {"type": "bool"}, + "size": {"type": "int"}, + "world_readable": {"type": "bool"}, + }, + "type": "dict", + }, + "flag": { + "options": { + "all": {"type": "bool"}, + "general": {"type": "bool"}, + "interface_stats": {"type": "bool"}, + "nonvolatile_sets": {"type": "bool"}, + "pdu": {"type": "bool"}, + "protocol_timeouts": {"type": "bool"}, + "routing_socket": {"type": "bool"}, + "subagent": {"type": "bool"}, + "timer": {"type": "bool"}, + "varbind_error": {"type": "bool"}, + }, + "type": "dict", + }, + "memory_trace": { + "options": { + "set": {"type": "bool"}, + "size": {"type": "int"}, + }, + "type": "dict", + }, + "no_remote_trace": {"type": "bool"}, + }, + "type": "dict", + }, + "trap_groups": { + "elements": "dict", + "options": { + "categories": { + "options": { + "authentication": {"type": "bool"}, + "chassis": {"type": "bool"}, + "chassis_cluster": {"type": "bool"}, + "configuration": {"type": "bool"}, + "dot3oam_events": {"type": "bool"}, + "link": {"type": "bool"}, + "otn_alarms": { + "options": { + "oc_lof": {"type": "bool"}, + "oc_lom": {"type": "bool"}, + "oc_los": {"type": "bool"}, + "odu_ais": {"type": "bool"}, + "odu_bbe_threshold": {"type": "bool"}, + "odu_bdi": {"type": "bool"}, + "odu_bdodu_es_threshold": { + "type": "bool", + }, + "odu_lck": {"type": "bool"}, + "odu_oci": {"type": "bool"}, + "odu_rx_aps_change": {"type": "bool"}, + "odu_sd": {"type": "bool"}, + "odu_ses_threshold": {"type": "bool"}, + "odu_sf": {"type": "bool"}, + "odu_ttim": {"type": "bool"}, + "odu_uas_threshold": {"type": "bool"}, + "opu_ptm": {"type": "bool"}, + "otu_ais": {"type": "bool"}, + "otu_bbe_threshold": {"type": "bool"}, + "otu_bdi": {"type": "bool"}, + "otu_es_threshold": {"type": "bool"}, + "otu_fec_deg": {"type": "bool"}, + "otu_fec_exe": {"type": "bool"}, + "otu_iae": {"type": "bool"}, + "otu_sd": {"type": "bool"}, + "otu_ses_threshold": {"type": "bool"}, + "otu_sf": {"type": "bool"}, + "otu_ttim": {"type": "bool"}, + "otu_uas_threshold": {"type": "bool"}, + "set": {"type": "bool"}, + "wavelength_lock": {"type": "bool"}, + }, + "type": "dict", + }, + "remote_operations": {"type": "bool"}, + "rmon_alarm": {"type": "bool"}, + "routing": {"type": "bool"}, + "services": {"type": "bool"}, + "startup": {"type": "bool"}, + "vrrp_events": {"type": "bool"}, + }, + "type": "dict", + }, + "destination_port": {"type": "int"}, + "logical_system": {"elements": "str", "type": "list"}, + "name": {"type": "str"}, + "routing_instance": {"type": "str"}, + "targets": {"elements": "str", "type": "list"}, + "version": { + "choices": ["all", "v1", "v2"], + "type": "str", + }, + }, + "type": "list", + }, + "trap_options": { + "options": { + "agent_address": { + "options": { + "outgoing_interface": {"type": "bool"}, + }, + "type": "dict", + }, + "context_oid": {"type": "bool"}, + "enterprise_oid": {"type": "bool"}, + "logical_system": {"elements": "str", "type": "list"}, + "routing_instance": {"type": "str"}, + "set": {"type": "bool"}, + "source_address": { + "options": { + "address": {"type": "str"}, + "lowest_loopback": {"type": "bool"}, + }, + "type": "dict", + }, + }, + "type": "dict", + }, + "views": { + "elements": "dict", + "options": { + "name": {"type": "str"}, + "oids": { + "elements": "dict", + "options": { + "exclude": {"type": "bool"}, + "include": {"type": "bool"}, + "oid": {"type": "str"}, + }, + "type": "list", + }, + }, + "type": "list", + }, + }, + "type": "dict", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "deleted", + "overridden", + "parsed", + "gathered", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/static_routes/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/static_routes/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/static_routes/static_routes.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/static_routes/static_routes.py new file mode 100644 index 00000000..34c01e8a --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/static_routes/static_routes.py @@ -0,0 +1,90 @@ +# +# -*- 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 junos_static_routes module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class Static_routesArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_static_routes module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "address_families": { + "elements": "dict", + "options": { + "afi": { + "choices": ["ipv4", "ipv6"], + "required": True, + "type": "str", + }, + "routes": { + "elements": "dict", + "options": { + "dest": {"type": "str"}, + "metric": {"type": "int"}, + "next_hop": { + "elements": "dict", + "options": { + "forward_router_address": { + "type": "str", + }, + }, + "type": "list", + }, + }, + "type": "list", + }, + }, + "type": "list", + }, + "vrf": {"type": "str"}, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "rendered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/vlans/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/vlans/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/vlans/vlans.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/vlans/vlans.py new file mode 100644 index 00000000..41eaa8d5 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/argspec/vlans/vlans.py @@ -0,0 +1,65 @@ +# +# -*- 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 junos_vlans module +""" +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +class VlansArgs(object): # pylint: disable=R0903 + """The arg spec for the junos_vlans module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "config": { + "elements": "dict", + "options": { + "description": {}, + "name": {"required": True, "type": "str"}, + "vlan_id": {"type": "int"}, + "l3_interface": {"type": "str"}, + }, + "type": "list", + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "rendered", + "parsed", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acl_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acl_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acl_interfaces/acl_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acl_interfaces/acl_interfaces.py new file mode 100644 index 00000000..556d6f6b --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acl_interfaces/acl_interfaces.py @@ -0,0 +1,164 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2020 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The junos 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 + +from copy import deepcopy + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.acl_interfaces.acl_interfaces import ( + Acl_interfacesArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Acl_interfacesFacts(object): + """The junos 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 populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for acl_interfaces + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg=missing_required_lib("lxml")) + + if not data: + config_filter = """ + + + + """ + data = connection.get_configuration(filter=config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + + resources = data.xpath("configuration/interfaces/interface") + + objs = [] + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + obj = self.render_config(self.generated_spec, xml) + if obj: + objs.append(obj) + + facts = {} + if objs: + facts["acl_interfaces"] = [] + # Included for compatibility, remove after 2025-07-01 + facts["junos_acl_interfaces"] = [] + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + for cfg in params["config"]: + facts["acl_interfaces"].append(utils.remove_empties(cfg)) + # Included for compatibility, remove after 2025-07-01 + facts["junos_acl_interfaces"].append(utils.remove_empties(cfg)) + + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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["access_groups"] = [] + + if "unit" in conf["interface"] and "family" in conf["interface"]["unit"]: + for family in conf["interface"]["unit"]["family"].keys(): + access_groups = { + "afi": "ipv6" if family == "inet6" else "ipv4", + "acls": [], + } + if conf["interface"]["unit"]["family"][family] is not None and conf["interface"][ + "unit" + ]["family"][family].get( + "filter", + ): + for direction in ["input-list", "output-list"]: + rendered_direction = "in" if direction == "input-list" else "out" + if conf["interface"]["unit"]["family"][family]["filter"].get(direction): + acl_name = conf["interface"]["unit"]["family"][family]["filter"][ + direction + ] + if not isinstance(acl_name, list): + acl_name = [acl_name] + for filter_name in acl_name: + access_groups["acls"].append( + { + "name": filter_name, + "direction": rendered_direction, + }, + ) + if access_groups["acls"]: + config["name"] = conf["interface"]["name"] + config["access_groups"].append(access_groups) + + return utils.remove_empties(config) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acls/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acls/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acls/acls.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acls/acls.py new file mode 100644 index 00000000..d8a04f57 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/acls/acls.py @@ -0,0 +1,245 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2020 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The junos 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 + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.acls.acls import ( + AclsArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class AclsFacts(object): + """The junos 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 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 HAS_LXML: + self._module.fail_json(msg=missing_required_lib("lxml")) + + if not data: + config_filter = """ + + + + """ + data = connection.get_configuration(filter=config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + + resources = data.xpath("configuration/firewall") + + objs = [] + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + for family, sub_dict in xml["firewall"]["family"].items(): + sub_dict["family"] = family + obj = self.render_config( + self.generated_spec, + dict(firewall=sub_dict), + ) + if obj: + objs.append(obj) + + facts = {"acls": []} + if objs: + 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 _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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["afi"] = "ipv6" if conf["firewall"].pop("family") == "inet6" else "ipv4" + acls = conf.get("firewall").get("filter") + if not isinstance(acls, list): + acls = [acls] + config["acls"] = [] + for acl in acls: + acl_dict = {"name": acl["name"], "aces": []} + if acl.get("term"): + terms = acl["term"] + if not isinstance(terms, list): + terms = [terms] + for term in terms: + ace = {"name": term.get("name")} + if term.get("from"): + if term["from"].get("source-address"): + ace["source"] = ace.get("source", {}) + source_address = term["from"].get("source-address") + if not isinstance(source_address, list): + ace["source"]["address"] = source_address["name"] + else: + ace["source"]["address"] = [] + for address in source_address: + ace["source"]["address"].append( + address["name"], + ) + if term["from"].get("source-prefix-list"): + ace["source"] = ace.get("source", {}) + ace["source"]["prefix_list"] = term["from"]["source-prefix-list"] + if term["from"].get("source-port"): + ace["source"] = ace.get("source", {}) + ace["source"]["port_protocol"] = dict( + eq=term["from"]["source-port"], + ) + if term["from"].get("destination-address"): + ace["destination"] = ace.get("destination", {}) + destination_address = term["from"].get( + "destination-address", + ) + if not isinstance(destination_address, list): + ace["destination"]["address"] = destination_address["name"] + else: + ace["destination"]["address"] = [] + for address in destination_address: + ace["destination"]["address"].append( + address["name"], + ) + if term["from"].get("destination-prefix-list"): + ace["destination"] = ace.get("destination", {}) + ace["destination"]["prefix_list"] = term["from"][ + "destination-prefix-list" + ] + if term["from"].get("destination-port"): + ace["destination"] = ace.get("destination", {}) + ace["destination"]["port_protocol"] = dict( + eq=term["from"]["destination-port"], + ) + if term["from"].get("protocol"): + ace["protocol"] = term["from"]["protocol"] + if term["from"].get("icmp-type"): + ace["protocol_options"] = dict(icmp={}) + icmp_type = term["from"]["icmp-type"] + if icmp_type == "echo-reply": + ace["protocol_options"]["icmp"]["echo_reply"] = True + if icmp_type == "echo-request": + ace["protocol_options"]["icmp"]["echo"] = True + if icmp_type == "redirect": + ace["protocol_options"]["icmp"]["redirect"] = True + if icmp_type == "router-advertisement": + ace["protocol_options"]["icmp"]["router_advertisement"] = True + if icmp_type == "router-solicit": + ace["protocol_options"]["icmp"]["router_solicitation"] = True + if icmp_type == "time-exceeded": + ace["protocol_options"]["icmp"]["time_exceeded"] = True + if term["from"].get("icmp-code"): + ace["protocol_options"] = dict(icmp={}) + icmp_code = term["from"]["icmp-code"] + if icmp_code == "destination-host-prohibited": + ace["protocol_options"]["icmp"]["dod_host_prohibited"] = True + if icmp_code == "destination-host-unknown": + ace["protocol_options"]["icmp"]["host_unknown"] = True + if icmp_code == "destination-network-prohibited": + ace["protocol_options"]["icmp"]["dod_net_prohibited"] = True + if icmp_code == "destination-network-unknown": + ace["protocol_options"]["icmp"]["network_unknown"] = True + if icmp_code == "host-unreachable": + ace["protocol_options"]["icmp"]["host_unreachable"] = True + if icmp_code == "host-unreachable-for-tos": + ace["protocol_options"]["icmp"]["host_tos_unreachable"] = True + if icmp_code == "port-unreachable": + ace["protocol_options"]["icmp"]["port_unreachable"] = True + if icmp_code == "protocol-unreachable": + ace["protocol_options"]["icmp"]["protocol_unreachable"] = True + if icmp_code == "redirect-for-host": + ace["protocol_options"]["icmp"]["host_redirect"] = True + if icmp_code == "redirect-for-network": + ace["protocol_options"]["icmp"]["net_redirect"] = True + if icmp_code == "redirect-for-tos-and-host": + ace["protocol_options"]["icmp"]["host_tos_redirect"] = True + if icmp_code == "redirect-for-tos-and-net": + ace["protocol_options"]["icmp"]["net_tos_redirect"] = True + if icmp_code == "source-route-failed": + ace["protocol_options"]["icmp"]["source_route_failed"] = True + if icmp_code == "ttl-eq-zero-during-reassembly": + ace["protocol_options"]["icmp"]["reassembly-timeout"] = True + if icmp_code == "ttl-eq-zero-during-transit": + ace["protocol_options"]["icmp"]["ttl_exceeded"] = True + if term.get("then"): + if "accept" in term["then"]: + ace["grant"] = "permit" + if "discard" in term["then"]: + ace["grant"] = "deny" + acl_dict["aces"].append(ace) + config["acls"].append(acl_dict) + return utils.remove_empties(config) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_address_family/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_address_family/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_address_family/bgp_address_family.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_address_family/bgp_address_family.py new file mode 100644 index 00000000..70cc0b1c --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_address_family/bgp_address_family.py @@ -0,0 +1,741 @@ +# +# -*- 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 junos bgp_address_family 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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.bgp_address_family.bgp_address_family import ( + Bgp_address_familyArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Bgp_address_familyFacts(object): + """The junos bgp_address_family fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Bgp_address_familyArgs.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_device_data(self, connection, config_filter): + """ + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for bgp_address_family + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + + + + + """ + data = self.get_device_data(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + objs = {} + resources = data.xpath("configuration/protocols/bgp") + autonomous_system_path = data.xpath( + "configuration/routing-options/autonomous-system", + ) + if autonomous_system_path: + self.autonomous_system = self._get_xml_dict( + autonomous_system_path.pop(), + ) + else: + self.autonomous_system = "" + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + + facts = {} + if objs: + facts["bgp_address_family"] = {} + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + facts["bgp_address_family"] = utils.remove_empties( + params["config"], + ) + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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 + """ + bgp_af_config = {} + + # Parse facts for BGP address-family global node + conf = conf.get("bgp") + bgp_af_config["address_family"] = self.parse_af_facts(conf) + + # Parse BGP group address-family config node + if "group" in conf.keys(): + groups = conf.get("group") + groups_af_lst = [] + group_af_dict = {} + if isinstance(groups, list): + for group in groups: + af_facts = self.parse_af_facts(group) + if af_facts is not None: + group_af_dict["address_family"] = af_facts + # Parse neighbors af node + if "neighbor" in group.keys(): + neighbors_af_lst = [] + nh_af_dict = {} + neighbors = group.get("neighbor") + if isinstance(neighbors, list): + for neighbor in neighbors: + # nh_af_dict["name"] = neighbor.get("neighbor_address") + naf_facts = self.parse_af_facts(neighbor) + if naf_facts is not None: + nh_af_dict["address_family"] = naf_facts + nh_af_dict["neighbor_address"] = neighbor.get("name") + if nh_af_dict: + neighbors_af_lst.append(nh_af_dict) + nh_af_dict = {} + else: + naf_facts = self.parse_af_facts(neighbors) + if naf_facts is not None: + nh_af_dict["address_family"] = naf_facts + nh_af_dict["neighbor_address"] = neighbors.get( + "name", + ) + if nh_af_dict: + neighbors_af_lst.append(nh_af_dict) + if neighbors_af_lst: + group_af_dict["neighbors"] = neighbors_af_lst + if group_af_dict: + group_af_dict["name"] = group.get("name") + groups_af_lst.append(group_af_dict) + group_af_dict = {} + else: + af_facts = self.parse_af_facts(groups) + if af_facts is not None: + group_af_dict["address_family"] = af_facts + # Parse neighbors af node + if "neighbor" in groups.keys(): + neighbors_af_lst = [] + nh_af_dict = {} + neighbors = groups.get("neighbor") + if isinstance(neighbors, list): + for neighbor in neighbors: + # nh_af_dict["name"] = neighbor.get("name") + naf_facts = self.parse_af_facts(neighbor) + if naf_facts is not None: + nh_af_dict["address_family"] = naf_facts + nh_af_dict["neighbor_address"] = neighbor.get( + "name", + ) + if nh_af_dict: + neighbors_af_lst.append(nh_af_dict) + nh_af_dict = {} + else: + naf_facts = self.parse_af_facts(neighbors) + if naf_facts is not None: + nh_af_dict["address_family"] = naf_facts + nh_af_dict["neighbor_address"] = neighbors.get( + "name", + ) + if nh_af_dict: + neighbors_af_lst.append(nh_af_dict) + if neighbors_af_lst: + group_af_dict["neighbors"] = neighbors_af_lst + if group_af_dict: + group_af_dict["name"] = groups.get("name") + groups_af_lst.append(group_af_dict) + if groups_af_lst is not None: + bgp_af_config["groups"] = groups_af_lst + + return utils.remove_empties(bgp_af_config) + + def parse_af_facts(self, conf): + """ + + :return: + """ + nlri_params = [ + "evpn", + "inet", + "inet-mdt", + "inet-mvpn", + "inet-vpn", + "inet6", + "inet6-mvpn", + "inet6-vpn", + "iso-vpn", + "l2vpn", + "traffic-engineering", + ] + # TBD wrap route-target' + nlri_types = [ + "any", + "flow", + "multicast", + "labeled-unicast", + "segment-routing-te", + "unicast", + "signaling", + ] + bgp = conf.get("family") + address_family = [] + # Parse NLRI Parameters + for param in nlri_params: + af_dict = {} + if bgp and param in bgp.keys(): + af_type = [] + nlri_param = bgp.get(param) + for nlri in nlri_types: + af_dict["afi"] = param + if nlri in nlri_param.keys(): + nlri_dict = self.parse_nlri(nlri_param, nlri) + if nlri_dict: + af_type.append(nlri_dict) + if af_type: + af_dict["af_type"] = af_type + if af_dict: + address_family.append(af_dict) + + return address_family + + def parse_nlri(self, cfg, nlri_t): + """ + + :param cfg: + :return: + """ + nlri_dict = {} + if cfg and nlri_t in cfg.keys(): + nlri_dict["type"] = nlri_t + nlri = cfg.get(nlri_t) + + if not nlri: + nlri_dict["set"] = True + return nlri_dict + # Parse accepted-prefix-limit + if "accepted-prefix-limit" in nlri.keys(): + apl_dict = self.parse_accepted_prefix_limit(nlri) + # populate accepted_prefix_limit + if apl_dict: + nlri_dict["accepted_prefix_limit"] = apl_dict + + # Parse add-path + if "add-path" in nlri.keys(): + ap_dict = self.parse_add_path(nlri) + # populate accepted_prefix_limit + if ap_dict: + nlri_dict["add_path"] = ap_dict + + # Parse aggregate-label + if "aggregate-label" in nlri.keys(): + al_dict = self.parse_aggregate_label(nlri) + # populate aggregate-label + if apl_dict: + nlri_dict["aggregate_label"] = al_dict + + # Parse aigp + if "aigp" in nlri.keys(): + aigp_dict = self.parse_aigp(nlri) + # populate aigp + if aigp_dict: + nlri_dict["aigp"] = aigp_dict + + # Parse and populate damping + if "damping" in nlri.keys(): + nlri_dict["damping"] = True + + # Parse defer-initial-multipath-build + if "defer-initial-multipath-build" in nlri.keys(): + dimb_dict = self.parse_defer_initial_multipath_build(nlri) + # populate defer_initial_multipath_build + if dimb_dict: + nlri_dict["defer_initial_multipath_build"] = dimb_dict + + # Parse delay-route-advertisements + if "delay-route-advertisements" in nlri.keys(): + dra_dict = self.parse_delay_route_advertisements(nlri) + # populate delay_route_advertisements + if dra_dict: + nlri_dict["delay_route_advertisements"] = dra_dict + + # Parse entropy-label + if "entropy-label" in nlri.keys(): + el_dict = self.parse_entropy_label(nlri) + # populate entropy-label + if el_dict: + nlri_dict["entropy_label"] = el_dict + + # Parse explicit-null + if "explicit-null" in nlri.keys(): + en_dict = self.parse_explicit_null(nlri) + # populate explicit-null + if en_dict: + nlri_dict["explicit_null"] = en_dict + + # Parse extended-nexthop + if "extended-nexthop" in nlri.keys(): + nlri_dict["extended_nexthop"] = True + + # Parse extended-nexthop-color + if "extended-nexthop-color" in nlri.keys(): + nlri_dict["extended_nexthop_color"] = True + + # Parse forwarding-state-bit + if "graceful-restart" in nlri.keys(): + gr = nlri.get("graceful-restart") + if "forwarding-state-bit" in gr.keys(): + fsb = gr.get("forwarding-state-bit") + nlri_dict["graceful_restart_forwarding_state_bit"] = fsb + + # Parse legacy-redirect-ip-action + if "legacy-redirect-ip-action" in nlri.keys(): + lria_dict = self.parse_legacy_redirect_ip_action(nlri) + # populate legacy_redirect_ip_action + if lria_dict: + nlri_dict["legacy_redirect_ip_action"] = lria_dict + + # Parse local-ipv4-address + if "local-ipv4-address" in nlri.keys(): + nlri_dict["local_ipv4_address"] = nlri.get( + "local-ipv4-address", + ) + + # Parse loops + if "loops" in nlri.keys(): + loops = nlri.get("loops") + nlri_dict["loops"] = loops.get("loops") + + # Parse no-install + if "no-install" in nlri.keys(): + nlri_dict["no_install"] = True + + # Parse no-validate + if "no-validate" in nlri.keys(): + nlri_dict["no_validate"] = nlri.get("no-validate") + + # Parse output-queue-priority + if "output-queue-priority" in nlri.keys(): + oqp = nlri.get("output-queue-priority") + if "expedited" in oqp.keys(): + nlri_dict["output_queue_priority_expedited"] = True + if "priority" in oqp.keys(): + nlri_dict["output_queue_priority_priority"] = oqp.get( + "priority", + ) + + # Parse per-group-label + if "per-group-label" in nlri.keys(): + nlri_dict["per_group_label"] = True + + # Parse per-prefix-label + if "per-prefix-label" in nlri.keys(): + nlri_dict["per_prefix_label"] = True + + # Parse resolve-vpn + if "resolve-vpn" in nlri.keys(): + nlri_dict["resolve_vpn"] = True + + # Parse prefix-limit + if "prefix-limit" in nlri.keys(): + pl_dict = self.parse_accepted_prefix_limit(nlri) + # populate delay_route_advertisements + if pl_dict: + nlri_dict["prefix_limit"] = pl_dict + + # Parse resolve-vpn + if "resolve-vpn" in nlri.keys(): + nlri_dict["resolve_vpn"] = True + + # Parse rib + if "rib" in nlri.keys(): + nlri_dict["rib"] = "inet.3" + + # Parse rib-group + if "rib-group" in nlri.keys(): + nlri_dict["rib_group"] = nlri.get("rib-group") + + # Parse route-refresh-priority + if "route-refresh-priority" in nlri.keys(): + oqp = nlri.get("route-refresh-priority") + if "expedited" in oqp.keys(): + nlri_dict["route_refresh_priority_expedited"] = True + if "priority" in oqp.keys(): + nlri_dict["route_refresh_priority_priority"] = oqp.get( + "priority", + ) + + # Parse secondary-independent-resolution + if "secondary-independent-resolution" in nlri.keys(): + nlri_dict["secondary_independent_resolution"] = True + + # Parse strip-nexthop + if "strip-nexthop" in nlri.keys(): + nlri_dict["strip_nexthop"] = True + + # Parse topology + if "topology" in nlri.keys(): + t_list = self.parse_topology(nlri) + # populate topology + if t_list: + nlri_dict["topology"] = t_list + + # Parse traffic-statistics + if "traffic-statistics" in nlri.keys(): + ts_dict = self.parse_traffic_statistics(nlri) + # populate topology + if ts_dict: + nlri_dict["traffic_statistics"] = ts_dict + + # Parse withdraw-priority + if "withdraw-priority" in nlri.keys(): + oqp = nlri.get("withdraw-priority") + if "expedited" in oqp.keys(): + nlri_dict["withdraw_priority_expedited"] = True + if "priority" in oqp.keys(): + nlri_dict["withdraw_priority_priority"] = oqp.get( + "priority", + ) + return nlri_dict + + def parse_accepted_prefix_limit(self, cfg): + """ + + :param self: + :param cfg: + :return: + """ + apl_dict = {} + if "accepted-prefix-limit" in cfg.keys(): + apl = cfg.get("accepted-prefix-limit") + else: + apl = cfg.get("prefix-limit") + if "maximum" in apl.keys(): + apl_dict["maximum"] = apl.get("maximum") + if "teardown" in apl.keys(): + if not apl.get("teardown"): + apl_dict["teardown"] = True + else: + td = apl.get("teardown") + if "idle-timeout" in td.keys(): + if not td.get("idle-timeout"): + apl_dict["idle_timeout"] = True + elif "forever" in td["idle-timeout"].keys(): + apl_dict["forever"] = True + elif "timeout" in td["idle-timeout"].keys(): + apl_dict["idle_timeout_value"] = td["idle-timeout"].get("timeout") + if "limit-threshold" in td.keys(): + apl_dict["limit_threshold"] = td.get("limit-threshold") + return apl_dict + + def parse_add_path(self, cfg): + """ + + :param self: + :param cfg: + :return: + """ + ap_dict = {} + ap = cfg.get("add-path") + if "receive" in ap.keys(): + ap_dict["receive"] = True + if "send" in ap.keys(): + send = ap.get("send") + s_dict = {} + if "include-backup-path" in send.keys(): + s_dict["include_backup_path"] = send.get("include-backup-path") + if "path-count" in send.keys(): + s_dict["path_count"] = send.get("path-count") + if "multipath" in send.keys(): + s_dict["multipath"] = True + if "path-selection-mode" in send.keys(): + psm = send.get("path-selection-mode") + psm_dict = {} + if "all-paths" in psm.keys(): + psm_dict["all_paths"] = True + if "equal-cost-paths" in psm.keys(): + psm_dict["equal_cost_paths"] = True + s_dict["path_selection_mode"] = psm_dict + if "prefix-policy" in send.keys(): + s_dict["prefix_policy"] = send.get("prefix-policy") + ap_dict["send"] = s_dict + return ap_dict + + def parse_aggregate_label(self, cfg): + """ + + :param self: + :param cfg: + :return: + """ + al_dict = {} + al = cfg.get("aggregate-label") + if not al: + al_dict["set"] = True + else: + al_dict["community"] = al.get("community") + return al_dict + + def parse_aigp(self, cfg): + """ + + :param self: + :param cfg: + :return: + """ + aigp_dict = {} + aigp = cfg.get("aigp") + if aigp and "disable" in aigp.keys(): + aigp_dict["disable"] = True + else: + aigp_dict["set"] = True + return aigp_dict + + def parse_defer_initial_multipath_build(self, cfg): + """ + + :param self: + :param cfg: + :return: + """ + dimb_dict = {} + dimb = cfg.get("defer-initial-multipath-build") + if not dimb: + dimb_dict["set"] = True + + elif "maximum-delay" in dimb.keys(): + dimb_dict["maximum_delay"] = dimb.get("maximum-delay") + return dimb_dict + + def parse_legacy_redirect_ip_action(self, cfg): + """ + + :param self: + :param cfg: + :return: + """ + lria_dict = {} + lria = cfg.get("legacy-redirect-ip-action") + if not lria: + lria_dict["set"] = True + else: + if "send" in lria.keys(): + lria_dict["send"] = True + if "receive" in lria.keys(): + lria_dict["receive"] = True + return lria_dict + + def parse_delay_route_advertisements(self, cfg): + """ + + :param self: + :param cfg: + :return: + """ + dra_dict = {} + dra = cfg.get("delay-route-advertisements") + if not dra: + dra_dict["set"] = True + else: + if "maximum-delay" in dra.keys(): + mxd = dra.get("maximum-delay") + if "route-age" in mxd.keys(): + dra_dict["max_delay_route_age"] = mxd.get("route-age") + if "routing-uptime" in mxd.keys(): + dra_dict["max_delay_routing_uptime"] = mxd.get( + "routing-uptime", + ) + if "minimum-delay" in dra.keys(): + mid = dra.get("minimum-delay") + if "inbound-convergence" in mid.keys(): + dra_dict["min_delay_inbound_convergence"] = mid.get( + "inbound-convergence", + ) + if "routing-uptime" in mid.keys(): + dra_dict["min_delay_routing_uptime"] = mid.get( + "routing-uptime", + ) + return dra_dict + + def parse_entropy_label(self, cfg): + """ + + :param self: + :param cfg: + :return: + """ + el_dict = {} + el = cfg.get("entropy-label") + if not el: + el_dict["set"] = True + else: + if "import" in el.keys(): + el_dict["import"] = el.get("import") + if "no-next-hop-validation" in el.keys(): + el_dict["no_next_hop_validation"] = True + return el_dict + + def parse_explicit_null(self, cfg): + """ + + :param self: + :param cfg: + :return: + """ + en_dict = {} + en = cfg.get("explicit-null") + if not en: + en_dict["set"] = True + elif "connected-only" in en.keys(): + en_dict["connected_only"] = True + return en_dict + + def parse_topology(self, cfg): + """ + + :param self: + :param cfg: + :return: + """ + top_dict = {} + topology_list = [] + topologies = cfg.get("topology") + if isinstance(topologies, list): + for topology in topologies: + top_dict["name"] = topology["name"] + communities = topology.get("community") + community_lst = [] + if isinstance(communities, list): + for community in communities: + community_lst.append(community) + else: + community_lst.append(communities) + if community_lst is not None: + top_dict["community"] = community_lst + if top_dict is not None: + topology_list.append(top_dict) + top_dict = {} + else: + top_dict["name"] = topologies["name"] + communities = topologies.get("community") + community_lst = [] + if isinstance(communities, list): + for community in communities: + community_lst.append(community) + else: + community_lst.append(communities) + if community_lst is not None: + top_dict["community"] = community_lst + if top_dict is not None: + topology_list.append(top_dict) + return topology_list + + def parse_traffic_statistics(self, cfg): + """ + + :param self: + :param cfg: + :return: + """ + ts_dict = {} + ts = cfg.get("traffic-statistics") + if not ts: + ts_dict["set"] = True + else: + if "interval" in ts.keys(): + ts_dict["interval"] = ts.get("interval") + if "labeled-path" in ts.keys(): + ts_dict["labeled_path"] = True + if "file" in ts.keys(): + file = ts.get("file") + file_dict = {} + if "files" in file.keys(): + file_dict["files"] = file.get("files") + if "no-world-readable" in file.keys(): + file_dict["no_world_readable"] = True + if "size" in file.keys(): + file_dict["size"] = file.get("size") + if "world-readable" in file.keys(): + file_dict["world_readable"] = True + + return ts_dict diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_global/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_global/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_global/bgp_global.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_global/bgp_global.py new file mode 100644 index 00000000..cedab029 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/bgp_global/bgp_global.py @@ -0,0 +1,1089 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2020 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The junos bgp_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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + generate_dict, + remove_empties, +) + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.bgp_global.bgp_global import ( + Bgp_globalArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.utils.utils import ( + _validate_config, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Bgp_globalFacts(object): + """The junos bgp_global fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Bgp_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 = generate_dict(facts_argument_spec) + + def get_device_data(self, connection, config_filter): + """ + + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for bgp_global + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + + + + + """ + data = self.get_device_data(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + objs = {} + resources = data.xpath("configuration/protocols/bgp") + autonomous_system_path = data.xpath( + "configuration/routing-options/autonomous-system", + ) + if autonomous_system_path: + self.autonomous_system = self._get_xml_dict( + autonomous_system_path.pop(), + ) + else: + self.autonomous_system = "" + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + if not objs: + if self.autonomous_system and self.autonomous_system.get( + "autonomous-system", + ): + objs["as_number"] = self.autonomous_system["autonomous-system"].get("as-number") + if self.autonomous_system["autonomous-system"].get("loops"): + objs["loops"] = self.autonomous_system["autonomous-system"].get("loops") + if "asdot-notation" in self.autonomous_system["autonomous-system"]: + objs["asdot_notation"] = True + facts = {} + if objs: + facts["bgp_global"] = {} + params = _validate_config( + self._module, + self.argument_spec, + {"config": objs}, + redact=True, + ) + facts["bgp_global"] = remove_empties(params["config"]) + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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 + """ + bgp_global = {} + bgp = conf.get("bgp") + # Set ASN value into facts + if self.autonomous_system and self.autonomous_system.get( + "autonomous-system", + ): + bgp_global["as_number"] = self.autonomous_system["autonomous-system"].get("as-number") + if self.autonomous_system["autonomous-system"].get("loops"): + bgp_global["loops"] = self.autonomous_system["autonomous-system"].get("loops") + if "asdot-notation" in self.autonomous_system["autonomous-system"]: + bgp_global["asdot_notation"] = True + + self.parse_attrib(bgp_global, bgp) + + # Read group + if "group" in bgp.keys(): + bgp_groups = [] + bgp_group = {} + groups = bgp.get("group") + if isinstance(groups, dict): + self.parse_attrib(bgp_group, groups) + # parse neighbors + if "neighbor" in groups.keys(): + neighbors_lst = [] + neighbors_dict = {} + neighbors = groups.get("neighbor") + if isinstance(neighbors, dict): + self.parse_attrib( + neighbors_dict, + neighbors, + "neighbor", + ) + if neighbors_dict: + neighbors_lst.append(neighbors_dict) + else: + for neighbor in neighbors: + self.parse_attrib( + neighbors_dict, + neighbor, + "neighbor", + ) + if neighbors_dict: + neighbors_lst.append(neighbors_dict) + neighbors_dict = {} + if neighbors_lst: + bgp_group["neighbors"] = neighbors_lst + + if bgp_group: + bgp_groups.append(bgp_group) + else: + for group in groups: + bgp_group = {} + self.parse_attrib(bgp_group, group) + # Parse neighbors in the group list + if "neighbor" in group.keys(): + neighbors_lst = [] + neighbors_dict = {} + neighbors = group.get("neighbor") + if isinstance(neighbors, dict): + self.parse_attrib( + neighbors_dict, + neighbors, + "neighbor", + ) + if neighbors_dict: + neighbors_lst.append(neighbors_dict) + else: + for neighbor in neighbors: + self.parse_attrib( + neighbors_dict, + neighbor, + "neighbor", + ) + if neighbors_dict: + neighbors_lst.append(neighbors_dict) + neighbors_dict = {} + + if neighbors_lst: + bgp_group["neighbors"] = neighbors_lst + + if bgp_group: + bgp_groups.append(bgp_group) + bgp_global["groups"] = bgp_groups + remove_empties(bgp_global) + return bgp_global + + def parse_attrib(self, cfg_dict, conf, type=None): + # Read accept-remote-nexthop value + if "accept-remote-nexthop" in conf.keys(): + cfg_dict["accept_remote_nexthop"] = True + + # Read add-path-display-ipv4-address value + if "add-path-display-ipv4-address" in conf.keys(): + cfg_dict["add_path_display_ipv4_address"] = True + + # Parse advertise-bgp-static dictionary + if "advertise-bgp-static" in conf.keys(): + cfg = {} + if conf.get("advertise-bgp-static") and "advertise-bgp-static" in conf.keys(): + if "policy" in conf["advertise-bgp-static"]: + cfg["policy"] = conf["advertise-bgp-static"].get("policy") + else: + cfg["set"] = True + cfg_dict["advertise_bgp_static"] = cfg + + # Parse advertise-external dictionary + if "advertise-external" in conf.keys(): + cfg = {} + if ( + isinstance(conf.get("advertise-external"), dict) + and "conditional" in conf["advertise-external"].keys() + ): + cfg["conditional"] = True + else: + cfg["set"] = True + cfg_dict["advertise_external"] = cfg + + # Read advertise-from-main-vpn-tables value + if "advertise-from-main-vpn-tables" in conf.keys(): + cfg_dict["advertise_from_main_vpn_tables"] = True + + # Read advertise-inactive value + if "advertise-inactive" in conf.keys(): + cfg_dict["advertise_inactive"] = True + + # Read advertise-peer-as value + if "advertise-peer-as" in conf.keys(): + cfg_dict["advertise_peer_as"] = True + + # Read authentication-algorithm value + if "authentication-algorithm" in conf.keys(): + cfg_dict["authentication_algorithm"] = conf["authentication-algorithm"] + + # Read authentication-key value + if "authentication-key" in conf.keys(): + cfg_dict["authentication_key"] = conf["authentication-key"] + + # Read authentication-key-chain value + if "authentication-key-chain" in conf.keys(): + cfg_dict["authentication_key_chain"] = conf["authentication-key-chain"] + + # Parse bfd-liveness-detection dictionary + if "bfd-liveness-detection" in conf.keys(): + cfg = {} + bld = conf["bfd-liveness-detection"] + # Parse authentication dictionary + if "authentication" in bld.keys(): + a_dict = {} + authentication = bld["authentication"] + if "algorithm" in authentication.keys(): + a_dict["algorithm"] = authentication["algorithm"] + if "key-chain" in authentication.keys(): + a_dict["key_chain"] = authentication["key-chain"] + if "loose-check" in authentication.keys(): + a_dict["loose_check"] = True + cfg["authentication"] = a_dict + + # Parse detection-time dictionary + if "detection-time" in bld.keys(): + dt_dict = {} + d_time = bld["detection-time"] + if "threshold" in d_time.keys(): + dt_dict["threshold"] = d_time["threshold"] + cfg["detection_time"] = dt_dict + # Parse transmit-interval dictionary + if "transmit-interval" in bld.keys(): + t_dict = {} + t_int = bld["transmit-interval"] + if "minimum-interval" in t_int.keys(): + t_dict["minimum_interval"] = t_int["minimum-interval"] + cfg["transmit_interval"] = t_dict + + # Read holddown-interval value + if "holddown-interval" in bld.keys(): + cfg["holddown_interval"] = bld["holddown-interval"] + + # Read minimum-receive-interval value + if "minimum-receive-interval" in bld.keys(): + cfg["minimum_receive_interval"] = bld["minimum-receive-interval"] + + # Read minimum-interval value + if "minimum-interval" in bld.keys(): + cfg["minimum_interval"] = bld["minimum-interval"] + + # Read multiplier value + if "multiplier" in bld.keys(): + cfg["multiplier"] = bld["multiplier"] + + # Read no-adaptation value + if "no-adaptation" in bld.keys(): + cfg["no_adaptation"] = True + + # Read session-mode value + if "session-mode" in bld.keys(): + cfg["session_mode"] = bld["session-mode"] + + # Read version value + if "version" in bld.keys(): + cfg["version"] = bld["version"] + + # write the bfd_liveness_detection to bgp global config dictionary + cfg_dict["bfd_liveness_detection"] = cfg + + # Parse bgp-error-tolerance dictionary + if "bgp-error-tolerance" in conf.keys(): + cfg = {} + bet = conf["bgp-error-tolerance"] + # Parse authentication dictionary + if "malformed-route-limit" in bet.keys(): + cfg["malformed_route_limit"] = bet["malformed-route-limit"] + if "malformed-update-log-interval" in bet.keys(): + cfg["malformed_update_log_interval"] = bet["malformed-update-log-interval"] + if "no-malformed-route-limit" in bet.keys(): + cfg["no_malformed_route_limit"] = True + # write the bfd_liveness_detection to bgp global config dictionary + cfg_dict["bgp_error_tolerance"] = cfg + + # Parse bmp dictionary + if "bmp" in conf.keys(): + cfg = {} + bmp = conf["bmp"] + # Parse authentication dictionary + if "route-monitoring" in bmp.keys(): + rm_dict = {} + r_monitoring = bmp["route-monitoring"] + + # Read none attribute value + if "none" in r_monitoring.keys(): + rm_dict["none"] = True + + # Read post-policy attribute value + if "post-policy" in r_monitoring.keys(): + if r_monitoring["post-policy"].get("exclude-non-eligible"): + rm_dict["post_policy_exclude_non_eligible"] = True + else: + rm_dict["post_policy"] = True + + # Read pre-policy attribute value + if "pre-policy" in r_monitoring.keys(): + if r_monitoring["pre-policy"].get("exclude-non-feasible"): + rm_dict["pre_policy_exclude_non_feasible"] = True + else: + rm_dict["pre_policy"] = True + cfg["route_monitoring"] = rm_dict + # Read monitor value + if "monitor" in bmp.keys(): + if bmp["monitor"] == "disable": + cfg["monitor"] = False + else: + cfg["monitor"] = True + + # write the bmp to bgp global config dictionary + cfg_dict["bmp"] = cfg + + # Read cluster value + if "cluster" in conf.keys(): + cfg_dict["cluster_id"] = conf["cluster"] + + # Read damping value + if "damping" in conf.keys(): + cfg_dict["damping"] = True + + # Read description value + if "description" in conf.keys(): + cfg_dict["description"] = conf["description"] + + # Read disable value + if "disable" in conf.keys(): + cfg_dict["disable"] = True + + # Read egress-te value + if "egress-te" in conf.keys(): + cfg = {} + if conf.get("egress-te") and "backup-path" in conf["egress-te"].keys(): + cfg["backup_path"] = conf["egress-te"].get("backup-path") + else: + cfg["set"] = True + cfg_dict["egress_te"] = cfg + + # Read egress-te-backup-paths + if "egress-te-backup-paths" in conf.keys(): + cfg = {} + templates_lst = [] + template_dict = {} + templates = conf["egress-te-backup-paths"].get("template") + if isinstance(templates, dict): + template_dict["path_name"] = templates["name"] + if "remote-nexthop" in templates.keys(): + template_dict["remote_nexthop"] = templates["remote-nexthop"].get( + "remote-nh-addr", + ) + if "peer" in templates.keys(): + peer_lst = [] + peers = templates.get("peer") + if isinstance(peers, dict): + peer_lst.append(peers.get("name")) + else: + for peer in peers: + peer_lst.append(peer.get("name")) + template_dict["peers"] = peer_lst + + if "ip-forward" in templates.keys(): + ipf_dict = {} + if templates.get("ip-forward") is None: + ipf_dict["set"] = True + else: + ipf_dict["rti_name"] = templates["ip-forward"].get( + "rti-name", + ) + template_dict["ip_forward"] = ipf_dict + if template_dict: + templates_lst.append(template_dict) + else: + # We have list of templates + for template in templates: + template_dict = {} + template_dict["path_name"] = template["name"] + if "remote-nexthop" in template.keys(): + template_dict["remote_nexthop"] = template["remote-nexthop"].get( + "remote-nh-addr", + ) + if "peer" in template.keys(): + peer_lst = [] + peers = template.get("peer") + if isinstance(peers, dict): + peer_lst.append(peers.get("name")) + else: + for peer in peers: + peer_lst.append(peer.get("name")) + template_dict["peers"] = peer_lst + if "ip-forward" in template.keys(): + ipf_dict = {} + if template.get("ip-forward") is None: + ipf_dict["set"] = True + else: + ipf_dict["rti_name"] = template["ip-forward"].get( + "rti-name", + ) + template_dict["ip_forward"] = ipf_dict + + if template_dict: + templates_lst.append(template_dict) + + if templates: + cfg["templates"] = templates_lst + cfg_dict["egress_te_backup_paths"] = cfg + + # Read egress-te-set-segment + if "egress-te-set-segment" in conf.keys(): + etss_lst = [] + etss_dict = {} + etsss = conf["egress-te-set-segment"] + if isinstance(etsss, dict): + etss_dict["name"] = etsss.get("name") + if "label" in etsss.keys(): + etss_dict["label"] = etsss["label"].get("label-value") + if "egress-te-backup-segment" in etsss.keys(): + etbs = etsss.get("egress-te-backup-segment") + etss_dict["egress_te_backup_segment_label"] = etbs["label"].get("label-value") + + if etss_dict: + etss_lst.append(etss_dict) + else: + for etss in etsss: + etss_dict["name"] = etss.get("name") + if "label" in etss.keys(): + etss_dict["label"] = etss["label"].get("label-value") + if "egress-te-backup-segment" in etss.keys(): + etbs = etss.get("egress-te-backup-segment") + etss_dict["egress_te_backup_segment_label"] = etbs["label"].get( + "label-value", + ) + + if etss_dict: + etss_lst.append(etss_dict) + etss_dict = {} + cfg_dict["egress_te_set_segment"] = etss_lst + + # Read egress-te-sid-stats value + if "egress-te-sid-stats" in conf.keys(): + cfg_dict["egress_te_sid_stats"] = True + + # Read enforce-first-as value + if "enforce-first-as" in conf.keys(): + cfg_dict["enforce_first_as"] = True + + # Read export value + if "export" in conf.keys(): + cfg_dict["export"] = conf["export"] + + # Read forwarding-context value + if "forwarding-context" in conf.keys(): + cfg_dict["forwarding_context"] = conf["forwarding-context"] + + # Read graceful-restart + if "graceful-restart" in conf.keys(): + cfg = {} + gr = conf.get("graceful-restart") + if gr is None: + cfg["set"] = True + else: + if "disable" in gr.keys(): + cfg["disable"] = True + if "dont-help-shared-fate-bfd-down" in gr.keys(): + cfg["dont_help_shared_fate_bfd_down"] = True + # read forwarding-state-bit + if "forwarding-state-bit" in gr.keys(): + fsb_dict = {} + if "as-rr-client" == gr.get("forwarding-state-bit"): + fsb_dict["as_rr_client"] = True + if "from-fib" == gr.get("forwarding-state-bit"): + fsb_dict["from_fib"] = True + cfg["forwarding_state_bit"] = fsb_dict + # read long-lived + if "long-lived" in gr.keys(): + ll_dict = {} + ll = gr.get("long-lived") + # read advertise_to_non_llgr_neighbor + if "advertise-to-non-llgr-neighbor" in ll.keys(): + atnln_dict = {} + atnln = ll.get("advertise-to-non-llgr-neighbor") + if atnln is None: + atnln_dict["set"] = True + else: + atnln_dict["omit_no_export"] = True + ll_dict["advertise_to_non_llgr_neighbor"] = atnln_dict + if "receiver" in ll.keys(): + ll_dict["receiver_disable"] = True + cfg["long_lived"] = ll_dict + # read restart-time + if "restart-time" in gr.keys(): + cfg["restart_time"] = gr.get("restart-time") + # read stale-routes-time + if "stale-routes-time" in gr.keys(): + cfg["stale_routes_time"] = gr.get("stale-routes-time") + + cfg_dict["graceful_restart"] = cfg + + # Read hold-time value + if "hold-time" in conf.keys(): + cfg_dict["hold_time"] = conf["hold-time"] + + # Read holddown-all-stale-labels value + if "holddown-all-stale-labels" in conf.keys(): + cfg_dict["holddown_all_stale_labels"] = True + + # Read idle-after-switch-over + if "idle-after-switch-over" in conf.keys(): + cfg = {} + iaso = conf.get("idle-after-switch-over") + if "forever" in iaso.keys(): + cfg["forever"] = True + else: + cfg["timeout"] = iaso.get("timeout") + cfg_dict["idle_after_switch_over"] = cfg + + # Read import value + if "import" in conf.keys(): + imports = conf.get("import") + import_lst = [] + if isinstance(imports, dict): + import_lst.append(imports) + else: + for entry in imports: + import_lst.append(entry) + cfg_dict["import"] = import_lst + + # Read include-mp-next-hop value + if "include-mp-next-hop" in conf.keys(): + cfg_dict["include_mp_next_hop"] = True + + # Read ipsec-sa value + if "ipsec-sa" in conf.keys(): + cfg_dict["ipsec_sa"] = conf["ipsec-sa"] + + # Read keep value + if "keep" in conf.keys(): + cfg_dict["keep"] = conf["keep"] + + # Read local-address value + if "local-address" in conf.keys(): + cfg_dict["local_address"] = conf["local-address"] + + # Read local_as value + if "local-as" in conf.keys(): + cfg = {} + la = conf.get("local-as") + cfg["as_num"] = la.get("as-number") + if "alias" in la.keys(): + cfg["alias"] = True + if "private" in la.keys(): + cfg["private"] = True + if "loops" in la.keys(): + cfg["loops"] = la.get("loops") + if "no-prepend-global-as" in la.keys(): + cfg["no_prepend_global_as"] = True + cfg_dict["local_as"] = cfg + + # Read local-interface value + if "local-interface" in conf.keys(): + cfg_dict["local_interface"] = conf["local-interface"] + + # Read local-preference value + if "local-preference" in conf.keys(): + cfg_dict["local_preference"] = conf["local-preference"] + + # Read log-updown value + if "log-updown" in conf.keys(): + cfg_dict["log_updown"] = True + + # Read metric-out + if "metric-out" in conf.keys(): + cfg = {} + mo = conf.get("metric-out") + # metric value + if "metric-value" in mo.keys(): + cfg["metric_value"] = mo.get("metric-value") + # read igp + if "igp" in mo.keys(): + igp_dict = {} + igp = mo.get("igp") + if igp is None: + igp_dict["set"] = True + else: + if "metric-offset" in igp.keys(): + igp_dict["metric_offset"] = igp.get("metric-offset") + if "delay-med-update" in igp.keys(): + igp_dict["delay_med_update"] = True + cfg["igp"] = igp_dict + # read minimum-igp + if "minimum-igp" in mo.keys(): + minigp_dict = {} + minigp = mo.get("minimum-igp") + if minigp is None: + minigp_dict["set"] = True + else: + if "metric-offset" in minigp.keys(): + minigp_dict["metric_offset"] = minigp.get( + "metric-offset", + ) + cfg["minimum_igp"] = minigp_dict + cfg_dict["metric_out"] = cfg + + # Read mtu-discovery value + if "mtu-discovery" in conf.keys(): + cfg_dict["mtu_discovery"] = True + + # Read multihop value + if "multihop" in conf.keys(): + cfg = {} + multihop = conf.get("multihop") + if multihop is None: + cfg["set"] = True + else: + if "no-nexthop-change" in multihop.keys(): + cfg["no_nexthop_change"] = True + if "ttl" in multihop.keys(): + cfg["ttl"] = multihop.get("ttl") + cfg_dict["multihop"] = cfg + + # Read multipath + if "multipath" in conf.keys(): + cfg = {} + multipath = conf.get("multipath") + if multipath is None: + cfg["set"] = True + else: + if "disable" in multipath.keys(): + cfg["disable"] = True + if "multiple-as" in multipath.keys(): + mas = multipath.get("multiple-as") + if mas is None: + cfg["multiple_as"] = True + else: + cfg["multiple_as_disable"] = True + + cfg_dict["multipath"] = cfg + + # Read no-advertise-peer-as value + if "no-advertise-peer-as" in conf.keys(): + cfg_dict["no_advertise_peer_as"] = True + + # Read no-aggregator-id value + if "no-aggregator-id" in conf.keys(): + cfg_dict["no_aggregator_id"] = True + + # Read no-client-reflect value + if "no-client-reflect" in conf.keys(): + cfg_dict["no_client_reflect"] = True + + # Read no-precision-timers value + if "no-precision-timers" in conf.keys(): + cfg_dict["no_precision_timers"] = True + + # Read out-delay value + if "out-delay" in conf.keys(): + cfg_dict["out_delay"] = conf["out-delay"] + + # Read outbound-route-filter + if "outbound-route-filter" in conf.keys(): + cfg = {} + orf = conf.get("outbound-route-filter") + # read outbound-route-filter + if "bgp-orf-cisco-mode" in orf.keys(): + cfg["bgp_orf_cisco_mode"] = True + # read prefix-based + if "prefix-based" in orf.keys(): + pb = orf.get("prefix-based") + pb_dict = {} + if pb is None: + pb_dict["set"] = True + else: + if "accept" in pb.keys(): + # read accept node attributes + accept = pb.get("accept") + accept_dict = {} + if accept is None: + accept_dict["set"] = True + else: + if "inet" in accept.keys(): + accept_dict["inet"] = True + if "inet6" in accept.keys(): + accept_dict["inet6"] = True + pb_dict["accept"] = accept_dict + cfg["prefix_based"] = pb_dict + + cfg_dict["outbound_route_filter"] = cfg + + # Read output-queue-priority value + if "output-queue-priority" in conf.keys(): + cfg = {} + oqp_dict = {} + oqp = conf.get("output-queue-priority") + # read defaults + if "defaults" in oqp.keys(): + defaults = oqp.get("defaults") + defaults_dict = {} + # read high + if "high" in defaults.keys(): + high_dict = {} + high = defaults.get("high") + if "expedited" in high: + high_dict["expedited"] = True + + defaults_dict["high"] = high_dict + # read low + if "low" in defaults.keys(): + low_dict = {} + low = defaults.get("low") + if "expedited" in low: + low_dict["expedited"] = True + # read medium + if "medium" in defaults.keys(): + medium_dict = {} + medium = defaults.get("medium") + if "expedited" in medium: + medium_dict["expedited"] = True + oqp_dict["defaults"] = defaults_dict + + # read expedited + if "expedited" in oqp.keys(): + expedited = oqp.get("expedited") + if "update-tokens" in expedited: + oqp_dict["expedited_update_tokens"] = expedited.get( + "update-tokens", + ) + + # read priority + if "priority" in oqp.keys(): + priority_lst = [] + priority_dict = {} + priority = oqp.get("priority") + if isinstance(priority, dict): + priority_dict["priority"] = priority.get("name") + priority_dict["update_tokens"] = priority.get( + "update-tokens", + ) + priority_lst.append(priority_dict) + else: + for element in priority: + priority_dict["priority"] = element.get("name") + priority_dict["update_tokens"] = element.get( + "update-tokens", + ) + priority_lst.append(priority_dict) + priority_dict = {} + + oqp_dict["priority_update_tokens"] = priority_lst + + cfg_dict["output_queue_priority"] = oqp_dict + + # Read passive value + if "passive" in conf.keys(): + cfg_dict["passive"] = True + + # Read path-selection value + if "path-selection" in conf.keys(): + ps_dict = {} + ps = conf.get("path-selection") + if "always-compare-med" in ps.keys(): + ps_dict["always_compare_med"] = True + if "as-path-ignore" in ps.keys(): + ps_dict["as_path_ignore"] = True + if "external-router-id" in ps.keys(): + ps_dict["external_router_id"] = True + if "cisco-non-deterministic" in ps.keys(): + ps_dict["cisco_non_deterministic"] = True + if "l2vpn-use-bgp-rules" in ps.keys(): + ps_dict["l2vpn_use_bgp_rules"] = True + # read med-plus-igp + if "med-plus-igp" in ps.keys(): + mpi_dict = {} + mpi = ps.get("med-plus-igp") + if mpi is None: + mpi_dict["set"] = True + else: + if "igp-multiplier" in mpi.keys(): + mpi_dict["igp_multiplier"] = mpi.get("igp-multiplier") + if "med-multiplier" in mpi.keys(): + mpi_dict["med_multiplier"] = mpi.get("med-multiplier") + ps_dict["med_plus_igp"] = mpi_dict + + cfg_dict["path_selection"] = ps_dict + + # Read peer-as value + if "peer-as" in conf.keys(): + cfg_dict["peer_as"] = conf["peer-as"] + + # Read precision-timers value + if "precision-timers" in conf.keys(): + cfg_dict["precision_timers"] = True + + # Read preference value + if "preference" in conf.keys(): + cfg_dict["preference"] = conf["preference"] + + # Read remove-private value + if "remove-private" in conf.keys(): + rp_dict = {} + rp = conf.get("remove-private") + if rp is None: + rp_dict["set"] = True + else: + if "all" in rp.keys(): + all = rp.get("all") + if all is None: + rp_dict["all"] = True + else: + if "replace" in all.keys(): + replace = all.get("replace") + if replace is None: + rp_dict["all_replace"] = True + else: + rp_dict["all_replace_nearest"] = True + + cfg_dict["remove_private"] = rp_dict + + # Read rfc6514-compliant-safi129 value + if "rfc6514-compliant-safi129" in conf.keys(): + cfg_dict["rfc6514_compliant_safi129"] = True + + # Read route-server-client value + if "route-server-client" in conf.keys(): + cfg_dict["route_server_client"] = True + + # Read send-addpath-optimization value + if "send-addpath-optimization" in conf.keys(): + cfg_dict["send_addpath_optimization"] = True + + # Read snmp-options value + if "snmp-options" in conf.keys(): + cfg = {} + so = conf.get("snmp-options") + if "backward-traps-only-from-established" in so: + cfg["backward_traps_only_from_established"] = True + if "emit-inet-address-length-in-oid" in so: + cfg["emit_inet_address_length_in_oid"] = True + cfg_dict["snmp_options"] = cfg + + # Read sr-preference-override value + if "sr-preference-override" in conf.keys(): + cfg_dict["sr_preference_override"] = conf["sr-preference-override"] + + # Read stale-labels-holddown-period value + if "stale-labels-holddown-period" in conf.keys(): + cfg_dict["stale_labels_holddown_period"] = conf["stale-labels-holddown-period"] + + # Read tcp-aggressive-transmission value + if "tcp-aggressive-transmission" in conf.keys(): + cfg_dict["tcp_aggressive_transmission"] = True + + # Read tcp-mss value + if "tcp-mss" in conf.keys(): + cfg_dict["tcp_mss"] = conf["tcp-mss"] + + # Read traceoptions value + if "traceoptions" in conf.keys(): + to_dict = {} + to = conf.get("traceoptions") + # read file + if "file" in to.keys(): + file_dict = {} + file = to.get("file") + if "filename" in file.keys(): + file_dict["filename"] = file.get("filename") + if "files" in file.keys(): + file_dict["files"] = file.get("files") + if "no-world-readable" in file.keys(): + file_dict["no_world_readable"] = True + if "world-readable" in file.keys(): + file_dict["world_readable"] = True + if "size" in file.keys(): + file_dict["size"] = file.get("size") + to_dict["file"] = file_dict + # read flag + if "flag" in to.keys(): + flag_lst = [] + flag = to.get("flag") + for event in flag: + flag_dict = {} + if event is not None: + if "detail" in event.keys(): + flag_dict["detail"] = True + if "disable" in event.keys(): + flag_dict["disable"] = True + if "receive" in event.keys(): + flag_dict["receive"] = True + if "send" in event.keys(): + flag_dict["send"] = True + if "filter" in event.keys(): + filter_dict = {} + filter = event.get("filter") + if filter is None: + filter_dict["set"] = True + else: + if "match-on" in filter.keys(): + filter_dict["match_on_prefix"] = True + if "policy" in filter.keys(): + filter_dict["policy"] = filter.get( + "policy", + ) + flag_dict["filter"] = filter_dict + flag_dict["name"] = event.get("name") + flag_lst.append(flag_dict) + + to_dict["flag"] = flag_lst + cfg_dict["traceoptions"] = to_dict + # Read traffic-statistics-labeled-path + if "traffic-statistics-labeled-path" in conf.keys(): + tslp_dict = {} + tslp = conf.get("traffic-statistics-labeled-path") + # read file + if "file" in tslp.keys(): + file_dict = {} + file = tslp.get("file") + if "filename" in file.keys(): + file_dict["filename"] = file.get("filename") + if "files" in file.keys(): + file_dict["files"] = file.get("files") + if "no-world-readable" in file.keys(): + file_dict["no_world_readable"] = True + if "world-readable" in file.keys(): + file_dict["world_readable"] = True + if "size" in file.keys(): + file_dict["size"] = file.get("size") + tslp_dict["file"] = file_dict + # read interval + if "interval" in tslp.keys(): + tslp_dict["interval"] = tslp.get("interval") + + cfg_dict["traffic_statistics_labeled_path"] = tslp_dict + # Read ttl value + if "ttl" in conf.keys(): + cfg_dict["ttl"] = conf["ttl"] + + # Read unconfigured-peer-graceful-restart value + if "unconfigured-peer-graceful-restart" in conf.keys(): + cfg_dict["unconfigured_peer_graceful_restart"] = True + + # Read vpn-apply-export value + if "vpn-apply-export" in conf.keys(): + cfg_dict["vpn_apply_export"] = True + + # Read group name value + if "name" in conf.keys(): + if type == "neighbor": + cfg_dict["neighbor_address"] = conf["name"] + else: + cfg_dict["name"] = conf["name"] + + # Read as-override value + if "as-override" in conf.keys(): + cfg_dict["as_override"] = True + + # Read allow + if "allow" in conf.keys(): + allow_lst = [] + allow = conf["allow"] + if isinstance(allow, list): + for item in allow: + allow_lst.append(item) + else: + allow_lst.append(allow) + if allow_lst: + cfg_dict["allow"] = allow_lst + + # Read optimal-route-reflection + if "optimal-route-reflection" in conf.keys(): + orr_dict = {} + orr = conf["optimal-route-reflection"] + + if "igp-backup" in orr.keys(): + orr_dict["igp_backup"] = orr.get("igp-backup") + + if "igp-primary" in orr.keys(): + orr_dict["igp_primary"] = orr.get("igp-primary") + cfg_dict["optimal_route_reflection"] = orr_dict + + # Read group type value + if "type" in conf.keys(): + cfg_dict["type"] = conf["type"] + + # Read unconfigured-peer-graceful-restart value + if "unconfigured-peer-graceful-restart" in conf.keys(): + cfg_dict["unconfigured_peer_graceful_restart"] = True + + # Read vpn-apply-export value + if "vpn-apply-export" in conf.keys(): + cfg_dict["vpn_apply_export"] = True diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/facts.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/facts.py new file mode 100644 index 00000000..2f6f5716 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/facts.py @@ -0,0 +1,203 @@ +# +# -*- 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 junos +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_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts import ( + FactsBase, +) + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.acl_interfaces.acl_interfaces import ( + Acl_interfacesFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.acls.acls import ( + AclsFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.bgp_address_family.bgp_address_family import ( + Bgp_address_familyFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.bgp_global.bgp_global import ( + Bgp_globalFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.hostname.hostname import ( + HostnameFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.interfaces.interfaces import ( + InterfacesFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.l2_interfaces.l2_interfaces import ( + L2_interfacesFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.l3_interfaces.l3_interfaces import ( + L3_interfacesFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.lacp.lacp import ( + LacpFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.lacp_interfaces.lacp_interfaces import ( + Lacp_interfacesFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.lag_interfaces.lag_interfaces import ( + Lag_interfacesFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.legacy.base import ( + Config, + Default, + Hardware, + Interfaces, + OFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.lldp_global.lldp_global import ( + Lldp_globalFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.lldp_interfaces.lldp_interfaces import ( + Lldp_interfacesFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.logging_global.logging_global import ( + Logging_globalFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.ntp_global.ntp_global import ( + Ntp_globalFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.ospf_interfaces.ospf_interfaces import ( + Ospf_interfacesFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.ospfv2.ospfv2 import ( + Ospfv2Facts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.ospfv3.ospfv3 import ( + Ospfv3Facts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.prefix_lists.prefix_lists import ( + Prefix_listsFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.routing_instances.routing_instances import ( + Routing_instancesFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.routing_options.routing_options import ( + Routing_optionsFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.security_policies.security_policies import ( + Security_policiesFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.security_policies_global.security_policies_global import ( + Security_policies_globalFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.security_zones.security_zones import ( + Security_zonesFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.snmp_server.snmp_server import ( + Snmp_serverFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.static_routes.static_routes import ( + Static_routesFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.vlans.vlans import ( + VlansFacts, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + HAS_PYEZ, +) + + +FACT_LEGACY_SUBSETS = dict( + default=Default, + hardware=Hardware, + config=Config, + interfaces=Interfaces, +) +FACT_RESOURCE_SUBSETS = dict( + acls=AclsFacts, + acl_interfaces=Acl_interfacesFacts, + interfaces=InterfacesFacts, + lacp=LacpFacts, + lacp_interfaces=Lacp_interfacesFacts, + lag_interfaces=Lag_interfacesFacts, + l2_interfaces=L2_interfacesFacts, + l3_interfaces=L3_interfacesFacts, + lldp_global=Lldp_globalFacts, + lldp_interfaces=Lldp_interfacesFacts, + ospfv2=Ospfv2Facts, + ospfv3=Ospfv3Facts, + ospf_interfaces=Ospf_interfacesFacts, + vlans=VlansFacts, + static_routes=Static_routesFacts, + bgp_global=Bgp_globalFacts, + bgp_address_family=Bgp_address_familyFacts, + routing_instances=Routing_instancesFacts, + prefix_lists=Prefix_listsFacts, + logging_global=Logging_globalFacts, + ntp_global=Ntp_globalFacts, + security_policies=Security_policiesFacts, + security_policies_global=Security_policies_globalFacts, + security_zones=Security_zonesFacts, + snmp_server=Snmp_serverFacts, + routing_options=Routing_optionsFacts, + hostname=HostnameFacts, +) + + +class Facts(FactsBase): + """The fact class for junos""" + + 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 junos + :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 not legacy_facts_type: + legacy_facts_type = self._gather_subset + # fetch old style facts only when explicitly mentioned in gather_subset option + if "ofacts" in legacy_facts_type: + if HAS_PYEZ: + self.ansible_facts.update(OFacts(self._module).populate()) + else: + self._warnings.extend( + [ + "junos-eznc is required to gather old style facts but does not appear to be installed. " + "It can be installed using `pip install junos-eznc`", + ], + ) + self.ansible_facts["ansible_net_gather_subset"].append( + "ofacts", + ) + legacy_facts_type.remove("ofacts") + + if self.VALID_LEGACY_GATHER_SUBSETS: + self.get_network_legacy_facts( + FACT_LEGACY_SUBSETS, + legacy_facts_type, + ) + + return self.ansible_facts, self._warnings \ No newline at end of file diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/hostname/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/hostname/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/hostname/hostname.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/hostname/hostname.py new file mode 100644 index 00000000..27f64bb4 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/hostname/hostname.py @@ -0,0 +1,137 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The junos hostname 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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.hostname.hostname import ( + HostnameArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class HostnameFacts(object): + """The junos hostname fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = HostnameArgs.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_device_data(self, connection, config_filter): + """ + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for ntp_gloabl + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + """ + data = self.get_device_data(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + objs = {} + resources = data.xpath("configuration/system/host-name") + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + + facts = {} + if objs: + facts["hostname"] = {} + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + facts["hostname"] = utils.remove_empties(params["config"]) + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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 + """ + hostname_config = {} + + # Parse facts for hostname node + + if "host-name" in conf.keys(): + hostname_config["hostname"] = conf.get("host-name") + return utils.remove_empties(hostname_config) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/interfaces/interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/interfaces/interfaces.py new file mode 100644 index 00000000..c0236343 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/interfaces/interfaces.py @@ -0,0 +1,179 @@ +# +# -*- 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 junos 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 + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.interfaces.interfaces import ( + InterfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.utils.utils import ( + get_resource_config, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class InterfacesFacts(object): + """The junos 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 get_config(self, connection, config_filter): + """ + + :param connection: + :param config_filter: + :return: + """ + return get_resource_config(connection, config_filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for interfaces + + :param connection: the device connection + :param data: previously collected configuration as lxml ElementTree root instance + or valid xml sting + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + """ + data = self.get_config(connection, config_filter=config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + + resources = data.xpath("configuration/interfaces/interface") + + objs = [] + for resource in resources: + if resource is not None: + obj = self.render_config(self.generated_spec, resource) + 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 _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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 ElementTree instance of configuration object + :rtype: dictionary + :returns: The generated config + """ + config = deepcopy(spec) + config["name"] = utils.get_xml_conf_arg(conf, "name") + config["description"] = utils.get_xml_conf_arg(conf, "description") + mtu = utils.get_xml_conf_arg(conf, "mtu") + config["mtu"] = int(mtu) if mtu else None + config["speed"] = utils.get_xml_conf_arg(conf, "speed") + config["duplex"] = utils.get_xml_conf_arg(conf, "link-mode") + config["hold_time"]["down"] = utils.get_xml_conf_arg( + conf, + "hold-time/down", + ) + config["hold_time"]["up"] = utils.get_xml_conf_arg( + conf, + "hold-time/up", + ) + disable = utils.get_xml_conf_arg(conf, "disable", data="tag") + if disable: + config["enabled"] = False + else: + config["enabled"] = True + cfg = self._get_xml_dict(conf) + unit_cfg = cfg.get("interface") + if "unit" in unit_cfg.keys(): + units = unit_cfg.get("unit") + unit_lst = [] + unit_dict = {} + if isinstance(units, dict): + if "description" in units.keys(): + unit_dict["name"] = units["name"] + unit_dict["description"] = units["description"] + unit_lst.append(unit_dict) + else: + for unit in units: + if "description" in unit.keys(): + unit_dict["name"] = unit["name"] + unit_dict["description"] = unit["description"] + unit_lst.append(unit_dict) + unit_dict = {} + config["units"] = unit_lst + + return utils.remove_empties(config) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l2_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l2_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l2_interfaces/l2_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l2_interfaces/l2_interfaces.py new file mode 100644 index 00000000..26568f11 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l2_interfaces/l2_interfaces.py @@ -0,0 +1,157 @@ +# +# -*- 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 junos l2_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 + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.l2_interfaces.l2_interfaces import ( + L2_interfacesArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + + +class L2_interfacesFacts(object): + """The junos 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 get_device_data(self, connection, config_filter): + """ + + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for interfaces + :param connection: the device connection + :param data: previously collected configuration as lxml ElementTree root instance + or valid xml sting + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + """ + data = self.get_device_data(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + self._resources = data.xpath("configuration/interfaces/interface") + + objs = [] + for resource in self._resources: + if resource is not None: + obj = self.render_config(self.generated_spec, resource) + 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 ElementTree instance of configuration object + :rtype: dictionary + :returns: The generated config + """ + config = deepcopy(spec) + + enhanced_layer = True + mode = utils.get_xml_conf_arg( + conf, + "unit/family/ethernet-switching/interface-mode", + ) + + if mode is None: + mode = utils.get_xml_conf_arg( + conf, + "unit/family/ethernet-switching/port-mode", + ) + enhanced_layer = False + + # Layer 2 is configured on interface + config["name"] = utils.get_xml_conf_arg(conf, "name") + unit = utils.get_xml_conf_arg(conf, "unit/name") + config["unit"] = unit if unit else 0 + config["enhanced_layer"] = enhanced_layer + + if mode == "access" or not mode: + config["access"] = {} + config["access"]["vlan"] = utils.get_xml_conf_arg( + conf, + "unit/family/ethernet-switching/vlan/members", + ) + elif mode == "trunk": + config["trunk"] = {} + vlan_members = conf.xpath( + "unit/family/ethernet-switching/vlan/members", + ) + if vlan_members: + config["trunk"]["allowed_vlans"] = [] + for vlan_member in vlan_members: + config["trunk"]["allowed_vlans"].append( + vlan_member.text, + ) + + config["trunk"]["native_vlan"] = utils.get_xml_conf_arg( + conf, + "native-vlan-id", + ) + return utils.remove_empties(config) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l3_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l3_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l3_interfaces/l3_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l3_interfaces/l3_interfaces.py new file mode 100644 index 00000000..14f7a869 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/l3_interfaces/l3_interfaces.py @@ -0,0 +1,189 @@ +# +# -*- 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 junos 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 + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import iteritems, string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.l3_interfaces.l3_interfaces import ( + L3_interfacesArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class L3_interfacesFacts(object): + """The junos 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 get_config(self, connection, config_filter): + """ + + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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 + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + """ + data = self.get_config(connection, config_filter) + data_string = etree.tostring(data, pretty_print=True).decode() + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + resources = data.xpath("configuration/interfaces/interface") + config = [] + + if resources: + config = self.parse_l3_if_resources(resources) + facts = {} + facts["l3_interfaces"] = config + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def parse_l3_if_resources(self, l3_if_resources): + l3_ifaces = [] + for iface in l3_if_resources: + int_have = self._get_xml_dict(iface) + int_dict = int_have["interface"] + if "unit" in int_dict.keys() and int_dict.get("unit") is not None: + unit_list = int_dict["unit"] + if isinstance(unit_list, list): + for item in unit_list: + fact_dict = self._render_l3_intf(item, int_dict) + if fact_dict: + l3_ifaces.append(fact_dict) + else: + fact_dict = self._render_l3_intf(unit_list, int_dict) + if fact_dict: + l3_ifaces.append(fact_dict) + return l3_ifaces + + def _render_l3_intf(self, unit, int_dict): + """ + + :param item: + :param int_dict: + :return: + """ + interface = {} + ipv4 = [] + ipv6 = [] + if "family" in unit.keys(): + if "inet" in unit["family"].keys(): + interface["name"] = int_dict["name"] + interface["unit"] = unit["name"] + inet = unit["family"].get("inet") + if inet is not None and "address" in inet.keys(): + if isinstance(inet["address"], dict): + for key, value in iteritems(inet["address"]): + addr = {} + addr["address"] = value + ipv4.append(addr) + else: + for ip in inet["address"]: + addr = {} + addr["address"] = ip["name"] + ipv4.append(addr) + if "inet" in unit["family"]: + interface["name"] = int_dict["name"] + interface["unit"] = unit["name"] + inet = unit["family"].get("inet") + if inet: + if inet.get("mtu"): + mtu = int(inet.get("mtu")) + interface["mtu"] = int(mtu) + if "dhcp" in inet: + ipv4.append({"address": "dhcp"}) + + if "inet6" in unit["family"]: + interface["name"] = int_dict["name"] + interface["unit"] = unit["name"] + + inet6 = unit["family"].get("inet6") + if inet6: + if inet6.get("mtu"): + mtu = int(inet6.get("mtu")) + interface["mtu"] = int(mtu) + + addresses = inet6.get("address") + if addresses: + if isinstance(addresses, dict): + for value in addresses.values(): + ipv6.append({"address": value}) + else: + for ip in addresses: + ipv6.append({"address": ip["name"]}) + + interface["ipv4"] = ipv4 + interface["ipv6"] = ipv6 + return utils.remove_empties(interface) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp/lacp.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp/lacp.py new file mode 100644 index 00000000..14617c38 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp/lacp.py @@ -0,0 +1,118 @@ +# +# -*- 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 junos 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._text import to_bytes +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.lacp.lacp import ( + LacpArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.utils.utils import ( + get_resource_config, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + + +class LacpFacts(object): + """The junos 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 interfaces + :param connection: the device connection + :param data: previously collected configuration as lxml ElementTree root instance + or valid xml sting + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + + + + + + """ + data = get_resource_config(connection, config_filter=config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + + facts = {} + config = deepcopy(self.generated_spec) + resources = data.xpath( + "configuration/chassis/aggregated-devices/ethernet/lacp", + ) + if resources: + lacp_root = resources[0] + config["system_priority"] = utils.get_xml_conf_arg( + lacp_root, + "system-priority", + ) + + if utils.get_xml_conf_arg( + lacp_root, + "link-protection/non-revertive", + data="tag", + ): + config["link_protection"] = "non-revertive" + + elif utils.get_xml_conf_arg(lacp_root, "link-protection"): + config["link_protection"] = "revertive" + + params = utils.validate_config( + self.argument_spec, + {"config": utils.remove_empties(config)}, + ) + facts["lacp"] = {} + facts["lacp"].update(utils.remove_empties(params["config"])) + + ansible_facts["ansible_network_resources"].update(facts) + + return ansible_facts diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp_interfaces/lacp_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp_interfaces/lacp_interfaces.py new file mode 100644 index 00000000..14f0e2e4 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lacp_interfaces/lacp_interfaces.py @@ -0,0 +1,146 @@ +# +# -*- 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 junos 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 + +from copy import deepcopy + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.lacp_interfaces.lacp_interfaces import ( + Lacp_interfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.utils.utils import ( + get_resource_config, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + + +class Lacp_interfacesFacts(object): + """The junos 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 interfaces + :param connection: the device connection + :param data: previously collected configuration as lxml ElementTree root instance + or valid xml sting + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + """ + data = get_resource_config(connection, config_filter=config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + + self._resources = data.xpath("configuration/interfaces/interface") + + objs = [] + for resource in self._resources: + if resource is not None: + obj = self.render_config(self.generated_spec, resource) + 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 ElementTree instance of configuration object + :rtype: dictionary + :returns: The generated config + """ + config = deepcopy(spec) + config["name"] = utils.get_xml_conf_arg(conf, "name") + config["period"] = utils.get_xml_conf_arg( + conf, + "aggregated-ether-options/lacp/periodic", + ) + config["sync_reset"] = utils.get_xml_conf_arg( + conf, + "aggregated-ether-options/lacp/sync-reset", + ) + force_up = utils.get_xml_conf_arg( + conf, + "ether-options/ieee-802.3ad/lacp/force-up", + data="tag", + ) + if force_up: + config["force_up"] = True + config["port_priority"] = utils.get_xml_conf_arg( + conf, + "ether-options/ieee-802.3ad/lacp/port-priority", + ) + config["system"]["priority"] = utils.get_xml_conf_arg( + conf, + "aggregated-ether-options/lacp/system-priority", + ) + address = utils.get_xml_conf_arg( + conf, + "aggregated-ether-options/lacp/system-id", + ) + if address: + config["system"].update({"mac": {"address": address}}) + + lacp_intf_cfg = utils.remove_empties(config) + # if lacp config is not present for interface return empty dict + if len(lacp_intf_cfg) == 1: + return {} + else: + return lacp_intf_cfg diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lag_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lag_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lag_interfaces/lag_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lag_interfaces/lag_interfaces.py new file mode 100644 index 00000000..1c5bf508 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lag_interfaces/lag_interfaces.py @@ -0,0 +1,193 @@ +# +# -*- 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 junos 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 + +from copy import deepcopy + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.lag_interfaces.lag_interfaces import ( + Lag_interfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.utils.utils import ( + get_resource_config, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + + +class Lag_interfacesFacts(object): + """The junos 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 data: previously collected configuration as lxml ElementTree root instance + or valid xml sting + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + """ + data = get_resource_config(connection, config_filter=config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + self._resources = data.xpath("configuration/interfaces/interface") + + objs = [] + for resource in self._resources: + if resource is not None: + obj = self.render_config(self.generated_spec, resource) + if obj: + objs.append(obj) + 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 get_member_config(self, interface_obj, intf_name): + """ + Extract member configuration for a given interface object and interface name. + + This function checks both `ether-options` and `gigether-options` for 802.3ad bundle configurations + and determines the link type (primary or backup) if applicable. + + :param interface_obj: The ElementTree instance of an interface configuration object. + :param intf_name: The name of the aggregated Ethernet interface (e.g., "ae0"). + :rtype: dictionary + :returns: A dictionary containing the member configuration with the following structure: + { + "member": , + "link_type": "primary" or "backup" (optional) + } + If no member configuration is found, an empty dictionary is returned. + """ + + member_config = {} + lag_interface_member = utils.get_xml_conf_arg( + interface_obj, + "ether-options/ieee-802.3ad[bundle='%s']/../../name" % intf_name, + ) or utils.get_xml_conf_arg( + interface_obj, + "gigether-options/ieee-802.3ad[bundle='%s']/../../name" % intf_name, + ) + if lag_interface_member: + member_config["member"] = lag_interface_member + if utils.get_xml_conf_arg( + interface_obj, + "ether-options/ieee-802.3ad/primary", + data="tag", + ): + member_config["link_type"] = "primary" + member_config["ether_option_type"] = "ether" + elif utils.get_xml_conf_arg( + interface_obj, + "gigether-options/ieee-802.3ad/primary", + data="tag", + ): + member_config["link_type"] = "primary" + member_config["ether_option_type"] = "gigether" + elif utils.get_xml_conf_arg( + interface_obj, + "ether-options/ieee-802.3ad/backup", + data="tag", + ): + member_config["link_type"] = "backup" + member_config["ether_option_type"] = "ether" + elif utils.get_xml_conf_arg( + interface_obj, + "gigether-options/ieee-802.3ad/backup", + data="tag", + ): + member_config["link_type"] = "backup" + member_config["ether_option_type"] = "gigether" + return member_config + + 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 ElementTree instance of configuration object + :rtype: dictionary + :returns: The generated config + """ + config = deepcopy(spec) + intf_name = utils.get_xml_conf_arg(conf, "name") + if intf_name.startswith("ae"): + config["name"] = intf_name + config["members"] = [] + for interface_obj in self._resources: + member_config = self.get_member_config(interface_obj, intf_name) + if member_config: + config["members"].append(member_config) + + for mode in ["active", "passive"]: + if utils.get_xml_conf_arg( + conf, + "aggregated-ether-options/lacp/%s" % mode, + data="tag", + ): + config["mode"] = mode + break + + if utils.get_xml_conf_arg(conf, "aggregated-ether-options/link-protection", data="tag"): + config["link_protection"] = True + + lag_intf_cfg = utils.remove_empties(config) + # if lag interfaces config is not present return empty dict + if len(lag_intf_cfg) == 1: + return {} + else: + return lag_intf_cfg diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/legacy/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/legacy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/legacy/base.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/legacy/base.py new file mode 100644 index 00000000..74b331f0 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/legacy/base.py @@ -0,0 +1,230 @@ +# -*- 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 junos 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 platform + + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + +from ansible.module_utils._text import to_text +from ansible.module_utils.basic import missing_required_lib +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf import ( + exec_rpc, +) + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + get_capabilities, + get_configuration, + get_device, + tostring, +) + + +try: + from lxml.etree import Element, SubElement +except ImportError: + from xml.etree.ElementTree import Element, SubElement + + +class FactsBase(object): + def __init__(self, module): + self.module = module + self.facts = dict() + self.warnings = [] + + def populate(self): + raise NotImplementedError + + def cli(self, command): + reply = command(self.module, command) + output = reply.find(".//output") + if not output: + self.module.fail_json( + msg="failed to retrieve facts for command %s" % command, + ) + return to_text(output.text).strip() + + def rpc(self, rpc): + return exec_rpc(self.module, tostring(Element(rpc))) + + def get_text(self, ele, tag): + try: + return to_text(ele.find(tag).text).strip() + except AttributeError: + pass + + +class Default(FactsBase): + def populate(self): + self.facts.update(self.platform_facts()) + + reply = self.rpc("get-chassis-inventory") + data = reply.find(".//chassis-inventory/chassis") + self.facts["serialnum"] = self.get_text(data, "serial-number") + + 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 Config(FactsBase): + def populate(self): + config_format = self.module.params["config_format"] + reply = get_configuration(self.module, format=config_format) + + if config_format == "xml": + config = tostring(reply.find("configuration")).strip() + + elif config_format == "text": + config = self.get_text(reply, "configuration-text") + + elif config_format == "json": + config = self.module.from_json(reply.text.strip()) + + elif config_format == "set": + config = self.get_text(reply, "configuration-set") + + self.facts["config"] = config + + +class Hardware(FactsBase): + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + def populate(self): + reply = self.rpc("get-system-memory-information") + data = reply.find( + ".//system-memory-information/system-memory-summary-information", + ) + + self.facts.update( + { + "memfree_mb": int(self.get_text(data, "system-memory-free")), + "memtotal_mb": int(self.get_text(data, "system-memory-total")), + }, + ) + + reply = self.rpc("get-system-storage") + data = reply.find(".//system-storage-information") + + filesystems = list() + for obj in data: + filesystems.append(self.get_text(obj, "filesystem-name")) + self.facts["filesystems"] = filesystems + + reply = self.rpc("get-route-engine-information") + data = reply.find(".//route-engine-information") + + routing_engines = dict() + for obj in data: + slot = self.get_text(obj, "slot") + routing_engines.update({slot: {}}) + routing_engines[slot].update({"slot": slot}) + for child in obj: + if child.text != "\n": + routing_engines[slot].update( + {child.tag.replace("-", "_"): child.text}, + ) + + self.facts["routing_engines"] = routing_engines + + if len(data) > 1: + self.facts["has_2RE"] = True + else: + self.facts["has_2RE"] = False + + reply = self.rpc("get-chassis-inventory") + data = reply.findall(".//chassis-module") + + modules = list() + for obj in data: + mod = dict() + for child in obj: + if child.text != "\n": + mod.update({child.tag.replace("-", "_"): child.text}) + if "chassis-sub-module" in child.tag: + mod["chassis_sub_module"] = self._get_xml_dict(obj)["chassis-module"][ + "chassis-sub-module" + ] + modules.append(mod) + + self.facts["modules"] = modules + + +class Interfaces(FactsBase): + def populate(self): + ele = Element("get-interface-information") + SubElement(ele, "detail") + reply = exec_rpc(self.module, tostring(ele)) + + interfaces = {} + + for item in reply[0]: + name = self.get_text(item, "name") + obj = { + "oper-status": self.get_text(item, "oper-status"), + "admin-status": self.get_text(item, "admin-status"), + "speed": self.get_text(item, "speed"), + "macaddress": self.get_text(item, "hardware-physical-address"), + "mtu": self.get_text(item, "mtu"), + "type": self.get_text(item, "if-type"), + } + + interfaces[name] = obj + + self.facts["interfaces"] = interfaces + + +class OFacts(FactsBase): + def populate(self): + device = get_device(self.module) + facts = dict(device.facts) + + if "2RE" in facts: + facts["has_2RE"] = facts["2RE"] + del facts["2RE"] + + facts["version_info"] = dict(facts["version_info"]) + if "junos_info" in facts: + for key, value in facts["junos_info"].items(): + if "object" in value: + value["object"] = dict(value["object"]) + + return facts diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_global/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_global/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_global/lldp_global.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_global/lldp_global.py new file mode 100644 index 00000000..a1019fa9 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_global/lldp_global.py @@ -0,0 +1,115 @@ +# +# -*- 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 junos lldp 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._text import to_bytes +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.lldp_global.lldp_global import ( + Lldp_globalArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.utils.utils import ( + get_resource_config, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + + +class Lldp_globalFacts(object): + """The junos lldp 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 interfaces + :param connection: the device connection + :param data: previously collected configuration as lxml ElementTree root instance + or valid xml sting + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + + """ + data = get_resource_config(connection, config_filter=config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + + facts = {"lldp_global": {}} + config = deepcopy(self.generated_spec) + resources = data.xpath("configuration/protocols/lldp") + if resources: + lldp_root = resources[0] + config["address"] = utils.get_xml_conf_arg( + lldp_root, + "management-address", + ) + config["interval"] = utils.get_xml_conf_arg( + lldp_root, + "advertisement-interval", + ) + config["transmit_delay"] = utils.get_xml_conf_arg( + lldp_root, + "transmit-delay", + ) + config["hold_multiplier"] = utils.get_xml_conf_arg( + lldp_root, + "hold-multiplier", + ) + if utils.get_xml_conf_arg(lldp_root, "disable", data="tag"): + config["enabled"] = False + + params = utils.validate_config( + self.argument_spec, + {"config": utils.remove_empties(config)}, + ) + + facts["lldp_global"] = utils.remove_empties(params["config"]) + ansible_facts["ansible_network_resources"].update(facts) + + return ansible_facts diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_interfaces/lldp_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_interfaces/lldp_interfaces.py new file mode 100644 index 00000000..5c11d219 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/lldp_interfaces/lldp_interfaces.py @@ -0,0 +1,115 @@ +# +# -*- 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 junos 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 + +from copy import deepcopy + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.lldp_interfaces.lldp_interfaces import ( + Lldp_interfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.utils.utils import ( + get_resource_config, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + + +class Lldp_interfacesFacts(object): + """The junos 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 interfaces + :param connection: the device connection + :param data: previously collected configuration as lxml ElementTree root instance + or valid xml sting + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + """ + data = get_resource_config(connection, config_filter=config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + + self._resources = data.xpath("configuration/protocols/lldp/interface") + + objs = [] + for resource in self._resources: + if resource is not None: + obj = self.render_config(self.generated_spec, resource) + if obj: + objs.append(obj) + facts = {"lldp_interfaces": []} + 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 ElementTree instance of configuration object + :rtype: dictionary + :returns: The generated config + """ + config = deepcopy(spec) + config["name"] = utils.get_xml_conf_arg(conf, "name") + if utils.get_xml_conf_arg(conf, "disable", data="tag"): + config["enabled"] = False + return utils.remove_empties(config) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/logging_global/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/logging_global/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/logging_global/logging_global.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/logging_global/logging_global.py new file mode 100644 index 00000000..038bcf95 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/logging_global/logging_global.py @@ -0,0 +1,428 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The junos logging_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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.logging_global.logging_global import ( + Logging_globalArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Logging_globalFacts(object): + """The junos logging_global fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Logging_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 get_device_data(self, connection, config_filter): + """ + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for logging_gloabl + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + + """ + data = self.get_device_data(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + objs = {} + resources = data.xpath("configuration/system/syslog") + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + + facts = {"logging_global": {}} + if objs: + facts["logging_global"] = {} + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + facts["logging_global"] = utils.remove_empties(params["config"]) + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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 + """ + logging_gloabl_config = {} + + # Parse facts for BGP address-family global node + conf = conf.get("syslog") + + # Read allow-duplicates node + if "allow-duplicates" in conf.keys(): + logging_gloabl_config["allow_duplicates"] = True + + # Read archive node + if "archive" in conf.keys(): + archive_dict = self.parse_archive_node(conf.get("archive")) + logging_gloabl_config["archive"] = archive_dict + + # Read console node + if "console" in conf.keys(): + console_dict = self.parse_console_node(conf.get("console")) + logging_gloabl_config["console"] = console_dict + + # Read file node + if "file" in conf.keys(): + files_list = self.parse_file_node(conf.get("file")) + logging_gloabl_config["files"] = files_list + + # Read host node + if "host" in conf.keys(): + hosts_list = self.parse_host_node(conf.get("host")) + logging_gloabl_config["hosts"] = hosts_list + + # Read log-rotate-frequency node + if "log-rotate-frequency" in conf.keys(): + logging_gloabl_config["log_rotate_frequency"] = conf.get( + "log-rotate-frequency", + ) + + # Read routing-instance node + if "routing-instance" in conf.keys(): + logging_gloabl_config["routing_instance"] = conf.get( + "routing-instance", + ) + + # Read source-address node + if "source-address" in conf.keys(): + logging_gloabl_config["source_address"] = conf.get( + "source-address", + ) + + # Read user node + if "user" in conf.keys(): + users_list = self.parse_user_node(conf.get("user")) + logging_gloabl_config["users"] = users_list + + # Read time-format + if "time-format" in conf.keys(): + time_format_dict = {} + time_format = conf.get("time-format") + if time_format is None: + time_format_dict["set"] = True + else: + if "millisecond" in time_format.keys(): + time_format_dict["millisecond"] = True + if "year" in time_format.keys(): + time_format_dict["year"] = True + logging_gloabl_config["time_format"] = time_format_dict + + return utils.remove_empties(logging_gloabl_config) + + def parse_archive_node(self, conf): + archive_dict = {} + if conf is not None: + # Read child attributes + if "binary-data" in conf.keys(): + archive_dict["binary_data"] = True + if "files" in conf.keys(): + archive_dict["files"] = conf.get("files") + if "no-binary-data" in conf.keys(): + archive_dict["no_binary_data"] = True + if "no-world-readable" in conf.keys(): + archive_dict["no_world_readable"] = True + if "size" in conf.keys(): + archive_dict["file_size"] = conf.get("size") + if "world-readable" in conf.keys(): + archive_dict["world_readable"] = True + if "archive-sites" in conf.keys(): + archive_sites_list = [] + archive_sites = conf.get("archive-sites") + if isinstance(archive_sites, list): + for item in archive_sites: + archive_sites_list.append(item["name"]) + else: + archive_sites_list.append(archive_sites["name"]) + archive_dict["archive_sites"] = archive_sites_list + else: + archive_dict["set"] = True + + return archive_dict + + def parse_console_node(self, conf, console_dict=None): + console_loggings = [ + "any", + "authorization", + "change-log", + "conflict-log", + "daemon", + "dfc", + "external", + "firewall", + "ftp", + "interactive-commands", + "kernel", + "ntp", + "pfe", + "security", + "user", + ] + if console_dict is None: + console_dict = {} + # Read any node + if isinstance(conf, dict): + for item in console_loggings: + if item in conf.get("name"): + any_dict = {} + for k, v in conf.items(): + if k != "name": + any_dict["level"] = k + console_dict[item.replace("-", "_")] = any_dict + else: + for console in conf: + for item in console_loggings: + if item in console.get("name"): + any_dict = {} + for k, v in console.items(): + if k != "name": + any_dict["level"] = k + console_dict[item.replace("-", "_")] = any_dict + + return console_dict + + def parse_file_node(self, conf): + files_list = [] + files = [] + if isinstance(conf, dict): + files.append(conf) + else: + files = conf + for file in files: + file_dict = {} + # Read file name node + file_dict["name"] = file.get("name") + # Read allow-duplicates node + if "allow-duplicates" in file: + file_dict["allow_duplicates"] = True + # Read contents + if "contents" in file.keys(): + contents = file.get("contents") + if isinstance(contents, list): + for content in contents: + file_dict = self.parse_console_node(content, file_dict) + else: + file_dict = self.parse_console_node(contents, file_dict) + # Read archives + if "archive" in file.keys(): + archive_dict = self.parse_archive_node(file.get("archive")) + file_dict["archive"] = archive_dict + # Read explicit priority + if "explicit-priority" in file.keys(): + file_dict["explicit_priority"] = True + # Read match + if "match" in file.keys(): + file_dict["match"] = file.get("match") + # Read match-strings + if "match-strings" in file.keys(): + match_strings = file.get("match-strings") + match_strings_list = [] + if isinstance(match_strings, list): + for item in match_strings: + match_strings_list.append(item) + else: + match_strings_list.append(match_strings) + file_dict["match_strings"] = match_strings_list + # Read srtructured-data + if "structured-data" in file.keys(): + structured_data_dict = {} + if file.get("structured-data"): + structured_data_dict["brief"] = True + else: + structured_data_dict["set"] = True + file_dict["structured_data"] = structured_data_dict + files_list.append(file_dict) + return files_list + + def parse_host_node(self, conf): + hosts_list = [] + hosts = [] + if isinstance(conf, dict): + hosts.append(conf) + else: + hosts = conf + for host in hosts: + host_dict = {} + # Read file name node + host_dict["name"] = host.get("name") + # Read allow-duplicates node + if "allow-duplicates" in host: + host_dict["allow_duplicates"] = True + # Read contents + if "contents" in host.keys(): + contents = host.get("contents") + if isinstance(contents, list): + for content in contents: + host_dict = self.parse_console_node(content, host_dict) + else: + host_dict = self.parse_console_node(contents, host_dict) + # Read exclude-hostname node + if "exclude-hostname" in host.keys(): + host_dict["exclude_hostname"] = True + # Read facility-override node + if "facility-override" in host.keys(): + host_dict["facility_override"] = host.get("facility-override") + # Read log-prefix node + if "log-prefix" in host.keys(): + host_dict["log_prefix"] = host.get("log-prefix") + # Read match + if "match" in host.keys(): + host_dict["match"] = host.get("match") + # Read match-strings + if "match-strings" in host.keys(): + match_strings = host.get("match-strings") + match_strings_list = [] + if isinstance(match_strings, list): + for item in match_strings: + match_strings_list.append(item) + else: + match_strings_list.append(match_strings) + host_dict["match_strings"] = match_strings_list + # Read port node + if "port" in host.keys(): + host_dict["port"] = host.get("port") + # Read routing-instance node + if "routing-instance" in host.keys(): + host_dict["routing_instance"] = host.get("routing-instance") + # Read source-address node + if "source-address" in host.keys(): + host_dict["source_address"] = host.get("source-address") + # Read srtructured-data + if "structured-data" in host.keys(): + structured_data_dict = {} + if host.get("structured-data"): + structured_data_dict["brief"] = True + else: + structured_data_dict["set"] = True + host_dict["structured_data"] = structured_data_dict + + hosts_list.append(host_dict) + + return hosts_list + + def parse_user_node(self, conf): + users_list = [] + users = [] + if isinstance(conf, dict): + users.append(conf) + else: + users = conf + for user in users: + user_dict = {} + # Read file name node + user_dict["name"] = user.get("name") + # Read allow-duplicates node + if "allow-duplicates" in user: + user_dict["allow_duplicates"] = True + # Read contents + if "contents" in user.keys(): + contents = user.get("contents") + if isinstance(contents, list): + for content in contents: + user_dict = self.parse_console_node(content, user_dict) + else: + user_dict = self.parse_console_node(contents, user_dict) + # Read match + if "match" in user.keys(): + user_dict["match"] = user.get("match") + # Read match-strings + if "match-strings" in user.keys(): + match_strings = user.get("match-strings") + match_strings_list = [] + if isinstance(match_strings, list): + for item in match_strings: + match_strings_list.append(item) + else: + match_strings_list.append(match_strings) + user_dict["match_strings"] = match_strings_list + + users_list.append(user_dict) + + return users_list diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ntp_global/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ntp_global/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ntp_global/ntp_global.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ntp_global/ntp_global.py new file mode 100644 index 00000000..1a43e666 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ntp_global/ntp_global.py @@ -0,0 +1,319 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The junos ntp_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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.ntp_global.ntp_global import ( + Ntp_globalArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Ntp_globalFacts(object): + """The junos ntp_global fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Ntp_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 get_device_data(self, connection, config_filter): + """ + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for ntp_gloabl + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + + """ + data = self.get_device_data(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + objs = {} + resources = data.xpath("configuration/system/ntp") + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + + facts = {"ntp_global": {}} + if objs: + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + facts["ntp_global"] = utils.remove_empties(params["config"]) + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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 + """ + ntp_global_config = {} + + # Parse facts for BGP address-family global node + conf = conf.get("ntp") + + # Read allow-duplicates node + if "authentication-key" in conf.keys(): + auth_key_lst = [] + auth_keys = conf.get("authentication-key") + auth_key_dict = {} + if isinstance(auth_keys, dict): + auth_key_dict["id"] = auth_keys["name"] + auth_key_dict["algorithm"] = auth_keys["type"] + auth_key_dict["key"] = auth_keys["value"] + auth_key_lst.append(auth_key_dict) + + else: + for auth_key in auth_keys: + auth_key_dict["id"] = auth_key["name"] + auth_key_dict["algorithm"] = auth_key["type"] + auth_key_dict["key"] = auth_key["value"] + auth_key_lst.append(auth_key_dict) + auth_key_dict = {} + if auth_key_lst: + ntp_global_config["authentication_keys"] = auth_key_lst + + # Read boot-server node + if "boot-server" in conf.keys(): + ntp_global_config["boot_server"] = conf.get("boot-server") + + # Read broadcast node + if "broadcast" in conf.keys(): + broadcast_lst = [] + broadcasts = conf.get("broadcast") + broadcast_dict = {} + if isinstance(broadcasts, dict): + broadcast_dict["address"] = broadcasts["name"] + if "key" in broadcasts.keys(): + broadcast_dict["key"] = broadcasts["key"] + if "ttl" in broadcasts.keys(): + broadcast_dict["ttl"] = broadcasts["ttl"] + if "version" in broadcasts.keys(): + broadcast_dict["version"] = broadcasts["version"] + if "routing-instance-name" in broadcasts.keys(): + broadcast_dict["routing_instance_name"] = broadcasts["routing-instance-name"] + broadcast_lst.append(broadcast_dict) + + else: + for broadcast in broadcasts: + broadcast_dict["address"] = broadcast["name"] + if "key" in broadcast.keys(): + broadcast_dict["key"] = broadcast["key"] + if "ttl" in broadcast.keys(): + broadcast_dict["ttl"] = broadcast["ttl"] + if "version" in broadcast.keys(): + broadcast_dict["version"] = broadcast["version"] + if "routing-instance-name" in broadcast.keys(): + broadcast_dict["routing_instance_name"] = broadcast["routing-instance-name"] + broadcast_lst.append(broadcast_dict) + broadcast_dict = {} + if broadcast_lst: + ntp_global_config["broadcasts"] = broadcast_lst + + # Read broadcast-client node + if "broadcast-client" in conf.keys(): + ntp_global_config["broadcast_client"] = True + + # Read interval-range node + if "interval-range" in conf.keys(): + ntp_global_config["interval_range"] = conf["interval-range"].get( + "value", + ) + + # Read multicast-client node + if "multicast-client" in conf.keys(): + ntp_global_config["multicast_client"] = conf["multicast-client"].get("address") + + # Read peer node + if "peer" in conf.keys(): + peer_lst = [] + peers = conf.get("peer") + peer_dict = {} + if isinstance(peers, dict): + peer_dict["peer"] = peers["name"] + if "key" in peers.keys(): + peer_dict["key_id"] = peers["key"] + if "prefer" in peers.keys(): + peer_dict["prefer"] = True + if "version" in peers.keys(): + peer_dict["version"] = peers["version"] + peer_lst.append(peer_dict) + + else: + for peer in peers: + peer_dict["peer"] = peer["name"] + if "key" in peer.keys(): + peer_dict["key_id"] = peer["key"] + if "prefer" in peer.keys(): + peer_dict["prefer"] = True + if "version" in peer.keys(): + peer_dict["version"] = peer["version"] + peer_lst.append(peer_dict) + peer_dict = {} + if peer_lst: + ntp_global_config["peers"] = peer_lst + + # Read server node + if "server" in conf.keys(): + server_lst = [] + servers = conf.get("server") + server_dict = {} + if isinstance(servers, dict): + server_dict["server"] = servers["name"] + if "key" in servers.keys(): + server_dict["key_id"] = servers["key"] + if "prefer" in servers.keys(): + server_dict["prefer"] = True + if "version" in servers.keys(): + server_dict["version"] = servers["version"] + if "routing-instance" in servers.keys(): + server_dict["routing-instance"] = servers["routing-instance"] + server_lst.append(server_dict) + + else: + for server in servers: + server_dict["server"] = server["name"] + if "key" in server.keys(): + server_dict["key_id"] = server["key"] + if "prefer" in server.keys(): + server_dict["prefer"] = True + if "version" in server.keys(): + server_dict["version"] = server["version"] + if "routing-instance" in server.keys(): + server_dict["routing_instance"] = server["routing-instance"] + server_lst.append(server_dict) + server_dict = {} + if server_lst: + ntp_global_config["servers"] = server_lst + + # Read source-address node + if "source-address" in conf.keys(): + source_address_lst = [] + source_addresses = conf.get("source-address") + source_address_dict = {} + if isinstance(source_addresses, dict): + source_address_dict["source_address"] = source_addresses["name"] + if "routing-instance" in source_addresses.keys(): + source_address_dict["routing_instance"] = source_addresses["routing-instance"] + source_address_lst.append(source_address_dict) + + else: + for source_address in source_addresses: + source_address_dict["source_address"] = source_address["name"] + if "routing-instance" in source_address.keys(): + source_address_dict["routing_instance"] = source_address["routing-instance"] + source_address_lst.append(source_address_dict) + source_address_dict = {} + if source_address_lst: + ntp_global_config["source_addresses"] = source_address_lst + + # Read threshold node + if "threshold" in conf.keys(): + threshold = conf.get("threshold") + threshold_dict = {} + if "value" in threshold.keys(): + threshold_dict["value"] = threshold.get("value") + if "action" in threshold.keys(): + threshold_dict["action"] = threshold.get("action") + if threshold_dict: + ntp_global_config["threshold"] = threshold_dict + + # read trusted-keys node + if "trusted-key" in conf.keys(): + trusted_keys = conf.get("trusted-key") + trusted_keys_lst = [] + trusted_keys_dict = {} + if isinstance(trusted_keys, list): + trusted_keys.sort(key=int) + for key in trusted_keys: + trusted_keys_dict["key_id"] = key + trusted_keys_lst.append(trusted_keys_dict) + trusted_keys_dict = {} + ntp_global_config["trusted_keys"] = trusted_keys_lst + else: + trusted_keys_dict["key_id"] = trusted_keys + trusted_keys_lst.append(trusted_keys_dict) + ntp_global_config["trusted_keys"] = trusted_keys_lst + return utils.remove_empties(ntp_global_config) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospf_interfaces/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospf_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospf_interfaces/ospf_interfaces.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospf_interfaces/ospf_interfaces.py new file mode 100644 index 00000000..11a7157c --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospf_interfaces/ospf_interfaces.py @@ -0,0 +1,269 @@ +# +# -*- 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 junos ospf_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 + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + generate_dict, + remove_empties, +) + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.ospf_interfaces.ospf_interfaces import ( + Ospf_interfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.utils.utils import ( + _validate_config, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Ospf_interfacesFacts(object): + """The junos ospf_interfaces fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Ospf_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 = generate_dict(facts_argument_spec) + self.router_id = "" + + def get_connection(self, connection, config_filter): + """ + + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for ospf_interfaces + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + + + + """ + data = self.get_connection(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + + resources = data.xpath("configuration/protocols/ospf") + router_id_path = data.xpath("configuration/routing-options/router-id") + + if router_id_path: + self.router_id = self._get_xml_dict(router_id_path.pop()) + else: + self.router_id = "" + + objs = [] + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + + facts = {"ospf_interfaces": []} + if objs: + params = _validate_config( + self._module, + self.argument_spec, + {"config": objs}, + redact=True, + ) + + for cfg in params["config"]: + facts["ospf_interfaces"].append(remove_empties(cfg)) + + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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 + """ + ospf_interfaces_config = [] + ospf = conf.get("ospf") + + if ospf.get("area"): + areas = ospf.get("area") + + if not isinstance(areas, list): + areas = [areas] + + for area in areas: + rendered_area = {} + rendered_area["area_id"] = area.get("name") + rendered_area["interfaces"] = [] + + interfaces = area["interface"] + if not isinstance(interfaces, list): + interfaces = [interfaces] + for interface in interfaces: + interface_dict = {} + interface_dict["priority"] = interface.get("priority") + interface_dict["metric"] = interface.get("metric") + interface_dict["mtu"] = interface.get("mtu") + interface_dict["te_metric"] = interface.get("te-metric") + interface_dict["ipsec_sa"] = interface.get("ipsec-sa") + interface_dict["hello_interval"] = interface.get( + "hello-interval", + ) + interface_dict["dead_interval"] = interface.get( + "dead-interval", + ) + interface_dict["retransmit_interval"] = interface.get( + "retransmit-interval", + ) + interface_dict["transit_delay"] = interface.get( + "transit-delay", + ) + interface_dict["poll_interval"] = interface.get( + "poll-interval", + ) + if "passive" in interface.keys(): + interface_dict["passive"] = True + if "flood-reduction" in interface.keys(): + interface_dict["flood_reduction"] = True + if "demand-circuit" in interface.keys(): + interface_dict["demand_circuit"] = True + if "no-advertise-adjacency-segment" in interface.keys(): + interface_dict["no_advertise_adjacency_segment"] = True + if "no-eligible-backup" in interface.keys(): + interface_dict["no_eligible_backup"] = True + if "no-eligible-remote-backup" in interface.keys(): + interface_dict["no_eligible_remote_backup"] = True + if "no-interface-state-traps" in interface.keys(): + interface_dict["no_interface_state_traps"] = True + if "no-neighbor-down-notification" in interface.keys(): + interface_dict["no_neighbor_down_notification"] = True + if "node-link-protection" in interface.keys(): + interface_dict["node_link_protection"] = True + if "bandwidth-based-metrics" in interface.keys(): + bandwidth_metrics = interface["bandwidth-based-metrics"].get("bandwidth") + if not isinstance(bandwidth_metrics, list): + bandwidth_metrics = [bandwidth_metrics] + interface_dict["bandwidth_based_metrics"] = [] + + for metric in bandwidth_metrics: + interface_dict["bandwidth_based_metrics"].append( + { + "metric": metric.get("metric"), + "bandwidth": metric.get("name"), + }, + ) + + if "authentication" in interface.keys(): + auth = interface["authentication"] + auth_dict = {} + if auth.get("simple-password"): + auth_dict["simple_password"] = auth.get( + "simple-password", + ) + if "md5" in auth.keys(): + md5_cfg = auth.get("md5") + md5_lst = [] + if isinstance(md5_cfg, dict): + md5_dict = {} + md5_dict["key_id"] = md5_cfg.get("name") + md5_dict["key_value"] = md5_cfg.get("key") + md5_dict["start_time"] = md5_cfg.get("start-time") + md5_lst.append(md5_dict) + else: + for md5 in md5_cfg: + md5_dict = {} + md5_dict["key_id"] = md5.get("name") + md5_dict["key_value"] = md5.get("key") + md5_dict["start_time"] = md5.get("start-time") + md5_lst.append(md5_dict) + auth_dict["md5"] = md5_lst + interface_dict["authentication"] = auth_dict + + rendered_area["interfaces"].append(interface_dict) + + af = {} + conf = {} + areas = {} + address_family = [] + af["afi"] = "ipv4" + areas["area_id"] = rendered_area["area_id"] + interface_dict["area"] = areas + af["processes"] = interface_dict + address_family.append(af) + conf["address_family"] = address_family + conf["name"] = interface.get("name") + if self.router_id: + conf["router_id"] = self.router_id["router-id"] + remove_empties(conf) + ospf_interfaces_config.append(conf) + + return ospf_interfaces_config diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv2/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv2/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv2/ospfv2.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv2/ospfv2.py new file mode 100644 index 00000000..09693296 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv2/ospfv2.py @@ -0,0 +1,322 @@ +# Copyright (C) 2020 Red Hat, Inc. +# +# This program 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. +# +# This program 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 this program. If not, see . +# + + +""" +The junos_ospfv2 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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.ospfv2.ospfv2 import ( + Ospfv2Args, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Ospfv2Facts(object): + """The junos ospf fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Ospfv2Args.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) + self.router_id = "" + + def get_connection(self, connection, config_filter): + """ + + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for ospf + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + + + + """ + data = self.get_connection(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + + resources = data.xpath("configuration/protocols/ospf") + router_id_path = data.xpath("configuration/routing-options/router-id") + if router_id_path: + self.router_id = self._get_xml_dict(router_id_path.pop()) + else: + self.router_id = "" + objs = [] + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + obj = self.render_config(self.generated_spec, xml) + if obj: + objs.append(obj) + + facts = {"ospfv2": []} + if objs is not None: + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + for cfg in params["config"]: + facts["ospfv2"].append(utils.remove_empties(cfg)) + + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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) + ospf = conf.get("ospf") + if ospf.get("area"): + rendered_areas = [] + areas = ospf.get("area") + + if not isinstance(areas, list): + areas = [areas] + + for area in areas: + rendered_area = {} + rendered_area["area_id"] = area.get("name") + rendered_area["interfaces"] = [] + + interfaces = area["interface"] + if not isinstance(interfaces, list): + interfaces = [interfaces] + + for interface in interfaces: + interface_dict = {} + interface_dict["name"] = interface.get("name") + interface_dict["priority"] = interface.get("priority") + interface_dict["metric"] = interface.get("metric") + interface_dict["timers"] = {} + interface_dict["timers"]["hello_interval"] = interface.get( + "hello-interval", + ) + interface_dict["timers"]["dead_interval"] = interface.get( + "dead-interval", + ) + interface_dict["timers"]["retransmit_interval"] = interface.get( + "retransmit-interval", + ) + interface_dict["timers"]["transit_delay"] = interface.get( + "transit-delay", + ) + interface_dict["timers"]["poll_interval"] = interface.get( + "poll-interval", + ) + if "passive" in interface.keys(): + interface_dict["passive"] = True + if "flood-reduction" in interface.keys(): + interface_dict["flood_reduction"] = True + if "bandwidth-based-metrics" in interface.keys(): + bandwidth_metrics = interface["bandwidth-based-metrics"].get("bandwidth") + if not isinstance(bandwidth_metrics, list): + bandwidth_metrics = [bandwidth_metrics] + interface_dict["bandwidth_based_metrics"] = [] + + for metric in bandwidth_metrics: + interface_dict["bandwidth_based_metrics"].append( + { + "metric": metric.get("metric"), + "bandwidth": metric.get("name"), + }, + ) + if "authentication" in interface.keys(): + auth = interface["authentication"] + auth_dict = {} + if auth.get("simple-password"): + auth_dict["type"] = {"simple_password": auth.get("simple-password")} + auth_dict["password"] = auth.get("simple-password") + elif auth.get("md5"): + auth_dict["type"] = {"md5": []} + md5_list = auth.get("md5") + key_lst = [] + if not isinstance(md5_list, list): + key_dict = {} + key_dict["key_id"] = md5_list.get("name") + key_dict["key"] = md5_list.get("key") + key_dict["start_time"] = md5_list.get("start_time") + key_lst.append(key_dict) + md5_list = [md5_list] + else: + for md5_auth in md5_list: + key_dict = {} + key_dict["key_id"] = md5_auth.get("name") + key_dict["key"] = md5_auth.get("key") + key_dict["start_time"] = md5_auth.get("start_time") + + auth_dict["type"]["md5"].append( + { + "key_id": md5_auth.get("name"), + "key": md5_auth.get("key"), + }, + ) + key_lst.append(key_dict) + if key_lst: + auth_dict["md5"] = key_lst + interface_dict["authentication"] = auth_dict + + rendered_area["interfaces"].append(interface_dict) + + if area.get("area-range"): + area_range = area["area-range"] + if not isinstance(area_range, list): + area_range = [area_range] + # Included for compatibility, remove after 2025-07-01 + rendered_area["area_range"] = [] + for a_range in area_range: + rendered_area["area_range"].append(a_range["name"]) + + rendered_area["area_ranges"] = [] + for a_range in area_range: + range = {} + range["address"] = a_range["name"] + if a_range.get("override-metric"): + range["override_metric"] = a_range.get("override-metric") + if "exact" in a_range: + range["exact"] = True + if "restrict" in a_range: + range["restrict"] = True + rendered_area["area_ranges"].append(range) + if area.get("stub"): + rendered_area["stub"] = {"set": True} + if "no-summaries" in area.get("stub").keys(): + rendered_area["stub"]["no_summary"] = True + if "default-metric" in area.get("stub").keys(): + rendered_area["stub"]["default_metric"] = area["stub"].get("default-metric") + if area.get("nssa"): + rendered_area["nssa"] = {"set": True} + if "no-summaries" in area.get("nssa").keys(): + rendered_area["nssa"]["no_summary"] = True + elif "summaries" in area.get("nssa").keys(): + rendered_area["nssa"]["no_summary"] = False + if "default-lsa" in area.get("nssa").keys(): + rendered_area["nssa"]["default-lsa"] = True + rendered_areas.append(rendered_area) + config["areas"] = rendered_areas + if "no-rfc-1583" in ospf.keys(): + config["rfc1583compatibility"] = False + if ospf.get("spf-options"): + config["spf_options"] = {} + config["spf_options"]["delay"] = ospf["spf-options"].get( + "delay", + ) + config["spf_options"]["holddown"] = ospf["spf-options"].get( + "holddown", + ) + config["spf_options"]["rapid_runs"] = ospf["spf-options"].get( + "rapid-runs", + ) + if "no-ignore-our-externals" in ospf["spf-options"]: + config["spf_options"]["no_ignore_our_externals"] = True + if "overload" in ospf.keys(): + overload = ospf.get("overload") + cfg = {} + if "allow-route-leaking" in overload: + cfg["allow_route_leaking"] = True + if "as-external" in overload: + cfg["as_external"] = True + if "stub-network" in overload: + cfg["stub_network"] = True + if overload.get("timeout"): + cfg["timeout"] = overload.get("timeout") + + config["overload"] = cfg + config["preference"] = ospf.get("preference") + config["external_preference"] = ospf.get("external-preference") + config["prefix_export_limit"] = ospf.get("prefix-export-limit") + config["reference_bandwidth"] = ospf.get("reference-bandwidth") + if self.router_id != "": + config["router_id"] = self.router_id["router-id"] + return utils.remove_empties(config) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv3/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv3/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv3/ospfv3.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv3/ospfv3.py new file mode 100644 index 00000000..89655b16 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/ospfv3/ospfv3.py @@ -0,0 +1,284 @@ +# Copyright (C) 2020 Red Hat, Inc. +# +# This program 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. +# +# This program 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 this program. If not, see . +# + + +""" +The junos_ospfv3 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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.ospfv3.ospfv3 import ( + Ospfv3Args, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Ospfv3Facts(object): + """The junos ospfv3 fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Ospfv3Args.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) + self.router_id = "" + + def get_connection(self, connection, config_filter): + """ + + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for ospfv3 + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + + + + """ + data = self.get_connection(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + + resources = data.xpath("configuration/protocols/ospf3") + router_id_path = data.xpath("configuration/routing-options/router-id") + if router_id_path: + self.router_id = self._get_xml_dict(router_id_path.pop()) + else: + self.router_id = "" + + objs = [] + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + obj = self.render_config(self.generated_spec, xml) + if obj: + objs.append(obj) + + facts = {"ospfv3": []} + if objs: + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + for cfg in params["config"]: + facts["ospfv3"].append(utils.remove_empties(cfg)) + + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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) + ospfv3 = conf.get("ospf3") + + if ospfv3.get("area"): + rendered_areas = [] + areas = ospfv3.get("area") + + if not isinstance(areas, list): + areas = [areas] + + for area in areas: + rendered_area = {} + rendered_area["area_id"] = area.get("name") + rendered_area["interfaces"] = [] + + interfaces = area["interface"] + if not isinstance(interfaces, list): + interfaces = [interfaces] + + for interface in interfaces: + interface_dict = {} + interface_dict["name"] = interface.get("name") + interface_dict["priority"] = interface.get("priority") + interface_dict["metric"] = interface.get("metric") + interface_dict["timers"] = {} + interface_dict["timers"]["hello_interval"] = interface.get( + "hello-interval", + ) + interface_dict["timers"]["dead_interval"] = interface.get( + "dead-interval", + ) + interface_dict["timers"]["retransmit_interval"] = interface.get( + "retransmit-interval", + ) + interface_dict["timers"]["transit_delay"] = interface.get( + "transit-delay", + ) + interface_dict["timers"]["poll_interval"] = interface.get( + "poll-interval", + ) + if "passive" in interface.keys(): + interface_dict["passive"] = True + if "flood-reduction" in interface.keys(): + interface_dict["flood_reduction"] = True + if "bandwidth-based-metrics" in interface.keys(): + bandwidth_metrics = interface["bandwidth-based-metrics"].get("bandwidth") + if not isinstance(bandwidth_metrics, list): + bandwidth_metrics = [bandwidth_metrics] + interface_dict["bandwidth_based_metrics"] = [] + + for metric in bandwidth_metrics: + interface_dict["bandwidth_based_metrics"].append( + { + "metric": metric.get("metric"), + "bandwidth": metric.get("name"), + }, + ) + + if "authentication" in interface.keys(): + auth = interface["authentication"] + auth_dict = {} + if auth.get("simple-password"): + auth_dict["type"] = "simple_password" + auth_dict["password"] = auth.get("simple-password") + elif auth.get("md5"): + auth_dict["type"] = {"md5": []} + md5_list = auth.get("md5") + + if not isinstance(md5_list, list): + md5_list = [md5_list] + + for md5_auth in md5_list: + auth_dict["type"]["md5"].append( + { + "key_id": md5_auth.get("name"), + "key": md5_auth.get("key"), + }, + ) + interface_dict["authentication"] = auth_dict + + rendered_area["interfaces"].append(interface_dict) + + if area.get("area-range"): + area_range = area["area-range"] + if not isinstance(area_range, list): + area_range = [area_range] + rendered_area["area_range"] = [] + for a_range in area_range: + rendered_area["area_range"].append(a_range["name"]) + + if area.get("stub"): + rendered_area["stub"] = {"set": True} + if "no-summaries" in area.get("stub").keys(): + rendered_area["stub"]["no_summary"] = True + if "default-metric" in area.get("stub").keys(): + rendered_area["stub"]["default_metric"] = area["stub"].get("default-metric") + if area.get("nssa"): + rendered_area["nssa"] = {"set": True} + if "no-summaries" in area.get("nssa").keys(): + rendered_area["nssa"]["no_summary"] = True + elif "summaries" in area.get("nssa").keys(): + rendered_area["nssa"]["no_summary"] = False + if "default-lsa" in area.get("nssa").keys(): + rendered_area["nssa"]["default-lsa"] = True + rendered_areas.append(rendered_area) + + if "no-rfc-1583" in ospfv3.keys(): + config["rfc1583compatibility"] = False + if ospfv3.get("spf-options"): + config["spf_options"] = {} + config["spf_options"]["delay"] = ospfv3["spf-options"].get( + "delay", + ) + config["spf_options"]["holddown"] = ospfv3["spf-options"].get( + "holddown", + ) + config["spf_options"]["rapid_runs"] = ospfv3["spf-options"].get("rapid-runs") + config["overload"] = ospfv3.get("overload") + config["preference"] = ospfv3.get("preference") + config["external_preference"] = ospfv3.get("external-preference") + config["prefix_export_limit"] = ospfv3.get("prefix-export-limit") + config["reference_bandwidth"] = ospfv3.get("reference-bandwidth") + config["areas"] = rendered_areas + if self.router_id: + config["router_id"] = self.router_id["router-id"] + return utils.remove_empties(config) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/prefix_lists/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/prefix_lists/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/prefix_lists/prefix_lists.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/prefix_lists/prefix_lists.py new file mode 100644 index 00000000..efbf3746 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/prefix_lists/prefix_lists.py @@ -0,0 +1,167 @@ +# +# -*- 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 junos prefix_lists 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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.prefix_lists.prefix_lists import ( + Prefix_listsArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Prefix_listsFacts(object): + """The junos prefix_lists fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Prefix_listsArgs.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_device_data(self, connection, config_filter): + """ + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for bgp_address_family + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + if not HAS_XMLTODICT: + self._module.fail_json(msg="xmltodict is not installed.") + if not data: + config_filter = """ + + + + + + + """ + data = self.get_device_data(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + objs = {} + resources = data.xpath("configuration/policy-options") + + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + + facts = {"prefix_lists": []} + if objs: + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + for cfg in params["config"]: + facts["prefix_lists"].append(utils.remove_empties(cfg)) + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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 + """ + prefix_lists_config = [] + pl_dict = {} + pl_cfg = [] + # Parse facts for routing instances node + prefix_lists = conf["policy-options"].get("prefix-list") + if isinstance(prefix_lists, dict): + pl_cfg.append(prefix_lists) + else: + pl_cfg = prefix_lists + for cfg in pl_cfg: + # Parse attribute name + if cfg.get("name"): + pl_dict["name"] = cfg.get("name") + + # Parse attribute dynamic-db + if "dynamic-db" in cfg.keys(): + pl_dict["dynamic_db"] = True + + # Parse attribute address-prefix + if cfg.get("prefix-list-item"): + addr_prefix = cfg.get("prefix-list-item") + addr_pre_list = [] + if isinstance(addr_prefix, dict): + addr_pre_list.append(addr_prefix["name"]) + else: + for prefix in addr_prefix: + addr_pre_list.append(prefix["name"]) + pl_dict["address_prefixes"] = addr_pre_list + + if pl_dict: + prefix_lists_config.append(pl_dict) + pl_dict = {} + + return prefix_lists_config diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_instances/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_instances/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_instances/routing_instances.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_instances/routing_instances.py new file mode 100644 index 00000000..cc6f8603 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_instances/routing_instances.py @@ -0,0 +1,266 @@ +# +# -*- 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 junos routing_instances 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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.routing_instances.routing_instances import ( + Routing_instancesArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Routing_instancesFacts(object): + """The junos routing_instances fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Routing_instancesArgs.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_device_data(self, connection, config_filter): + """ + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for bgp_address_family + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + if not HAS_XMLTODICT: + self._module.fail_json(msg="xmltodict is not installed.") + if not data: + config_filter = """ + + + + """ + data = self.get_device_data(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + objs = {} + resources = data.xpath("configuration/routing-instances") + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + + facts = {"routing_instances": []} + if objs: + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + for cfg in params["config"]: + facts["routing_instances"].append(utils.remove_empties(cfg)) + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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 + """ + routing_instances_config = [] + + # Parse facts for routing instances node + conf = conf.get("routing-instances") + + # Parse routing instances + routing_instances = conf.get("instance") + if isinstance(routing_instances, list): + for instance in routing_instances: + instance_dict = self.parse_instance(instance) + routing_instances_config.append(instance_dict) + else: + instance_dict = self.parse_instance(routing_instances) + routing_instances_config.append(instance_dict) + + return routing_instances_config + + def parse_instance(self, instance): + """ + + :param instance: + :return: + """ + instance_dict = {} + # read instance name + instance_dict["name"] = instance["name"] + + # read connection-id-advertise + if "connector-id-advertise" in instance.keys(): + instance_dict["connector_id_advertise"] = True + + # read description + if instance.get("description"): + instance_dict["description"] = instance["description"] + + # read instance role + if instance.get("instance-role"): + instance_dict["instance_role"] = instance["instance-role"] + + # read instance type + if instance.get("instance-type"): + instance_dict["type"] = instance["instance-type"] + + # read interfaces + if instance.get("interface"): + interfaces = instance.get("interface") + interfaces_list = [] + if isinstance(interfaces, list): + for interface in interfaces: + interfaces_list.append(self.parse_interface(interface)) + else: + interfaces_list.append(self.parse_interface(interfaces)) + instance_dict["interfaces"] = interfaces_list + + # read l2vpn-id + if instance.get("l2vpn-id"): + instance_dict["l2vpn_id"] = instance["l2vpn-id"].get("community") + + # read no-irb-layer2-copy + if "no-irb-layer2-copy" in instance.keys(): + instance_dict["no_irb_layer_2_copy"] = True + + # read no_local_switching + if "no-local-switching" in instance.keys(): + instance_dict["no_local_switching"] = True + + # read no-vrf-advertise + if "no-vrf-advertise" in instance.keys(): + instance_dict["no_vrf_advertise"] = True + + # read no_vrf_propagate_ttl + if "no-vrf-propagate-ttl" in instance.keys(): + instance_dict["no_vrf_propagate_ttl"] = True + + # read qualified_bum_pruning_mode + if instance.get("qualified-bum-pruning-mode"): + instance_dict["qualified_bum_pruning_mode"] = True + + # read route-distinguisher + if instance.get("route-distinguisher"): + instance_dict["route_distinguisher"] = instance["route-distinguisher"].get("rd-type") + + # read vrf imports + if instance.get("vrf-import"): + vrf_imp_lst = [] + vrf_imp = instance.get("vrf-import") + + if isinstance(vrf_imp, list): + vrf_imp_lst = vrf_imp + else: + vrf_imp_lst.append(vrf_imp) + instance_dict["vrf_imports"] = vrf_imp_lst + + # read vrf exports + if instance.get("vrf-export"): + vrf_exp_lst = [] + vrf_exp = instance.get("vrf-export") + if isinstance(vrf_exp, list): + vrf_exp_lst = vrf_exp + else: + vrf_exp_lst.append(vrf_exp) + instance_dict["vrf_exports"] = vrf_exp_lst + + # read bridge domains + if instance.get("bridge-domains"): + br_domain_lst = [] + br_domains = instance.get("bridge-domains").get("domain") + if isinstance(br_domains, list): + for domain in br_domains: + br_item = { + k.replace("-", "_"): (v if v is not None else True) + for k, v in domain.items() + } + br_domain_lst.append(br_item) + else: + br_item = { + k.replace("-", "_"): (v if v is not None else True) + for k, v in br_domains.items() + } + br_domain_lst.append(br_item) + instance_dict["bridge_domains"] = br_domain_lst + + return utils.remove_empties(instance_dict) + + def parse_interface(self, interface): + """ + + :param instance: + :return: + """ + cfg_dict = {} + cfg_dict["name"] = interface["name"] + if interface.get("protect-interface"): + cfg_dict["protect_interface"] = interface.get("protect-interface") + + return cfg_dict diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_options/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_options/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_options/routing_options.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_options/routing_options.py new file mode 100644 index 00000000..0eb68dd8 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/routing_options/routing_options.py @@ -0,0 +1,149 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The junos routing_options 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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.routing_options.routing_options import ( + Routing_optionsArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Routing_optionsFacts(object): + """The junos routing_options fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Routing_optionsArgs.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_device_data(self, connection, config_filter): + """ + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for routing_options + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + """ + data = self.get_device_data(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + objs = {} + resources = data.xpath("configuration/routing-options") + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + + facts = {"routing_options": []} + if objs: + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + facts["routing_options"] = utils.remove_empties(params["config"]) + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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 + """ + routing_config = {} + conf = conf.get("routing-options") + + # Read autonomous-system + if "autonomous-system" in conf.keys(): + as_num = conf.get("autonomous-system") + as_dict = {} + if "as-number" in as_num.keys(): + as_dict["as_number"] = as_num.get("as-number") + if as_num.get("loops"): + as_dict["loops"] = as_num.get("loops") + if "asdot-notation" in as_num.keys(): + as_dict["asdot_notation"] = True + routing_config["autonomous_system"] = as_dict + + # Read router-id + if "router-id" in conf.keys(): + routing_config["router_id"] = conf.get("router-id") + + return utils.remove_empties(routing_config) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies/security_policies.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies/security_policies.py new file mode 100644 index 00000000..c8b56b34 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies/security_policies.py @@ -0,0 +1,527 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2022 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The junos security_policies 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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.security_policies.security_policies import ( + Security_policiesArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Security_policiesFacts(object): + """The junos security_policies fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Security_policiesArgs.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_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + def _get_device_data(self, connection, config_filters): + """ + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filters) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for security_polices + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + + """ + data = self._get_device_data(connection, config_filter) + + # split the config into instances of the resource + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + objs = {} + resources = data.xpath("configuration/security/policies") + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + + facts = {"security_policies": {}} + if objs: + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + facts["security_policies"] = 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 + """ + security_policies_config = {} + + # Parse facts for security policies + conf = conf.get("policies") or {} + + if "policy" in conf: + security_policies_config["from_zones"] = [] + from_zone_dict = {} + zone_pairs = conf.get("policy") + if isinstance(zone_pairs, dict): + temp = zone_pairs + zone_pairs = [] + zone_pairs.append(temp) + for zone_pair_policies in zone_pairs: + if zone_pair_policies["from-zone-name"] not in from_zone_dict: + from_zone_dict[zone_pair_policies["from-zone-name"]] = {} + from_zone_dict[zone_pair_policies["from-zone-name"]]["name"] = ( + zone_pair_policies["from-zone-name"] + ) + from_zone_dict[zone_pair_policies["from-zone-name"]]["to_zones"] = {} + + from_zone = from_zone_dict[zone_pair_policies["from-zone-name"]] + + from_zone["to_zones"][zone_pair_policies["to-zone-name"]] = {} + to_zone = from_zone["to_zones"][zone_pair_policies["to-zone-name"]] + + to_zone["name"] = zone_pair_policies["to-zone-name"] + to_zone["policies"] = self.parse_policies( + zone_pair_policies["policy"], + ) + + for from_zone in from_zone_dict.values(): + from_zone["to_zones"] = list(from_zone["to_zones"].values()) + security_policies_config["from_zones"].append(from_zone) + + if "global" in conf: + global_policies = conf.get("global") + global_policies = global_policies.get("policy") + security_policies_config["global"] = {} + security_policies_config["global"]["policies"] = self.parse_policies(global_policies) + + return security_policies_config + + def parse_policies(self, policies): + policy_list = [] + + if isinstance(policies, dict): + temp = policies + policies = [] + policies.append(temp) + + for policy in policies: + tmp_policy = {} + + # parse name of policy + tmp_policy["name"] = policy["name"] + + # parse match criteria of security policy + tmp_policy["match"] = {} + + match = tmp_policy["match"] + policy_match = policy["match"] + + match["source_address"] = {} + if isinstance(policy_match["source-address"], string_types): + policy_match["source-address"] = [ + policy_match["source-address"], + ] + for source_address in policy_match["source-address"]: + if source_address == "any-ipv6": + match["source_address"]["any_ipv6"] = True + elif source_address == "any-ipv4": + match["source_address"]["any_ipv4"] = True + elif source_address == "any": + match["source_address"]["any"] = True + else: + if "addresses" not in match["source_address"]: + match["source_address"]["addresses"] = [] + match["source_address"]["addresses"].append(source_address) + + if "source-address-excluded" in policy_match: + match["source_address_excluded"] = True + + match["destination_address"] = {} + if isinstance(policy_match["destination-address"], string_types): + policy_match["destination-address"] = [ + policy_match["destination-address"], + ] + for destination_address in policy_match["destination-address"]: + if destination_address == "any-ipv6": + match["destination_address"]["any_ipv6"] = True + elif destination_address == "any-ipv4": + match["destination_address"]["any_ipv4"] = True + elif destination_address == "any": + match["destination_address"]["any"] = True + else: + if "addresses" not in match["destination_address"]: + match["destination_address"]["addresses"] = [] + match["destination_address"]["addresses"].append( + destination_address, + ) + + if "destination-address-excluded" in policy_match: + match["destination_address_excluded"] = True + + match["application"] = {} + if policy_match["application"] == "any": + match["application"]["any"] = True + else: + if isinstance(policy_match["application"], string_types): + policy_match["application"] = [policy_match["application"]] + match["application"]["names"] = policy_match["application"] + + if "source-end-user-profile" in policy_match: + match["source_end_user_profile"] = policy_match["source-end-user-profile"][ + "source-end-user-profile-name" + ] + + if "source-identity" in policy_match: + if isinstance(policy_match["source-identity"], string_types): + policy_match["source-identity"] = [ + policy_match["source-identity"], + ] + match["source_identity"] = {} + for source_identity in policy_match["source-identity"]: + if source_identity == "any": + match["source_identity"]["any"] = True + elif "authenticated-user" == source_identity: + match["source_identity"]["authenticated_user"] = True + elif "unauthenticated-user" == source_identity: + match["source_identity"]["unauthenticated_user"] = True + elif "unknown-user" == source_identity: + match["source_identity"]["unknown_user"] = True + else: + if "names" not in match["source_identity"]: + match["source_identity"]["names"] = [] + match["source_identity"]["names"].append( + source_identity, + ) + + if "url-category" in policy_match: + if isinstance(policy_match["url-category"], string_types): + policy_match["url-category"] = [ + policy_match["url-category"], + ] + match["url_category"] = {} + for url_category in policy_match["url-category"]: + if url_category == "any": + match["url_category"]["any"] = True + elif url_category == "none": + match["url_category"]["none"] = True + else: + if "names" not in match["url_category"]: + match["url_category"]["names"] = [] + match["url_category"]["names"].append(url_category) + + if "dynamic-application" in policy_match: + if isinstance( + policy_match["dynamic-application"], + string_types, + ): + policy_match["dynamic-application"] = [ + policy_match["dynamic-application"], + ] + match["dynamic_application"] = {} + for dynamic_application in policy_match["dynamic-application"]: + if dynamic_application == "any": + match["dynamic_application"]["any"] = True + elif dynamic_application == "none": + match["dynamic_application"]["none"] = True + else: + if "names" not in match["dynamic_application"]: + match["dynamic_application"]["names"] = [] + match["dynamic_application"]["names"].append( + dynamic_application, + ) + # end of match criteria parsing + + # parse match action of security policy + tmp_policy["then"] = {} + action = tmp_policy["then"] + policy_action = policy["then"] + + if "count" in policy_action: + action["count"] = True + + if "log" in policy_action: + action["log"] = {} + if "session-close" in policy_action["log"]: + action["log"]["session_close"] = True + if "session-init" in policy_action["log"]: + action["log"]["session_init"] = True + + if "deny" in policy_action: + action["deny"] = True + + if "reject" in policy_action: + action["reject"] = {} + reject = action["reject"] + policy_reject = policy_action["reject"] or {} + reject["enable"] = True + + if "profile" in policy_reject: + reject["profile"] = policy_reject["profile"] + if "ssl-proxy" in policy_reject: + policy_reject["ssl-proxy"] = policy_reject["ssl-proxy"] or {} + reject["ssl_proxy"] = {} + reject["ssl_proxy"]["enable"] = True + if "profile-name" in policy_reject["ssl-proxy"]: + reject["ssl_proxy"]["profile_name"] = policy_reject["ssl-proxy"][ + "profile-name" + ] + + if "permit" in policy_action: + action["permit"] = {} + permit = action["permit"] + policy_permit = policy_action["permit"] or {} + + if "application-services" in policy_permit: + permit["application_services"] = {} + application_services = permit["application_services"] + policy_application_services = policy_permit["application-services"] or {} + + if "advanced-anti-malware-policy" in policy_application_services: + application_services["advanced_anti_malware_policy"] = ( + policy_application_services["advanced-anti-malware-policy"] + ) + if "application-traffic-control" in policy_application_services: + application_services["application_traffic_control_rule_set"] = ( + policy_application_services["application-traffic-control"]["rule-set"] + ) + if "gprs-gtp-profile" in policy_application_services: + application_services["gprs_gtp_profile"] = policy_application_services[ + "gprs-gtp-profile" + ] + if "gprs-sctp-profile" in policy_application_services: + application_services["gprs_sctp_profile"] = policy_application_services[ + "gprs-sctp-profile" + ] + if "icap-redirect" in policy_application_services: + application_services["icap_redirect"] = policy_application_services[ + "icap-redirect" + ] + if "idp" in policy_application_services: + application_services["idp"] = True + if "idp-policy" in policy_application_services: + application_services["idp_policy"] = policy_application_services[ + "idp-policy" + ] + if "redirect-wx" in policy_application_services: + application_services["redirect_wx"] = True + if "reverse-redirect-wx" in policy_application_services: + application_services["reverse_redirect_wx"] = True + if "security-intelligence-policy" in policy_application_services: + application_services["security_intelligence_policy"] = ( + policy_application_services["security-intelligence-policy"] + ) + if "ssl-proxy" in policy_application_services: + application_services["ssl_proxy"] = {} + application_services["ssl_proxy"]["enable"] = True + if ( + policy_application_services["ssl-proxy"] + and "profile-name" in policy_application_services["ssl-proxy"] + ): + application_services["ssl_proxy"]["profile_name"] = ( + policy_application_services["ssl-proxy"]["profile-name"] + ) + if "uac-policy" in policy_application_services: + application_services["uac_policy"] = {} + application_services["uac_policy"]["enable"] = True + if ( + policy_application_services["uac-policy"] + and "captive-portal" in policy_application_services["uac-policy"] + ): + application_services["uac_policy"]["captive_portal"] = ( + policy_application_services["uac-policy"]["captive-portal"] + ) + if "utm-policy" in policy_application_services: + application_services["utm_policy"] = policy_application_services[ + "utm-policy" + ] + + if "destination-address" in policy_permit: + permit["destination_address"] = policy_permit["destination-address"] + + if "firewall-authentication" in policy_permit: + permit["firewall_authentication"] = {} + f_a = permit["firewall_authentication"] + policy_f_a = policy_permit["firewall-authentication"] or {} + + if "pass-through" in policy_f_a: + f_a["pass_through"] = {} + if "access-profile" in policy_f_a["pass-through"]: + f_a["pass_through"]["access_profile"] = policy_f_a["pass-through"][ + "access-profile" + ] + if "auth-only-browser" in policy_f_a["pass-through"]: + f_a["pass_through"]["auth_only_browser"] = True + if "auth-user-agent" in policy_f_a["pass-through"]: + f_a["pass_through"]["auth_user_agent"] = policy_f_a["pass-through"][ + "auth-user-agent" + ] + if "client-match" in policy_f_a["pass-through"]: + f_a["pass_through"]["client_match"] = policy_f_a["pass-through"][ + "client-match" + ] + if "ssl-termination-profile" in policy_f_a["pass-through"]: + f_a["pass_through"]["ssl_termination_profile"] = policy_f_a[ + "pass-through" + ]["ssl-termination-profile"] + if "web-redirect" in policy_f_a["pass-through"]: + f_a["pass_through"]["web_redirect"] = True + if "web-redirect-to-https" in policy_f_a["pass-through"]: + f_a["pass_through"]["web_redirect_to_https"] = True + + if "push-to-identity-management" in policy_f_a: + f_a["push_to_identity_management"] = True + + if "user-firewall" in policy_f_a: + f_a["user_firewall"] = {} + if "access-profile" in policy_f_a["user-firewall"]: + f_a["user_firewall"]["access_profile"] = policy_f_a["user-firewall"][ + "access-profile" + ] + if "auth-only-browser" in policy_f_a["user-firewall"]: + f_a["user_firewall"]["auth_only_browser"] = True + if "auth-user-agent" in policy_f_a["user-firewall"]: + f_a["user_firewall"]["auth_user_agent"] = policy_f_a["user-firewall"][ + "auth-user-agent" + ] + if "domain" in policy_f_a["user-firewall"]: + f_a["user_firewall"]["domain"] = policy_f_a["user-firewall"]["domain"] + if "ssl-termination-profile" in policy_f_a["user-firewall"]: + f_a["user_firewall"]["ssl_termination_profile"] = policy_f_a[ + "user-firewall" + ]["ssl-termination-profile"] + if "web-redirect" in policy_f_a["user-firewall"]: + f_a["user_firewall"]["web_redirect"] = True + if "web-redirect-to-https" in policy_f_a["user-firewall"]: + f_a["user_firewall"]["web_redirect_to_https"] = True + + if "web-authentication" in policy_f_a: + f_a["web_authentication"] = [] + if isinstance( + policy_f_a["web-authentication"]["client-match"], + str, + ): + temp = policy_f_a["web-authentication"]["client-match"] + policy_f_a["web-authentication"]["client-match"] = [] + policy_f_a["web-authentication"]["client-match"].append(temp) + f_a["web_authentication"] = policy_f_a["web-authentication"]["client-match"] + + if "tcp-options" in policy_permit: + permit["tcp_options"] = {} + tcp_options = permit["tcp_options"] + policy_tcp_options = policy_permit["tcp-options"] or {} + + if "initial-tcp-mss" in policy_tcp_options: + tcp_options["initial_tcp_mss"] = policy_permit["tcp-options"][ + "initial-tcp-mss" + ] + if "reverse-tcp-mss" in policy_tcp_options: + tcp_options["reverse_tcp_mss"] = policy_permit["tcp-options"][ + "reverse-tcp-mss" + ] + if "sequence-check-required" in policy_tcp_options: + tcp_options["sequence_check_required"] = True + if "syn-check-required" in policy_tcp_options: + tcp_options["syn_check_required"] = True + if "window-scale" in policy_tcp_options: + tcp_options["window_scale"] = True + + if "tunnel" in policy_permit: + permit["tunnel"] = {} + policy_permit["tunnel"] = policy_permit["tunnel"] or {} + if "ipsec-vpn" in policy_permit["tunnel"]: + permit["tunnel"]["ipsec_vpn"] = policy_permit["tunnel"]["ipsec-vpn"] + if "pair-policy" in policy_permit["tunnel"]: + permit["tunnel"]["pair_policy"] = policy_permit["tunnel"]["pair-policy"] + + # end of match action parsing + + # parse description of security policy + if "description" in policy: + tmp_policy["description"] = policy["description"] + + # parse scheduler name of security policy + if "scheduler-name" in policy: + tmp_policy["scheduler_name"] = policy["scheduler-name"] + + test = utils.remove_empties(tmp_policy) + policy_list.append(test) + + return policy_list diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies_global/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies_global/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies_global/security_policies_global.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies_global/security_policies_global.py new file mode 100644 index 00000000..cce040cf --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_policies_global/security_policies_global.py @@ -0,0 +1,244 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2022 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The junos security_policies_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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.security_policies_global.security_policies_global import ( + Security_policies_globalArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Security_policies_globalFacts(object): + """The junos security_policies_global fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Security_policies_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 _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + def _get_device_data(self, connection, config_filters): + """ + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filters) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for security_polices + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + + """ + data = self._get_device_data(connection, config_filter) + + # split the config into instances of the resource + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + objs = {} + resources = data.xpath("configuration/security/policies") + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + + facts = {"security_policies_global": {}} + if objs: + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + facts["security_policies_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 + """ + security_policies_global_config = {} + + # Parse facts for security policies global settings + global_policies = conf.get("policies") or {} + + if "default-policy" in global_policies: + if "deny-all" in global_policies["default-policy"]: + security_policies_global_config["default_policy"] = "deny-all" + elif "permit-all" in global_policies["default-policy"]: + security_policies_global_config["default_policy"] = "permit-all" + + if "policy-rematch" in global_policies: + security_policies_global_config["policy_rematch"] = {} + security_policies_global_config["policy_rematch"]["enable"] = True + + global_policies["policy-rematch"] = global_policies["policy-rematch"] or {} + if "extensive" in global_policies["policy-rematch"]: + security_policies_global_config["policy_rematch"]["extensive"] = True + + if "policy-stats" in global_policies: + security_policies_global_config["policy_stats"] = {} + security_policies_global_config["policy_stats"]["enable"] = True + + global_policies["policy-stats"] = global_policies["policy-stats"] or {} + if "system-wide" in global_policies["policy-stats"]: + if global_policies["policy-stats"]["system-wide"] == "enable": + security_policies_global_config["policy_stats"]["system_wide"] = True + elif global_policies["policy-stats"]["system-wide"] == "disable": + security_policies_global_config["policy_stats"]["system_wide"] = False + + if "pre-id-default-policy" in global_policies: + security_policies_global_config["pre_id_default_policy_action"] = {} + pre_id_action = security_policies_global_config["pre_id_default_policy_action"] + policy_pre_id_action = global_policies["pre-id-default-policy"]["then"] + + if "log" in policy_pre_id_action: + pre_id_action["log"] = {} + if "session-close" in policy_pre_id_action["log"]: + pre_id_action["log"]["session_close"] = True + if "session-init" in policy_pre_id_action["log"]: + pre_id_action["log"]["session_init"] = True + + if "session-timeout" in policy_pre_id_action: + pre_id_action["session_timeout"] = {} + if "icmp" in policy_pre_id_action["session-timeout"]: + pre_id_action["session_timeout"]["icmp"] = policy_pre_id_action[ + "session-timeout" + ]["icmp"] + if "icmp6" in policy_pre_id_action["session-timeout"]: + pre_id_action["session_timeout"]["icmp6"] = policy_pre_id_action[ + "session-timeout" + ]["icmp6"] + if "ospf" in policy_pre_id_action["session-timeout"]: + pre_id_action["session_timeout"]["ospf"] = policy_pre_id_action[ + "session-timeout" + ]["ospf"] + if "others" in policy_pre_id_action["session-timeout"]: + pre_id_action["session_timeout"]["others"] = policy_pre_id_action[ + "session-timeout" + ]["others"] + if "tcp" in policy_pre_id_action["session-timeout"]: + pre_id_action["session_timeout"]["tcp"] = policy_pre_id_action[ + "session-timeout" + ]["tcp"] + if "udp" in policy_pre_id_action["session-timeout"]: + pre_id_action["session_timeout"]["udp"] = policy_pre_id_action[ + "session-timeout" + ]["udp"] + + if "traceoptions" in global_policies: + security_policies_global_config["traceoptions"] = {} + traceoptions = security_policies_global_config["traceoptions"] + policy_traceoptions = global_policies["traceoptions"] + + if "file" in policy_traceoptions: + traceoptions["file"] = {} + if "files" in policy_traceoptions["file"]: + traceoptions["file"]["files"] = policy_traceoptions["file"]["files"] + if "match" in policy_traceoptions["file"]: + traceoptions["file"]["match"] = policy_traceoptions["file"]["match"] + if "size" in policy_traceoptions["file"]: + traceoptions["file"]["size"] = policy_traceoptions["file"]["size"] + if "world-readable" in policy_traceoptions["file"]: + traceoptions["file"]["world_readable"] = True + if "no-world-readable" in policy_traceoptions["file"]: + traceoptions["file"]["no_world_readable"] = True + + if "flag" in policy_traceoptions: + traceoptions["flag"] = {} + + if policy_traceoptions["flag"]["name"] == "all": + traceoptions["flag"] = "all" + elif policy_traceoptions["flag"]["name"] == "configuration": + traceoptions["flag"] = "configuration" + elif policy_traceoptions["flag"]["name"] == "compilation": + traceoptions["flag"] = "compilation" + elif policy_traceoptions["flag"]["name"] == "ipc": + traceoptions["flag"] = "ipc" + elif policy_traceoptions["flag"]["name"] == "lookup": + traceoptions["flag"] = "lookup" + elif policy_traceoptions["flag"]["name"] == "routing-socket": + traceoptions["flag"] = "routing-socket" + elif policy_traceoptions["flag"]["name"] == "rules": + traceoptions["flag"] = "rules" + + if "no-remote-trace" in policy_traceoptions: + traceoptions["no_remote_trace"] = True + + return security_policies_global_config diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_zones/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_zones/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_zones/security_zones.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_zones/security_zones.py new file mode 100644 index 00000000..f33085cd --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/security_zones/security_zones.py @@ -0,0 +1,336 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2022 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The junos security_zones 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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.security_zones.security_zones import ( + Security_zonesArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Security_zonesFacts(object): + """The junos security_zones fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Security_zonesArgs.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_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + def _get_device_data(self, connection, config_filters): + """ + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filters) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for security_polices + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + + + """ + data = self._get_device_data(connection, config_filter) + + # split the config into instances of the resource + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + objs = {} + resources = data.xpath("configuration/security/zones") + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + + facts = {"security_zones": {}} + if objs: + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + facts["security_zones"] = 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 + """ + security_zones_config = {} + + # Parse facts for security zones + conf = conf.get("zones") + + if "functional-zone" in conf: + security_zones_config["functional_zone_management"] = {} + functional_zone_management = conf.get("functional-zone").get("management") or {} + + if "description" in functional_zone_management: + security_zones_config["functional_zone_management"]["description"] = ( + functional_zone_management["description"] + ) + + if "host-inbound-traffic" in functional_zone_management: + security_zones_config["functional_zone_management"]["host_inbound_traffic"] = ( + self.parse_host_inbound_traffic( + functional_zone_management["host-inbound-traffic"], + ) + ) + + if "interfaces" in functional_zone_management: + if isinstance(functional_zone_management["interfaces"], dict): + functional_zone_management["interfaces"] = [ + functional_zone_management["interfaces"], + ] + security_zones_config["functional_zone_management"]["interfaces"] = [ + interface["name"] for interface in functional_zone_management["interfaces"] + ] + + if "screen" in functional_zone_management: + security_zones_config["functional_zone_management"]["screen"] = ( + functional_zone_management["screen"] + ) + + if "security-zone" in conf: + security_zones_list = conf.get("security-zone") + if isinstance(security_zones_list, dict): + security_zones_list = [security_zones_list] + security_zones_config["zones"] = [] + + for security_zone in security_zones_list: + temp_sec_zone = {} + temp_sec_zone["name"] = security_zone["name"] + + if "address-book" in security_zone: + temp_sec_zone["address_book"] = {} + + if "address" in security_zone["address-book"]: + temp_sec_zone["address_book"]["addresses"] = [] + if isinstance( + security_zone["address-book"]["address"], + dict, + ): + security_zone["address-book"]["address"] = [ + security_zone["address-book"]["address"], + ] + + for address in security_zone["address-book"]["address"]: + temp_address = {} + + temp_address["name"] = address["name"] + if "ip-prefix" in address: + temp_address["ip_prefix"] = address["ip-prefix"] + elif "dns-name" in address: + temp_address["dns_name"] = {} + temp_address["dns_name"]["name"] = address["dns-name"]["name"] + if "ipv4-only" in address["dns-name"]: + temp_address["dns_name"]["ipv4_only"] = True + if "ipv6-only" in address["dns-name"]: + temp_address["dns_name"]["ipv6_only"] = True + elif "range-address" in address: + temp_address["range_address"] = {} + temp_address["range_address"]["from"] = address["range-address"][ + "name" + ] + temp_address["range_address"]["to"] = address["range-address"][ + "to" + ]["range-high"] + elif "wildcard-address" in address: + temp_address["wildcard_address"] = address["wildcard-address"][ + "name" + ] + if "description" in address: + temp_address["description"] = address["description"] + + temp_sec_zone["address_book"]["addresses"].append( + temp_address, + ) + + if "address-set" in security_zone["address-book"]: + temp_sec_zone["address_book"]["address_sets"] = [] + + for address_set in security_zone["address-book"]["address-set"]: + temp_address_set = {} + + temp_address_set["name"] = address_set["name"] + if "address" in address_set: + if isinstance(address_set["address"], dict): + address_set["address"] = [ + address_set["address"], + ] + temp_address_set["addresses"] = [ + address["name"] for address in address_set["address"] + ] + if "address-set" in address_set: + if isinstance( + address_set["address-set"], + dict, + ): + address_set["address-set"] = [ + address_set["address-set"], + ] + temp_address_set["address_sets"] = [ + addr_set["name"] for addr_set in address_set["address-set"] + ] + if "description" in address_set: + temp_address_set["description"] = address_set["description"] + + temp_sec_zone["address_book"]["address_sets"].append(temp_address_set) + + if "advance-policy-based-routing-profile" in security_zone: + temp_sec_zone["advance_policy_based_routing_profile"] = security_zone[ + "advance-policy-based-routing-profile" + ]["profile"] + if "advanced-connection-tracking" in security_zone: + temp_sec_zone["advanced_connection_tracking"] = {} + temp_act = temp_sec_zone["advanced_connection_tracking"] + if "mode" in security_zone["advanced-connection-tracking"]: + temp_act["mode"] = security_zone["advanced-connection-tracking"]["mode"] + if "timeout" in security_zone["advanced-connection-tracking"]: + temp_act["timeout"] = security_zone["advanced-connection-tracking"][ + "timeout" + ] + if ( + "track-all-policies-to-this-zone" + in security_zone["advanced-connection-tracking"] + ): + temp_act["track_all_policies_to_this_zone"] = True + if "application-tracking" in security_zone: + temp_sec_zone["application_tracking"] = True + if "description" in security_zone: + temp_sec_zone["description"] = security_zone["description"] + if "enable-reverse-reroute" in security_zone: + temp_sec_zone["enable_reverse_reroute"] = True + if "host-inbound-traffic" in security_zone: + temp_sec_zone["host_inbound_traffic"] = self.parse_host_inbound_traffic( + security_zone["host-inbound-traffic"], + ) + if "interfaces" in security_zone: + if isinstance(security_zone["interfaces"], dict): + security_zone["interfaces"] = [ + security_zone["interfaces"], + ] + else: + temp_sec_zone["interfaces"] = [ + interface["name"] for interface in security_zone["interfaces"] + ] + if "screen" in security_zone: + temp_sec_zone["screen"] = security_zone["screen"] + if "source-identity-log" in security_zone: + temp_sec_zone["source_identity_log"] = True + if "tcp-rst" in security_zone: + temp_sec_zone["tcp_rst"] = True + if "unidirectional-session-refreshing" in security_zone: + temp_sec_zone["unidirectional_session_refreshing"] = True + + security_zones_config["zones"].append(temp_sec_zone) + + return security_zones_config + + def parse_host_inbound_traffic(self, host_inbound_traffic): + temp_hit = {} + + if "protocols" in host_inbound_traffic: + temp_hit["protocols"] = [] + if isinstance(host_inbound_traffic["protocols"], dict): + host_inbound_traffic["protocols"] = [ + host_inbound_traffic["protocols"], + ] + for protocol in host_inbound_traffic["protocols"]: + temp_protocol = {} + temp_protocol["name"] = protocol["name"] + if "except" in protocol: + temp_protocol["except"] = True + + temp_hit["protocols"].append(temp_protocol) + + if "system-services" in host_inbound_traffic: + temp_hit["system_services"] = [] + if isinstance(host_inbound_traffic["system-services"], dict): + host_inbound_traffic["system-services"] = [ + host_inbound_traffic["system-services"], + ] + for system_services in host_inbound_traffic["system-services"]: + temp_system_services = {} + temp_system_services["name"] = system_services["name"] + if "except" in system_services: + temp_system_services["except"] = True + + temp_hit["system_services"].append(temp_system_services) + + return temp_hit diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/snmp_server/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/snmp_server/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/snmp_server/snmp_server.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/snmp_server/snmp_server.py new file mode 100644 index 00000000..cb8da46c --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/snmp_server/snmp_server.py @@ -0,0 +1,850 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The junos snmp_server 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._text import to_bytes +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.snmp_server.snmp_server import ( + Snmp_serverArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Snmp_serverFacts(object): + """The junos snmp_server fact class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Snmp_serverArgs.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_device_data(self, connection, config_filter): + """ + :param connection: + :param config_filter: + :return: + """ + return connection.get_configuration(filter=config_filter) + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for ntp_gloabl + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + """ + data = self.get_device_data(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + objs = {} + resources = data.xpath("configuration/snmp") + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + objs = self.render_config(self.generated_spec, xml) + + facts = {"snmp_server": {}} + if objs: + params = utils.validate_config( + self.argument_spec, + {"config": objs}, + ) + + facts["snmp_server"] = utils.remove_empties(params["config"]) + ansible_facts["ansible_network_resources"].update(facts) + return ansible_facts + + def _get_xml_dict(self, xml_root): + if not HAS_XMLTODICT: + self._module.fail_json(msg=missing_required_lib("xmltodict")) + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + 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 + """ + snmp_server_config = {} + + # Parse facts for BGP address-family global node + conf = conf.get("snmp") + + # Read arp node + if "arp" in conf.keys(): + arp = conf.get("arp") + arp_dict = {} + if arp is None: + arp_dict["set"] = True + elif "host-name-resolution" in arp.keys(): + arp_dict["host_name_resolution"] = True + snmp_server_config["arp"] = arp_dict + + # Read client_lists node + if "client-list" in conf.keys(): + snmp_server_config["client_lists"] = self.get_client_list( + conf.get("client-list"), + ) + + # Read communities node + if "community" in conf.keys(): + comm_lst = [] + comm_lists = conf.get("community") + + if isinstance(comm_lists, dict): + comm_lst.append(self.get_community(comm_lists)) + else: + for item in comm_lists: + comm_lst.append(self.get_community(item)) + if comm_lst: + snmp_server_config["communities"] = comm_lst + + # Read routing-instance-access + if "routing-instance-access" in conf.keys(): + rinst_access = conf.get("routing-instance-access") + rints_dict = {} + access_lst = [] + if rinst_access is None: + rints_dict["set"] = True + else: + access_lists = rinst_access.get("access-list") + if isinstance(access_lists, dict): + access_lst.append(access_lists["name"]) + else: + for item in access_lists: + access_lst.append(item["name"]) + rints_dict["access_lists"] = access_lst + snmp_server_config["routing_instance_access"] = rints_dict + + # Read contact + if "contact" in conf.keys(): + snmp_server_config["contact"] = conf.get("contact") + + # Read description + if "description" in conf.keys(): + snmp_server_config["description"] = conf.get("description") + + # Read customization + if "customization" in conf.keys(): + custom_dict = {} + if "ether-stats-ifd-only" in conf["customization"].keys(): + custom_dict["ether_stats_ifd_only"] = True + snmp_server_config["customization"] = custom_dict + + # Read engine-id + if "engine-id" in conf.keys(): + engine_id = conf.get("engine-id") + engine_id_dict = {} + if "local" in engine_id.keys(): + engine_id_dict["local"] = engine_id["local"] + elif "use-default-ip-address" in engine_id.keys(): + engine_id_dict["use_default_ip_address"] = True + else: + engine_id_dict["use_mac_address"] = True + + snmp_server_config["engine_id"] = engine_id_dict + + # Read filter-duplicates + if "filter-duplicates" in conf.keys(): + snmp_server_config["filter_duplicates"] = True + + # Read filter-interfaces + if "filter-interfaces" in conf.keys(): + filter_dict = {} + filter_interfaces = conf.get("filter-interfaces") + + if filter_interfaces is None: + filter_dict["set"] = True + else: + if "all-internal-interfaces" in filter_interfaces.keys(): + filter_dict["all_internal_interfaces"] = True + if "interfaces" in filter_interfaces.keys(): + int_lst = [] + interfaces = filter_interfaces.get("interfaces") + if isinstance(interfaces, dict): + int_lst.append(interfaces["name"]) + else: + for item in interfaces: + int_lst.append(item["name"]) + filter_dict["interfaces"] = int_lst + + snmp_server_config["filter_interfaces"] = filter_dict + + # Read health_monitor + if "health-monitor" in conf.keys(): + health_dict = {} + health_monitor = conf.get("health-monitor") + + if health_monitor is None: + health_dict["set"] = True + else: + if "idp" in health_monitor.keys(): + health_dict["idp"] = True + if "falling-threshold" in health_monitor.keys(): + health_dict["falling_threshold"] = health_monitor["falling-threshold"] + if "rising-threshold" in health_monitor.keys(): + health_dict["rising_threshold"] = health_monitor["rising-threshold"] + if "interval" in health_monitor.keys(): + health_dict["interval"] = health_monitor["interval"] + snmp_server_config["health_monitor"] = health_dict + + # Read if-count-with-filter-interfaces + if "if-count-with-filter-interfaces" in conf.keys(): + snmp_server_config["if_count_with_filter_interfaces"] = True + + # Read interfaces + if "interfaces" in conf.keys(): + int_lst = [] + interfaces = conf.get("interfaces") + if isinstance(interfaces, dict): + int_lst.append(interfaces["name"]) + else: + for item in interfaces: + int_lst.append(item["name"]) + + snmp_server_config["interfaces"] = int_lst + + # Read location + if "location" in conf.keys(): + snmp_server_config["location"] = conf.get("location") + + # Read logical-system-trap-filter + if "logical-system-trap-filter" in conf.keys(): + snmp_server_config["logical_system_trap_filter"] = True + + # Read name + if "system-name" in conf.keys(): + snmp_server_config["name"] = conf.get("system-name") + + # Read nonvolatile + if "nonvolatile" in conf.keys(): + cfg_dict = {} + cfg_dict["commit_delay"] = conf["nonvolatile"].get("commit-delay") + snmp_server_config["nonvolatile"] = cfg_dict + + # Read rmon + if "rmon" in conf.keys(): + cfg_dict = {} + events = [] + alarms = [] + rmon = conf.get("rmon") + + if rmon is None: + cfg_dict["set"] = True + else: + if "event" in rmon.keys(): + event = rmon.get("event") + if isinstance(event, dict): + events.append(self.get_events(event)) + else: + for item in event: + events.append(self.get_events(item)) + cfg_dict["events"] = events + if "alarm" in rmon.keys(): + alarm = rmon.get("alarm") + if isinstance(alarm, dict): + alarms.append(self.get_alarms(alarm)) + else: + for item in alarm: + alarms.append(self.get_alarms(item)) + cfg_dict["alarms"] = alarms + + snmp_server_config["rmon"] = cfg_dict + + # Read subagent node + if "subagent" in conf.keys(): + cfg_dict = {} + subagent = conf.get("subagent") + + if "tcp" in subagent.keys(): + tcp = subagent.get("tcp") + tcp_dict = {} + if tcp is None: + tcp_dict["set"] = True + else: + tcp_dict["routing_instances_default"] = True + cfg_dict["tcp"] = tcp_dict + snmp_server_config["subagent"] = cfg_dict + + # Read traceoptions node + if "traceoptions" in conf.keys(): + cfg_dict = {} + trace_options = conf.get("traceoptions") + + if "file" in trace_options.keys(): + cfg_dict["file"] = self.get_trace_file( + trace_options.get("file"), + ) + if "flag" in trace_options.keys(): + cfg_dict["flag"] = self.get_trace_flag( + trace_options.get("flag"), + ) + if "memory-trace" in trace_options.keys(): + mtrace = trace_options.get("memory-trace") + trace_dict = {} + if mtrace is None: + trace_dict["set"] = True + else: + trace_dict["size"] = mtrace.get("size") + cfg_dict["memory_trace"] = trace_dict + if "no-remote-trace" in conf.keys(): + cfg_dict["no_remote_trace"] = True + + snmp_server_config["traceoptions"] = cfg_dict + + # Read trap-group node + if "trap-group" in conf.keys(): + cfg_lst = [] + trap_groups = conf.get("trap-group") + + if isinstance(trap_groups, dict): + cfg_lst.append(self.get_trap_group(trap_groups)) + else: + for item in trap_groups: + cfg_lst.append(self.get_trap_group(item)) + + snmp_server_config["trap_groups"] = cfg_lst + + # Read trap-options node + if "trap-options" in conf.keys(): + cfg_dict = {} + trap_options = conf.get("trap-options") + if trap_options is None: + cfg_dict["set"] = True + else: + if "agent-address" in trap_options.keys(): + agent_dict = {} + agent_dict["outgoing_interface"] = True + cfg_dict["agent_address"] = agent_dict + if "context-oid" in trap_options.keys(): + cfg_dict["context_oid"] = True + if "enterprise-oid" in trap_options.keys(): + cfg_dict["enterprise_oid"] = True + if "source-address" in trap_options.keys(): + source_address = trap_options.get("source-address") + source_dict = {} + if "address" in source_address.keys(): + source_dict["address"] = source_address["address"] + if "lowest-loopback" in source_address.keys(): + source_dict["lowest_loopback"] = True + cfg_dict["source_address"] = source_dict + if "routing-instance" in trap_options.keys(): + cfg_dict["routing_instance"] = trap_options.get( + "routing-instance", + ) + + snmp_server_config["trap_options"] = cfg_dict + + # Read snmp-v3 + if "v3" in conf.keys(): + cfg_dict = {} + snmp_v3 = conf.get("v3") + + if "notify" in snmp_v3.keys(): + notify_lst = [] + notify = snmp_v3.get("notify") + if isinstance(notify, dict): + notify_lst.append(self.get_notify(notify)) + else: + for item in notify: + notify_lst.append(self.get_notify(item)) + cfg_dict["notify"] = notify_lst + if "notify-filter" in snmp_v3.keys(): + notify_filter = snmp_v3.get("notify-filter") + notify_lst = [] + if isinstance(notify_filter, dict): + notify_lst.append(self.get_notify_filter(notify_filter)) + else: + for item in notify_filter: + notify_lst.append(self.get_notify_filter(item)) + cfg_dict["notify_filter"] = notify_lst + + if "snmp-community" in snmp_v3.keys(): + comm_lst = [] + communities = snmp_v3.get("snmp-community") + if isinstance(communities, dict): + comm_lst.append(self.get_snmpv3_comm(communities)) + else: + for item in communities: + comm_lst.append(self.get_snmpv3_comm(item)) + cfg_dict["snmp_community"] = comm_lst + + if "target-address" in snmp_v3.keys(): + tar_addr_lst = [] + tar_addr = snmp_v3.get("target-address") + if isinstance(tar_addr, dict): + tar_addr_lst.append(self.get_snmpv3_target(tar_addr)) + else: + for item in tar_addr: + tar_addr_lst.append(self.get_snmpv3_target(item)) + cfg_dict["target_addresses"] = tar_addr_lst + + if "target-parameters" in snmp_v3.keys(): + tar_param_lst = [] + tar_params = snmp_v3.get("target-parameters") + if isinstance(tar_params, dict): + tar_param_lst.append(self.get_snmpv3_param(tar_params)) + else: + for item in tar_params: + tar_param_lst.append(self.get_snmpv3_param(item)) + cfg_dict["target_parameters"] = tar_param_lst + + if "usm" in snmp_v3.keys(): + usm_dict = {} + usm = snmp_v3.get("usm") + if "local-engine" in usm.keys(): + local_dict = {} + local_engine = usm.get("local-engine") + if "user" in local_engine.keys(): + user_lst = [] + users = local_engine.get("user") + if isinstance(users, dict): + user_lst.append(self.get_user(users)) + else: + for item in users: + user_lst.append(self.get_user(item)) + local_dict["users"] = user_lst + + usm_dict["local_engine"] = local_dict + + if "remote-engine" in usm.keys(): + remote_lst = [] + remote_dict = {} + remote_engine = usm.get("remote-engine") + if isinstance(remote_engine, dict): + remote_dict["id"] = remote_engine["name"] + if "user" in remote_engine.keys(): + user_lst = [] + users = remote_engine.get("user") + if isinstance(users, dict): + user_lst.append(self.get_user(users)) + else: + for item in users: + user_lst.append(self.get_user(item)) + remote_dict["users"] = user_lst + remote_lst.append(remote_dict) + else: + for remote_eng in remote_engine: + remote_dict["id"] = remote_eng["name"] + if "user" in remote_eng.keys(): + user_lst = [] + users = remote_eng.get("user") + if isinstance(users, dict): + user_lst.append(self.get_user(users)) + else: + for item in users: + user_lst.append(self.get_user(item)) + remote_dict["users"] = user_lst + remote_lst.append(remote_dict) + remote_dict = {} + usm_dict["remote_engine"] = remote_lst + cfg_dict["usm"] = usm_dict + + snmp_server_config["snmp_v3"] = cfg_dict + + # Read view + if "view" in conf.keys(): + cfg_lst = [] + views = conf.get("view") + if isinstance(views, dict): + cfg_lst.append(self.get_view(views)) + else: + for item in views: + cfg_lst.append(self.get_view(item)) + + snmp_server_config["views"] = cfg_lst + return utils.remove_empties(snmp_server_config) + + def get_view(self, cfg): + cfg_dict = {} + cfg_dict["name"] = cfg["name"] + if "oid" in cfg.keys(): + oid_lst = [] + oid_dict = {} + oids = cfg.get("oid") + if isinstance(oids, list): + for item in oids: + oid_dict["oid"] = item["name"] + if "exclude" in item.keys(): + oid_dict["exclude"] = True + if "include" in item.keys(): + oid_dict["include"] = True + oid_lst.append(oid_dict) + oid_dict = {} + else: + oid_dict["oid"] = oids["name"] + if "exclude" in oids.keys(): + oid_dict["exclude"] = True + if "include" in oids.keys(): + oid_dict["include"] = True + oid_lst.append(oid_dict) + cfg_dict["oids"] = oid_lst + + return cfg_dict + + def get_user(self, cfg): + cfg_dict = {} + cfg_dict["name"] = cfg.get("name") + if "authentication-md5" in cfg.keys(): + auth_dict = {} + auth_md5 = cfg.get("authentication-md5") + auth_dict["key"] = auth_md5["authentication-key"] + if "authentication-password" in auth_md5.keys(): + auth_dict["password"] = auth_md5["authentication-password"] + cfg_dict["authentication_md5"] = auth_dict + if "authentication-none" in cfg.keys(): + cfg_dict["authentication_none"] = True + if "authentication-sha" in cfg.keys(): + auth_dict = {} + auth_sha = cfg.get("authentication-sha") + auth_dict["key"] = auth_sha["authentication-key"] + if "authentication-password" in auth_sha.keys(): + auth_dict["password"] = auth_sha["authentication-password"] + cfg_dict["authentication_sha"] = auth_dict + if "privacy-3des" in cfg.keys(): + pri_dict = {} + pri_3des = cfg.get("privacy-3des") + pri_dict["key"] = pri_3des["privacy-key"] + if "privacy-password" in pri_3des.keys(): + pri_dict["password"] = pri_3des["privacy-password"] + cfg_dict["privacy_3des"] = pri_dict + if "privacy-aes128" in cfg.keys(): + pri_dict = {} + pri_aes = cfg.get("privacy-aes128") + pri_dict["key"] = pri_aes["privacy-key"] + if "privacy-password" in pri_aes.keys(): + pri_dict["password"] = pri_aes["privacy-password"] + cfg_dict["privacy_aes128"] = pri_dict + if "privacy-none" in cfg.keys(): + cfg_dict["privacy_none"] = True + return cfg_dict + + def get_snmpv3_param(self, cfg): + cfg_dict = {} + cfg_dict["name"] = cfg.get("name") + if "notify-filter" in cfg.keys(): + cfg_dict["notify_filter"] = cfg.get("notify-filter") + if "parameters" in cfg.keys(): + param_dict = {} + parameters = cfg.get("parameters") + for key in parameters.keys(): + param_dict[key.replace("-", "_")] = parameters.get(key) + cfg_dict["parameters"] = param_dict + return cfg_dict + + def get_snmpv3_target(self, cfg): + cfg_dict = {} + for key in cfg.keys(): + cfg_dict[key.replace("-", "_")] = cfg.get(key) + return cfg_dict + + def get_snmpv3_comm(self, cfg): + cfg_dict = {} + cfg_dict["community_index"] = cfg["name"] + if "context" in cfg.keys(): + cfg_dict["context"] = cfg.get("context") + if "tag" in cfg.keys(): + cfg_dict["tag"] = cfg.get("tag") + if "security-name" in cfg.keys(): + cfg_dict["security_name"] = cfg.get("security-name") + if "community-name" in cfg.keys(): + cfg_dict["community_name"] = cfg.get("community-name") + return cfg_dict + + def get_notify_filter(self, cfg): + cfg_dict = {} + cfg_dict["name"] = cfg["name"] + if "oid" in cfg.keys(): + oid_lst = [] + oid_dict = {} + oids = cfg.get("oid") + if isinstance(oids, list): + for item in oids: + oid_dict["oid"] = item["name"] + if "exclude" in item.keys(): + oid_dict["exclude"] = True + if "include" in item.keys(): + oid_dict["include"] = True + oid_lst.append(oid_dict) + oid_dict = {} + else: + oid_dict["oid"] = oids["name"] + if "exclude" in oids.keys(): + oid_dict["exclude"] = True + if "include" in oids.keys(): + oid_dict["include"] = True + oid_lst.append(oid_dict) + cfg_dict["oids"] = oid_lst + return cfg_dict + + def get_notify(self, cfg): + cfg_dict = {} + cfg_dict["name"] = cfg["name"] + if "type" in cfg.keys(): + cfg_dict["type"] = cfg.get("type") + if "tag" in cfg.keys(): + cfg_dict["tag"] = cfg.get("tag") + + return cfg_dict + + def get_trap_group(self, cfg): + cfg_dict = {} + cfg_dict["name"] = cfg.get("name") + if "categories" in cfg.keys(): + categories_dict = {} + categories = cfg.get("categories") + for item in categories.keys(): + if item == "otn-alarms": + otn_dict = {} + otn_alarms = categories.get("otn-alarms") + for key in otn_alarms.keys(): + otn_dict[key.replace("-", "_")] = True + categories_dict["otn_alarms"] = otn_dict + else: + categories_dict[item.replace("-", "_")] = True + cfg_dict["categories"] = categories_dict + if "destination-port" in cfg.keys(): + cfg_dict["destination_port"] = cfg.get("destination-port") + if "routing-instance" in cfg.keys(): + cfg_dict["routing_instance"] = cfg.get("routing-instance") + if "version" in cfg.keys(): + cfg_dict["version"] = cfg.get("version") + if "targets" in cfg.keys(): + targets_lst = [] + targets = cfg.get("targets") + if isinstance(targets, dict): + targets_lst.append(targets["name"]) + else: + for item in targets: + targets_lst.append(item["name"]) + cfg_dict["targets"] = targets_lst + + return cfg_dict + + def get_trace_flag(self, cfg): + cfg_dict = {} + if isinstance(cfg, dict): + cfg_dict[cfg["name"].replace("-", "_")] = True + else: + for item in cfg: + cfg_dict[item["name"].replace("-", "_")] = True + + return cfg_dict + + def get_trace_file(self, cfg): + cfg_dict = {} + if "match" in cfg.keys(): + cfg_dict["match"] = cfg.get("match") + if "files" in cfg.keys(): + cfg_dict["files"] = cfg.get("files") + if "no-world-readable" in cfg.keys(): + cfg_dict["no_world_readable"] = True + if "world-readable" in cfg.keys(): + cfg_dict["world_readable"] = True + if "size" in cfg.keys(): + cfg_dict["size"] = cfg.get("size") + + return cfg_dict + + def get_events(self, cfg): + cfg_dict = {} + cfg_dict["id"] = cfg["name"] + if "community" in cfg.keys(): + cfg_dict["community"] = cfg.get("community") + if "description" in cfg.keys(): + cfg_dict["description"] = cfg.get("description") + if "type" in cfg.keys(): + cfg_dict["type"] = cfg.get("type") + return cfg_dict + + def get_alarms(self, cfg): + cfg_dict = {} + cfg_dict["id"] = cfg["name"] + if "description" in cfg.keys(): + cfg_dict["description"] = cfg.get("description") + if "falling-event-index" in cfg.keys(): + cfg_dict["falling_event_index"] = cfg.get("falling-event-index") + if "falling-threshold" in cfg.keys(): + cfg_dict["falling_threshold"] = cfg.get("falling-threshold") + if "falling-threshold-interval" in cfg.keys(): + cfg_dict["falling_threshold_interval"] = cfg.get( + "falling-threshold-interval", + ) + if "interval" in cfg.keys(): + cfg_dict["interval"] = cfg.get("interval") + if "request-type" in cfg.keys(): + cfg_dict["request_type"] = cfg.get("request-type") + if "rising-event-index" in cfg.keys(): + cfg_dict["rising_event_index"] = cfg.get("rising-event-index") + if "rising-threshold" in cfg.keys(): + cfg_dict["rising_threshold"] = cfg.get("rising-threshold") + if "sample-type" in cfg.keys(): + cfg_dict["sample_type"] = cfg.get("sample-type") + if "startup-alarm" in cfg.keys(): + cfg_dict["startup_alarm"] = cfg.get("startup-alarm") + if "syslog-subtag" in cfg.keys(): + cfg_dict["syslog_subtag"] = cfg.get("syslog-subtag") + if "variable" in cfg.keys(): + cfg_dict["variable"] = cfg.get("variable") + + return cfg_dict + + def get_routing_instance(self, cfg): + cfg_dict = {} + cfg_dict["name"] = cfg["name"] + if "client-list-name" in cfg.keys(): + cfg_dict["client_list_name"] = cfg.get("client-list-name") + if "clients" in cfg.keys(): + client_lst = [] + if isinstance(cfg.get("clients"), dict): + client_lst.append(self.get_client_address(cfg.get("clients"))) + else: + clients = cfg.get("clients") + for item in clients: + client_lst.append(self.get_client_address(item)) + cfg_dict["clients"] = client_lst + return cfg_dict + + def get_community(self, cfg): + cfg_dict = {} + cfg_dict["name"] = cfg["name"] + if "authorization" in cfg.keys(): + cfg_dict["authorization"] = cfg.get("authorization") + if "client-list-name" in cfg.keys(): + cfg_dict["client_list_name"] = cfg.get("client-list-name") + if "clients" in cfg.keys(): + client_lst = [] + if isinstance(cfg.get("clients"), dict): + client_lst.append(self.get_client_address(cfg.get("clients"))) + else: + clients = cfg.get("clients") + for item in clients: + client_lst.append(self.get_client_address(item)) + cfg_dict["clients"] = client_lst + if "routing-instance" in cfg.keys(): + rinst_lst = [] + rinst_lists = cfg.get("routing-instance") + + if isinstance(rinst_lists, dict): + rinst_lst.append(self.get_routing_instance(rinst_lists)) + else: + for item in rinst_lists: + rinst_lst.append(self.get_routing_instance(item)) + if rinst_lst: + cfg_dict["routing_instances"] = rinst_lst + if "view" in cfg.keys(): + cfg_dict["view"] = cfg.get("view") + + return cfg_dict + + def get_client_address(self, cfg): + cfg_dict = {} + cfg_dict["address"] = cfg["name"] + if "restrict" in cfg.keys(): + cfg_dict["restrict"] = True + return cfg_dict + + def get_client_list(self, cfg): + client_lst = [] + client_lists = cfg + client_dict = {} + if isinstance(client_lists, dict): + client_dict["name"] = client_lists["name"] + if "client-address-list" in client_lists.keys(): + client_addresses = client_lists["client-address-list"] + client_address_lst = [] + if isinstance(client_addresses, dict): + client_address_lst.append( + self.get_client_address(client_addresses), + ) + else: + for address in client_addresses: + client_address_lst.append( + self.get_client_address(address), + ) + if client_address_lst: + client_dict["addresses"] = client_address_lst + client_lst.append(client_dict) + + else: + for client in client_lists: + client_dict["name"] = client["name"] + if "client-address-list" in client.keys(): + client_addresses = client["client-address-list"] + client_address_lst = [] + if isinstance(client_addresses, dict): + client_address_lst.append( + self.get_client_address(client_addresses), + ) + else: + for address in client_addresses: + client_address_lst.append( + self.get_client_address(address), + ) + if client_address_lst: + client_dict["addresses"] = client_address_lst + client_lst.append(client_dict) + client_dict = {} + return client_lst diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/static_routes/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/static_routes/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/static_routes/static_routes.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/static_routes/static_routes.py new file mode 100644 index 00000000..63c671e2 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/static_routes/static_routes.py @@ -0,0 +1,179 @@ +# +# -*- 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 junos 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._text import to_bytes +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.static_routes.static_routes import ( + Static_routesArgs, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False +try: + import xmltodict + + HAS_XMLTODICT = True +except ImportError: + HAS_XMLTODICT = False + + +class Static_routesFacts(object): + """The junos 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 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 + """ + if not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + if not HAS_XMLTODICT: + self._module.fail_json(msg="xmltodict is not installed.") + + if not data: + config_filter = """ + + + + + """ + data = connection.get_configuration(filter=config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + + resources = data.xpath("configuration/routing-options") + vrf_resources = data.xpath("configuration/routing-instances") + resources.extend(vrf_resources) + + objs = [] + for resource in resources: + if resource is not None: + xml = self._get_xml_dict(resource) + obj = self.render_config(self.generated_spec, xml) + if obj: + objs.append(obj) + + facts = {"static_routes": []} + if objs: + 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 _get_xml_dict(self, xml_root): + xml_dict = xmltodict.parse( + etree.tostring(xml_root), + dict_constructor=dict, + ) + return xml_dict + + def _create_route_dict(self, afi, route_path): + routes_dict = {"afi": afi, "routes": []} + if isinstance(route_path, dict): + route_path = [route_path] + for route in route_path: + route_dict = {} + route_dict["dest"] = route["name"] + if route.get("metric"): + route_dict["metric"] = route["metric"]["metric-value"] + route_dict["next_hop"] = [] + route_dict["next_hop"].append( + {"forward_router_address": route["next-hop"]}, + ) + routes_dict["routes"].append(route_dict) + return routes_dict + + 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) + routes = [] + config["address_families"] = [] + + if conf.get("routing-options"): + if conf["routing-options"].get("rib"): + if conf["routing-options"].get("rib").get("name") == "inet6.0": + if conf["routing-options"].get("rib").get("static"): + route_path = conf["routing-options"]["rib"]["static"].get("route") + routes.append( + self._create_route_dict("ipv6", route_path), + ) + if conf["routing-options"].get("static"): + route_path = conf["routing-options"]["static"].get("route") + routes.append(self._create_route_dict("ipv4", route_path)) + + if conf.get("routing-instances"): + config["vrf"] = conf["routing-instances"]["instance"]["name"] + if ( + conf["routing-instances"] + .get("instance") + .get("routing-options") + .get("rib") + .get("name") + == config["vrf"] + ".inet6.0" + ): + if conf["routing-instances"]["instance"]["routing-options"]["rib"].get("static"): + route_path = conf["routing-instances"]["instance"]["routing-options"]["rib"][ + "static" + ].get("route") + routes.append(self._create_route_dict("ipv6", route_path)) + if conf["routing-instances"].get("instance").get("routing-options").get("static"): + route_path = conf["routing-instances"]["instance"]["routing-options"]["static"].get( + "route", + ) + routes.append(self._create_route_dict("ipv4", route_path)) + config["address_families"].extend(routes) + return utils.remove_empties(config) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/vlans/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/vlans/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/vlans/vlans.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/vlans/vlans.py new file mode 100644 index 00000000..7e681390 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/facts/vlans/vlans.py @@ -0,0 +1,123 @@ +# +# -*- 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 junos 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._text import to_bytes +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.vlans.vlans import ( + VlansArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.utils.utils import ( + get_resource_config, +) + + +try: + from lxml import etree + + HAS_LXML = True +except ImportError: + HAS_LXML = False + + +class VlansFacts(object): + """The junos 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 get_device_data(self, connection, config_filter): + """ + :param connection: + :param config_filter: + :return: + """ + return get_resource_config(connection, config_filter=config_filter) + + 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 not HAS_LXML: + self._module.fail_json(msg="lxml is not installed.") + + if not data: + config_filter = """ + + + + + """ + data = self.get_device_data(connection, config_filter) + + if isinstance(data, string_types): + data = etree.fromstring( + to_bytes(data, errors="surrogate_then_replace"), + ) + + resources = data.xpath("configuration/vlans/vlan") + + objs = [] + for resource in resources: + if resource is not None: + obj = self.render_config(self.generated_spec, resource) + if obj: + objs.append(obj) + facts = {"vlans": []} + if objs: + 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): + """ + 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["name"] = utils.get_xml_conf_arg(conf, "name") + config["vlan_id"] = utils.get_xml_conf_arg(conf, "vlan-id") + config["description"] = utils.get_xml_conf_arg(conf, "description") + config["l3_interface"] = utils.get_xml_conf_arg(conf, "l3-interface") + return utils.remove_empties(config) diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/junos.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/junos.py new file mode 100644 index 00000000..768bd73c --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/junos.py @@ -0,0 +1,536 @@ +# +# (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 +import collections +import json + +from contextlib import contextmanager +from copy import deepcopy + +from ansible.module_utils._text import to_text +from ansible.module_utils.basic import env_fallback +from ansible.module_utils.connection import Connection, ConnectionError +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf import ( + NetconfConnection, +) + + +try: + from lxml.etree import Element, SubElement + from lxml.etree import tostring as xml_to_string + + HAS_LXML = True +except ImportError: + from xml.etree.ElementTree import Element, SubElement + from xml.etree.ElementTree import tostring as xml_to_string + + HAS_LXML = False + +try: + from jnpr.junos import Device + from jnpr.junos.exception import ConnectError + + HAS_PYEZ = True +except ImportError: + HAS_PYEZ = False + +ACTIONS = frozenset(["merge", "override", "replace", "update", "set"]) +JSON_ACTIONS = frozenset(["merge", "override", "update"]) +FORMATS = frozenset(["xml", "text", "json"]) +CONFIG_FORMATS = frozenset(["xml", "text", "json", "set"]) + +junos_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", + ), + "timeout": dict(type="int"), + "transport": dict(default="netconf", choices=["cli", "netconf"]), +} +junos_argument_spec = { + "provider": dict( + type="dict", + options=junos_provider_spec, + removed_at_date="2022-06-01", + removed_from_collection="junipernetworks.junos", + ), +} + + +def tostring(element, encoding="UTF-8", pretty_print=False): + if HAS_LXML: + return xml_to_string( + element, + encoding="unicode", + pretty_print=pretty_print, + ) + else: + return to_text( + xml_to_string(element, encoding), + encoding=encoding, + ) + + +def get_provider_argspec(): + return junos_provider_spec + + +def get_connection(module): + if hasattr(module, "_junos_connection"): + return module._junos_connection + capabilities = get_capabilities(module) + network_api = capabilities.get("network_api") + if network_api == "cliconf": + module._junos_connection = Connection(module._socket_path) + elif network_api == "netconf": + module._junos_connection = NetconfConnection(module._socket_path) + else: + module.fail_json(msg="Invalid connection type %s" % network_api) + + return module._junos_connection + + +def get_capabilities(module): + if hasattr(module, "_junos_capabilities"): + return module._junos_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._junos_capabilities = json.loads(capabilities) + return module._junos_capabilities + + +def get_device(module): + provider = module.params.get("provider") or {} + host = provider.get("host") + + kwargs = { + "port": provider.get("port") or 830, + "user": provider.get("username"), + } + + if "password" in provider: + kwargs["passwd"] = provider.get("password") + + if "ssh_keyfile" in provider: + kwargs["ssh_private_key_file"] = provider.get("ssh_keyfile") + + if module.params.get("ssh_config"): + kwargs["ssh_config"] = module.params["ssh_config"] + + if module.params.get("ssh_private_key_file"): + kwargs["ssh_private_key_file"] = module.params["ssh_private_key_file"] + + kwargs["gather_facts"] = False + + try: + device = Device(host, **kwargs) + device.open() + device.timeout = provider.get("timeout") or 10 + except ConnectError as exc: + module.fail_json("unable to connect to %s: %s" % (host, to_text(exc))) + + return device + + +def is_netconf(module): + capabilities = get_capabilities(module) + return True if capabilities.get("network_api") == "netconf" else False + + +def _validate_rollback_id(module, value): + try: + if not 0 <= int(value) <= 49: + raise ValueError + except ValueError: + module.fail_json(msg="rollback must be between 0 and 49") + + +def load_configuration( + module, + candidate=None, + action="merge", + rollback=None, + format="xml", +): + if all((candidate is None, rollback is None)): + module.fail_json(msg="one of candidate or rollback must be specified") + + elif all((candidate is not None, rollback is not None)): + module.fail_json(msg="candidate and rollback are mutually exclusive") + + if format not in FORMATS: + module.fail_json(msg="invalid format specified") + + if format == "json" and action not in JSON_ACTIONS: + module.fail_json(msg="invalid action for format json") + elif format in ("text", "xml") and action not in ACTIONS: + module.fail_json(msg="invalid action format %s" % format) + if action == "set" and format != "text": + module.fail_json(msg="format must be text when action is set") + + conn = get_connection(module) + try: + if rollback is not None: + _validate_rollback_id(module, rollback) + obj = Element("load-configuration", {"rollback": str(rollback)}) + conn.execute_rpc(tostring(obj)) + else: + return conn.load_configuration( + config=candidate, + action=action, + format=format, + ) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) + + +def get_configuration( + module, + compare=False, + format="xml", + rollback="0", + filter=None, +): + if format not in CONFIG_FORMATS: + module.fail_json(msg="invalid config format specified") + + conn = get_connection(module) + try: + if compare: + xattrs = {"format": format} + _validate_rollback_id(module, rollback) + xattrs["compare"] = "rollback" + xattrs["rollback"] = str(rollback) + reply = conn.execute_rpc( + tostring(Element("get-configuration", xattrs)), + ) + else: + reply = conn.get_configuration(format=format, filter=filter) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) + return reply + + +def commit_configuration( + module, + confirm=False, + check=False, + comment=None, + confirm_timeout=None, + synchronize=False, + at_time=None, +): + conn = get_connection(module) + try: + if check: + reply = conn.validate() + else: + if is_netconf(module): + reply = conn.commit( + confirmed=confirm, + timeout=confirm_timeout, + comment=comment, + synchronize=synchronize, + at_time=at_time, + ) + else: + reply = conn.commit( + comment=comment, + confirmed=confirm, + at_time=at_time, + synchronize=synchronize, + ) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) + return reply + + +def command(module, cmd, format="text", rpc_only=False): + conn = get_connection(module) + if rpc_only: + cmd += " | display xml rpc" + try: + response = conn.command(command=cmd, format=format) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) + return response + + +def lock_configuration(module): + conn = get_connection(module) + try: + response = conn.lock() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) + return response + + +def unlock_configuration(module): + conn = get_connection(module) + try: + response = conn.unlock() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) + return response + + +@contextmanager +def locked_config(module): + try: + lock_configuration(module) + yield + finally: + unlock_configuration(module) + + +def discard_changes(module): + conn = get_connection(module) + try: + response = conn.discard_changes() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) + return response + + +def get_diff(module, rollback="0"): + reply = get_configuration( + module, + compare=True, + format="text", + rollback=rollback, + ) + # if warning is received from device diff is empty. + if isinstance(reply, list): + return None + + output = reply.find(".//configuration-output") + if output is not None: + return to_text(output.text, encoding="latin-1").strip() + + +def load_config(module, candidate, warnings, action="merge", format="xml"): + get_connection(module) + if not candidate: + return + + if isinstance(candidate, list): + candidate = "\n".join(candidate) + + reply = load_configuration(module, candidate, action=action, format=format) + if isinstance(reply, list): + warnings.extend(reply) + + module._junos_connection.validate() + return get_diff(module) + + +def map_params_to_obj(module, param_to_xpath_map, param=None): + """ + Creates a new dictionary with key as xpath corresponding + to param and value is a list of dict with metadata and values for + the xpath. + Acceptable metadata keys: + 'value': Value of param. + 'tag_only': Value is indicated by tag only in xml hierarchy. + 'leaf_only': If operation is to be added at leaf node only. + 'value_req': If value(text) is required for leaf node. + 'is_key': If the field is key or not. + eg: Output + { + 'name': [{'value': 'ge-0/0/1'}] + 'disable': [{'value': True, tag_only': True}] + } + + :param module: + :param param_to_xpath_map: Modules params to xpath map + :return: obj + """ + if not param: + param = module.params + + obj = collections.OrderedDict() + for key, attribute in param_to_xpath_map.items(): + if key in param: + is_attribute_dict = False + + value = param[key] + if not isinstance(value, (list, tuple)): + value = [value] + + if isinstance(attribute, dict): + xpath = attribute.get("xpath") + is_attribute_dict = True + else: + xpath = attribute + + if not obj.get(xpath): + obj[xpath] = list() + + for val in value: + if is_attribute_dict: + attr = deepcopy(attribute) + del attr["xpath"] + + attr.update({"value": val}) + obj[xpath].append(attr) + else: + obj[xpath].append({"value": val}) + return obj + + +def map_obj_to_ele(module, want, top, value_map=None, param=None): + if not HAS_LXML: + module.fail_json(msg="lxml is not installed.") + + if not param: + param = module.params + + root = Element("root") + top_ele = top.split("/") + ele = SubElement(root, top_ele[0]) + + if len(top_ele) > 1: + for item in top_ele[1:-1]: + ele = SubElement(ele, item) + container = ele + state = param.get("state") + active = param.get("active") + if active: + oper = "active" + else: + oper = "inactive" + + # build xml subtree + if container.tag != top_ele[-1]: + node = SubElement(container, top_ele[-1]) + else: + node = container + + for fxpath, attributes in want.items(): + for attr in attributes: + tag_only = attr.get("tag_only", False) + leaf_only = attr.get("leaf_only", False) + value_req = attr.get("value_req", False) + is_key = attr.get("is_key", False) + parent_attrib = attr.get("parent_attrib", True) + value = attr.get("value") + field_top = attr.get("top") + + # operation 'delete' is added as element attribute + # only if it is key or leaf only node + if state == "absent" and not (is_key or leaf_only): + continue + + # convert param value to device specific value + if value_map and fxpath in value_map: + value = value_map[fxpath].get(value) + + if (value is not None) or tag_only or leaf_only: + ele = node + if field_top: + # eg: top = 'system/syslog/file' + # field_top = 'system/syslog/file/contents' + # + # test + # + # + # + ele_list = root.xpath(top + "/" + field_top) + + if not len(ele_list): + fields = field_top.split("/") + ele = node + for item in fields: + inner_ele = root.xpath(top + "/" + item) + if len(inner_ele): + ele = inner_ele[0] + else: + ele = SubElement(ele, item) + else: + ele = ele_list[0] + + if value is not None and not isinstance(value, bool): + value = to_text(value, errors="surrogate_then_replace") + + if fxpath: + tags = fxpath.split("/") + for item in tags: + ele = SubElement(ele, item) + + if tag_only: + if state == "present": + if not value: + # if value of tag_only node is false, delete the node + ele.set("delete", "delete") + + elif leaf_only: + if state == "present": + ele.set(oper, oper) + ele.text = value + else: + ele.set("delete", "delete") + # Add value of leaf node if required while deleting. + # in some cases if value is present while deleting, it + # can result in error, hence the check + if value_req: + ele.text = value + if is_key: + par = ele.getparent() + par.set("delete", "delete") + else: + ele.text = value + par = ele.getparent() + + if parent_attrib: + if state == "present": + # set replace attribute at parent node + if not par.attrib.get("replace"): + par.set("replace", "replace") + + # set active/inactive at parent node + if not par.attrib.get(oper): + par.set(oper, oper) + else: + par.set("delete", "delete") + + return root.getchildren()[0] + + +def to_param_list(module): + aggregate = module.params.get("aggregate") + if aggregate: + if isinstance(aggregate, dict): + return [aggregate] + else: + return aggregate + else: + return [module.params] \ No newline at end of file diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/utils/__init__.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/juniper/device/plugins/module_utils/network/junos/utils/utils.py b/ansible_collections/juniper/device/plugins/module_utils/network/junos/utils/utils.py new file mode 100644 index 00000000..c77de3b8 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/module_utils/network/junos/utils/utils.py @@ -0,0 +1,51 @@ +# +# -*- 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 + +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + validate_config, +) + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + tostring, +) + + +try: + from ncclient.xml_ import new_ele, to_ele + + HAS_NCCLIENT = True +except ImportError: + HAS_NCCLIENT = False + +try: + from ansible.module_utils.common.parameters import _list_no_log_values as list_no_log_values +except ImportError: + # TODO: Remove this import when we no longer support ansible < 2.11 + from ansible.module_utils.common.parameters import list_no_log_values + + +def get_resource_config(connection, config_filter=None, attrib=None): + if attrib is None: + attrib = {"inherit": "inherit"} + + get_ele = new_ele("get-configuration", attrib) + if config_filter: + get_ele.append(to_ele(config_filter)) + + return connection.execute_rpc(tostring(get_ele)) + + +def _validate_config(_module, spec, data, redact=False): + validated_data = validate_config(spec, data) + if redact: + _module.no_log_values.update(list_no_log_values(spec, validated_data)) + return validated_data diff --git a/ansible_collections/juniper/device/plugins/modules/junos_acl_interfaces.py b/ansible_collections/juniper/device/plugins/modules/junos_acl_interfaces.py new file mode 100644 index 00000000..43d05dd1 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_acl_interfaces.py @@ -0,0 +1,364 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2020 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 junos_acl_interfaces +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_acl_interfaces +short_description: ACL interfaces resource module +description: +- This module manages adding and removing Access Control Lists (ACLs) from interfaces + on devices running Juniper JUNOS. +version_added: 1.0.0 +author: Daniel Mellado (@dmellado) +requirements: +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) +notes: +- This module requires the netconf system service be enabled on the device being managed. +- This module works with connection C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +- Tested against JunOS v18.4R1 +options: + config: + description: A dictionary of ACL options for interfaces. + type: list + elements: dict + suboptions: + name: + description: + - Name/Identifier for the interface. + type: str + access_groups: + type: list + elements: dict + description: + - Specifies ACLs attached to the interface. + suboptions: + afi: + description: + - Specifies the AFI for the ACL(s) to be configured on this interface. + type: str + choices: [ipv4, ipv6] + acls: + type: list + description: + - Specifies the ACLs for the provided AFI. + elements: dict + suboptions: + name: + description: + - Specifies the name of the IPv4/IPv4 ACL for the interface. + type: str + direction: + description: + - Specifies the direction of packets that the ACL will be applied + on. + type: str + choices: [in, out] + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show interfaces). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + description: + - The state the configuration should be left in. + type: str + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - rendered + - parsed + default: merged +""" +EXAMPLES = """ +# Using deleted + +# Before state: +# ------------- +# +# admin# show interfaces +# ge-1/0/0 { +# description "L3 interface with filter"; +# unit 0 { +# family inet { +# filter { +# input inbound_acl; +# output outbound_acl; +# } +# address 100.64.0.1/10; +# address 100.64.0.2/10; +# } +# family inet6; +# } + +- name: Delete JUNOS L3 interface filter + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: inbound_acl + direction: in + - name: outbound_acl + direction: out + state: deleted + +# After state: +# ------------- +# +# admin# show interfaces +# ge-1/0/0 { +# description "L3 interface with filter"; +# unit 0 { +# family inet { +# address 100.64.0.1/10; +# address 100.64.0.2/10; +# } +# family inet6; +# } + + +# Using merged + +# Before state: +# ------------- +# +# admin# show interfaces +# ge-1/0/0 { +# description "L3 interface without filter"; +# unit 0 { +# family inet { +# address 100.64.0.1/10; +# address 100.64.0.2/10; +# } +# family inet6; +# } + +- name: Merge JUNOS L3 interface filter + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: inbound_acl + direction: in + - name: outbound_acl + direction: out + state: merged + +# After state: +# ------------- +# +# admin# show interfaces +# ge-1/0/0 { +# description "L3 interface with filter"; +# unit 0 { +# family inet { +# filter { +# input inbound_acl; +# output outbound_acl; +# } +# address 100.64.0.1/10; +# address 100.64.0.2/10; +# } +# family inet6; +# } + + +# Using overridden + +# Before state: +# ------------- +# +# admin# show interfaces +# ge-1/0/0 { +# description "L3 interface without filter"; +# unit 0 { +# family inet { +# filter { +# input foo_acl; +# } +# address 100.64.0.1/10; +# address 100.64.0.2/10; +# } +# family inet6; +# } + +- name: Override JUNOS L3 interface filter + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: inbound_acl + direction: in + - name: outbound_acl + direction: out + state: overridden + +# After state: +# ------------- +# +# admin# show interfaces +# ge-1/0/0 { +# description "L3 interface with filter"; +# unit 0 { +# family inet { +# filter { +# input inbound_acl; +# output outbound_acl; +# } +# address 100.64.0.1/10; +# address 100.64.0.2/10; +# } +# family inet6; +# } + + +# Using replaced + +# Before state: +# ------------- +# +# admin# show interfaces +# ge-1/0/0 { +# description "L3 interface without filter"; +# unit 0 { +# family inet { +# filter { +# input foo_acl; +# output outbound_acl; +# } +# address 100.64.0.1/10; +# address 100.64.0.2/10; +# } +# family inet6; +# } + +- name: Replace JUNOS L3 interface filter + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: inbound_acl + direction: in + state: replaced + +# After state: +# ------------- +# +# admin# show interfaces +# ge-1/0/0 { +# description "L3 interface with filter"; +# unit 0 { +# family inet { +# filter { +# input inbound_acl; +# output outbound_acl; +# } +# address 100.64.0.1/10; +# address 100.64.0.2/10; +# } +# family inet6; +# } +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + type: dict + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration model invocation. + 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: ['command 1', 'command 2', 'command 3'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.acl_interfaces.acl_interfaces import ( + Acl_interfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.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", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_config",)), + ] + module = AnsibleModule( + argument_spec=Acl_interfacesArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + result = Acl_interfaces(module).execute_module() + + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_acls.py b/ansible_collections/juniper/device/plugins/modules/junos_acls.py new file mode 100644 index 00000000..c72fc992 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_acls.py @@ -0,0 +1,363 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2020 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 junos_acls +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_acls +short_description: ACLs resource module +description: This module provides declarative management of acls/filters on Juniper + JUNOS devices +version_added: 1.0.0 +author: Daniel Mellado (@dmellado) +requirements: +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) +notes: +- This module requires the netconf system service be enabled on the device being managed +- This module works with connection C(netconf) +- See L(the Junos OS Platform Options,https://docsansiblecom/ansible/latest/network/user_guide/platform_junoshtml) +- Tested against JunOS v18.4R1 +options: + config: + description: A dictionary of acls options + type: list + elements: dict + suboptions: + afi: + description: + - Protocol family to use by the acl filter + type: str + required: true + choices: + - ipv4 + - ipv6 + acls: + description: + - List of Access Control Lists (ACLs). + type: list + elements: dict + suboptions: + name: + description: + - Name to use for the acl filter + type: str + required: true + aces: + description: + - List of Access Control Entries (ACEs) for this Access Control List (ACL). + type: list + elements: dict + suboptions: + name: + description: + - Filter term name + type: str + required: true + grant: + description: + - Action to take after matching condition (allow, discard/reject) + type: str + choices: [permit, deny] + source: + type: dict + description: + - Specifies the source for the filter + suboptions: + address: + description: + - IP source address to use for the filter + type: raw + prefix_list: + description: + - IP source prefix list to use for the filter + type: list + elements: dict + suboptions: + name: + description: Name of the list + type: str + port_protocol: + description: + - Specify the source port or protocol. + type: dict + suboptions: + eq: + description: + - Match only packets on a given port number. + type: str + range: + description: + - Match only packets in the range of port numbers + 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: + type: dict + description: + - Specifies the destination for the filter + suboptions: + address: + description: + - Match IP destination address + type: raw + prefix_list: + description: + - Match IP destination prefixes in named list + type: list + elements: dict + suboptions: + name: + description: Name of the list + type: str + port_protocol: + description: + - Specify the destination port or protocol. + type: dict + suboptions: + eq: + description: + - Match only packets on a given port number. + type: str + range: + description: + - Match only packets in the range of port numbers + 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 + protocol: + description: + - Specify the protocol to match. + - Refer to vendor documentation for valid values. + type: str + protocol_options: + description: All possible suboptions for the protocol chosen. + type: dict + suboptions: + icmp: + description: ICMP protocol options. + type: dict + suboptions: + 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 + 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 + net_redirect: + description: Network redirect + type: bool + net_tos_redirect: + description: Net redirect for TOS + type: bool + network_unknown: + description: Network unknown + type: bool + port_unreachable: + description: Port unreachable + 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_route_failed: + description: Source route failed + type: bool + time_exceeded: + description: All time exceeded. + type: bool + ttl_exceeded: + description: TTL exceeded + type: bool + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show firewall). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + description: + - The state the configuration should be left in + type: str + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - rendered + - parsed + default: merged +""" +EXAMPLES = """ +# Using merged + +# Before state: +# ------------- +# +# admin# show firewall + +- name: Merge JUNOS acl + junipernetworks.junos.junos_acls: + config: + - afi: ipv4 + acls: + - name: allow_ssh_acl + aces: + - name: ssh_rule + source: + port_protocol: + eq: ssh + protocol: tcp + state: merged + +# After state: +# ------------- +# admin# show firewall +# family inet { +# filter allow_ssh_acl { +# term ssh_rule { +# from { +# protocol tcp; +# source-port ssh; +# } +# } +# } +# } +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + type: list + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration model invocation. + 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: ['command 1', 'command 2', 'command 3'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.acls.acls import ( + AclsArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.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", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_config",)), + ] + module = AnsibleModule( + argument_spec=AclsArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + + result = Acls(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_banner.py b/ansible_collections/juniper/device/plugins/modules/junos_banner.py new file mode 100644 index 00000000..c86cd48b --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_banner.py @@ -0,0 +1,194 @@ +#!/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 + + +DOCUMENTATION = """ +module: junos_banner +author: Ganesh Nalawade (@ganeshrn) +short_description: Manage multiline banners on Juniper JUNOS devices +description: +- This will configure both login and motd banners on network devices. It allows playbooks + to add or remote banner text from the active running configuration. +version_added: 1.0.0 +extends_documentation_fragment: +- junipernetworks.junos.junos +options: + banner: + description: + - Specifies which banner that should be configured on the remote device. Value + C(login) indicates system login message prior to authenticating, C(motd) is + login announcement after successful authentication. + type: str + required: true + choices: + - login + - motd + 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). + type: str + state: + description: + - Specifies whether or not the configuration is present in the current devices + active running configuration. + type: str + default: present + choices: + - present + - absent + active: + description: + - Specifies whether or not the configuration is active or deactivated + type: bool + default: true +requirements: +- ncclient (>=v0.5.2) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. +- Recommended connection is C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +- This module also works with C(local) connections for legacy playbooks. +""" + +EXAMPLES = """ +- name: configure the login banner + junipernetworks.junos.junos_banner: + banner: login + text: | + this is my login banner + that contains a multiline + string + state: present + +- name: remove the motd banner + junipernetworks.junos.junos_banner: + banner: motd + state: absent + +- name: deactivate the motd banner + junipernetworks.junos.junos_banner: + banner: motd + state: present + active: false + +- name: activate the motd banner + junipernetworks.junos.junos_banner: + banner: motd + state: present + active: true + +- name: Configure banner from file + junipernetworks.junos.junos_banner: + banner: motd + text: "{{ lookup('file', './config_partial/raw_banner.cfg') }}" + state: present +""" + +RETURN = """ +diff.prepared: + description: Configuration difference before and after applying change. + returned: when configuration is changed and diff option is enabled. + type: str + sample: > + [edit system login] + + message \"this is my login banner\"; +""" +import collections + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + commit_configuration, + discard_changes, + load_config, + locked_config, + map_obj_to_ele, + map_params_to_obj, + tostring, +) + + +USE_PERSISTENT_CONNECTION = True + + +def validate_param_values(module, obj): + for key in obj: + # validate the param value (if validator func exists) + validator = globals().get("validate_%s" % key) + if callable(validator): + validator(module.params.get(key), module) + + +def main(): + """main entry point for module execution""" + argument_spec = dict( + banner=dict(required=True, choices=["login", "motd"]), + text=dict(), + state=dict(default="present", choices=["present", "absent"]), + active=dict(default=True, type="bool"), + ) + + 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 + + top = "system/login" + + param_to_xpath_map = collections.OrderedDict() + + param_to_xpath_map.update( + [ + ( + "text", + { + "xpath": "message" if module.params["banner"] == "login" else "announcement", + "leaf_only": True, + }, + ), + ], + ) + + validate_param_values(module, param_to_xpath_map) + + want = map_params_to_obj(module, param_to_xpath_map) + ele = map_obj_to_ele(module, want, top) + + with locked_config(module): + diff = load_config(module, tostring(ele), warnings, action="merge") + + commit = not module.check_mode + if diff: + if commit: + commit_configuration(module) + else: + discard_changes(module) + result["changed"] = True + + if module._diff: + result["diff"] = {"prepared": diff} + + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_bgp_address_family.py b/ansible_collections/juniper/device/plugins/modules/junos_bgp_address_family.py new file mode 100644 index 00000000..a509c250 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_bgp_address_family.py @@ -0,0 +1,2009 @@ +#!/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 junos_bgp_address_family +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +ANSIBLE_METADATA = { + "metadata_version": "1.1", + "status": ["preview"], + "supported_by": "network", +} + +DOCUMENTATION = """ +--- +module: junos_bgp_address_family +version_added: 1.3.0 +short_description: Manage BGP Address Family attributes of interfaces on Junos devices. +description: Manage BGP Address Family attributes of interfaces on Junos network devices. +author: Rohit Thakur (@rohitthakur2590) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). + - Tested against JunOS v18.4R1 +options: + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show protocols bgp). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + config: + description: The provided link BGP address family dictionary. + type: dict + suboptions: + address_family: &address_family + description: Enable address family and enter its config mode. + type: list + elements: dict + suboptions: + afi: + description: address family. + type: str + choices: + - evpn + - inet + - inet-mdt + - inet-mvpn + - inet-vpn + - inet6 + - inet6-mvpn + - inet6-vpn + - iso-vpn + - l2vpn + - route-target + - traffic-engineering + af_type: + description: Address family type for ipv4. + type: list + elements: dict + suboptions: + type: + description: Specify type of NLRI. + type: str + choices: + - any + - flow + - labeled-unicast + - multicast + - segment-routing-te + - unicast + - signaling + - auto-discovery-mspw + - auto-discovery-only + set: + description: Set NLRI. + type: bool + accepted_prefix_limit: + description: Specify limit for maximum number of prefixes accepted from a peer. + type: dict + suboptions: + maximum: + description: Specify maximum number of prefixes accepted from a peer. + type: int + teardown: + description: Clear peer connection on reaching limit. + type: bool + limit_threshold: + description: Specify teardown percentage of prefix-limit to start warnings. + type: int + idle_timeout: + description: Set idle timeout node. + type: bool + idle_timeout_value: + description: Specify timeout before attempting to restart peer. + type: int + forever: + description: Idle the peer until the user intervenes. + type: bool + add_path: + description: Advertise multiple paths to peer. + type: dict + suboptions: + receive: + description: Receive multiple paths from peer. + type: bool + send: + description: Send multiple paths to peer. + type: dict + suboptions: + include_backup_path: + description: Specify number of backup paths to advertise. + type: int + multipath: + description: Include only multipath contributor routes. + type: bool + path_count: + description: Include only multipath contributor routes. + type: int + required: true + path_selection_mode: + description: Configure how to select add-path routes. + type: dict + suboptions: + all_paths: + description: Advertise all paths allowed by path count. + type: bool + equal_cost_paths: + description: Advertise equal cost paths. + type: bool + prefix_policy: + description: Perform add-path only for prefixes that match policy. + type: str + aggregate_label: + description: Aggregate labels of incoming routes with the same FEC. + type: dict + suboptions: + set: + description: Set Aggregate labels of incoming routes with the same FEC + type: bool + community: + description: Community to identify the FEC of incoming routesC. + type: str + aigp: + description: Allow sending and receiving of AIGP attribute. + type: dict + suboptions: + set: + description: Set AIGP. + type: bool + disable: + description: Dn not allow sending and receiving of AIGP attribute. + type: bool + damping: + description: Enable route flap damping. + type: bool + defer_initial_multipath_build: + description: Defer initial multipath build until EOR is received. + type: dict + suboptions: + set: + description: Set defer initial multipath build. + type: bool + maximum_delay: + description: Max delay(sec) multipath build after peer is up. + type: int + delay_route_advertisements: + description: Delay route updates for this family until FIB-sync. + type: dict + suboptions: + set: + description: Set delay route advertisements. + type: bool + max_delay_route_age: + description: Set max delay advertisement route age. + type: int + max_delay_routing_uptime: + description: Set max delay advertisement route age. + type: int + min_delay_inbound_convergence: + description: Set min delayadvertisement after source-peer sent all routes. + type: int + min_delay_routing_uptime: + description: Set min delay advertisement route age. + type: int + entropy_label: + description: Use entropy label for entropy label capable BGP LSPs. + type: dict + suboptions: + set: + description: Set entropy-label attribute. + type: bool + import: + description: Policy to select BGP LSPs to use entropy label. + type: str + no_next_hop_validation: + description: Don't validate next hop field against route next hop. + type: bool + explicit_null: + description: Advertise explicit null. + type: dict + suboptions: + set: + description: Set explicit-null attribute. + type: bool + connected_only: + description: Advertise explicit null only for connected routes. + type: bool + extended_nexthop: + description: Enable extended nexthop encoding. + type: bool + extended_nexthop_color: + description: Resolve using extended color nexthop. + type: bool + graceful_restart_forwarding_state_bit: + description: Specify BGP graceful restart options. + type: str + choices: ['from-fib', 'set'] + local_ipv4_address: + description: Specify local IPv4 address. + type: str + legacy_redirect_ip_action: + description: Configure legacy redirect to IP support. + type: dict + suboptions: + set: + description: Set the legacy-redirect-ip-action. + type: bool + send: + description: Advertise Redirect action as legacy redirect attribute. + type: bool + receive: + description: Accept legacy encoded redirect-to-ip action attribute + type: bool + loops: + description: Allow local AS in received AS paths. + type: int + no_install: + description: Dont install received routes in forwarding. + type: bool + no_validate: + description: Bypass validation procedure for routes that match policy. + type: str + output_queue_priority_expedited: + description: Expedited queue; highest priority. + type: bool + output_queue_priority_priority: + description: Output queue priority; higher is better. + type: int + per_group_label: + description: Advertise prefixes with unique labels per group. + type: bool + per_prefix_label: + description: Allocate a unique label to each advertised prefix. + type: bool + prefix_limit: + description: Limit maximum number of prefixes from a peer. + type: dict + suboptions: + maximum: + description: Specify maximum number of prefixes from a peer. + type: int + teardown: + description: Clear peer connection on reaching limit. + type: bool + limit_threshold: + description: Percentage of prefix-limit to start warnings. + type: int + idle_timeout: + description: Set idle timeout node. + type: bool + idle_timeout_value: + description: Specify timeout before attempting to restart peer. + type: int + forever: + description: Idle the peer until the user intervenes. + type: bool + resolve_vpn: + description: Install received NLRI in inet.3 also. + type: bool + rib: + description: Select table used by labeled unicast routes. + type: str + choices: ['inet.3'] + ribgroup_name: + description: Name of the routing table group. + type: str + route_refresh_priority_expedited: + description: Expedited queue; highest priority. + type: bool + route_refresh_priority_priority: + description: Output queue priority; higher is better. + type: int + secondary_independent_resolution: + description: Resolve FLOW routes in VRF table independent of VPN FLOW route. + type: bool + topology: + description: Multi topology routing tables. + type: list + elements: dict + suboptions: + name: + description: Specify topology name. + type: str + community: + description: Community to identify multi topology routes. + type: list + elements: str + withdraw_priority_expedited: + description: Expedited queue; highest priority. + type: bool + withdraw_priority_priority: + description: Output queue priority; higher is better. + type: int + strip_nexthop: + description: Strip the next-hop from the outgoing flow update. + type: bool + traffic_statistics: + description: Collect statistics for BGP label-switched paths + type: dict + suboptions: + set: + description: Set traffic-statistics. + type: bool + interval: + description: Time to collect statistics (seconds). + type: int + labeled_path: + description: Enable ingress labeled path statistics. + type: bool + file: + description: Statistics file options. + type: dict + suboptions: + filename: + description: Name of file in which to write trace information. + type: str + files: + description: Maximum number of trace files. + type: int + no_world_readable: + description: Don't allow any user to read the log file. + type: bool + size: + description: Maximum trace file size. + type: int + world_readable: + description: Don't allow any user to read the log file. + type: bool + groups: + description: Specify address family config for groups. + type: list + elements: dict + suboptions: + name: + description: Specify name of the group + type: str + address_family: *address_family + neighbors: + description: Specify address family config per neighbor. + type: list + elements: dict + suboptions: + neighbor_address: + description: Specify neighbor address. + type: str + address_family: *address_family + state: + description: + - The state the configuration should be left in. + - State I(deleted) only removes BGP address family attributes that this modules + manages and does not negate the BGP neighbor address family completely. Thereby, preserving + address-family related configurations under BGP group neighbor context. + - To delete the address family associated to neighbor use M(junipernetworks.junos.junos_bgp_neighbor_address_family) + modules for prior cleanup. + - Refer to examples for more details. + type: str + choices: + - merged + - replaced + - overridden + - deleted + - parsed + - gathered + - rendered + default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# admin# show protocols bgp +# +# [edit] + +- name: Merge Junos BGP address family configuration + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'evpn' + af_type: + - type: 'signaling' + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + - afi: 'inet' + af_type: + - type: 'flow' + legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + + - type: 'unicast' + extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: '9.9.9.9' + + - type: 'labeled-unicast' + entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_prefix_label: true + per_group_label: true + prefix_limit: + maximum: 20 + limit_threshold: 99 + forever: true + resolve_vpn: true + rib: 'inet.3' + route_refresh_priority_expedited: true + route_refresh_priority_priority: 3 + + - type: 'any' + accepted_prefix_limit: + maximum: 20 + limit_threshold: 99 + idle_timeout_value: 2000 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: 'from-fib' + state: merged + +# Task Output: +# ------------ +# +# before: {} +# +# commands: +# - +# 2098 +# 2001 +# 2 +# +# 4 +# +# 9.9.9.9 +# +# +# 2099 +# +# 3 +# 2099 +# 2000 +# 2 +# 2032000 +# 32000 +# 23000 +# from-fib +# +# - +# +# after: +# address_family: +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2001 +# limit_threshold: 98 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# type: signaling +# afi: evpn +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2000 +# limit_threshold: 99 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# delay_route_advertisements: +# max_delay_route_age: 20 +# max_delay_routing_uptime: 32000 +# min_delay_inbound_convergence: 32000 +# min_delay_routing_uptime: 23000 +# graceful_restart_forwarding_state_bit: from-fib +# type: any +# - legacy_redirect_ip_action: +# receive: true +# send: true +# loops: 4 +# no_install: true +# output_queue_priority_expedited: true +# secondary_independent_resolution: true +# type: flow +# - entropy_label: +# no_next_hop_validation: true +# explicit_null: +# connected_only: true +# per_group_label: true +# per_prefix_label: true +# prefix_limit: +# forever: true +# limit_threshold: 99 +# maximum: 20 +# resolve_vpn: true +# rib: inet.3 +# route_refresh_priority_priority: 3 +# type: labeled-unicast +# - extended_nexthop: true +# extended_nexthop_color: true +# local_ipv4_address: 9.9.9.9 +# type: unicast +# afi: inet + +# After state +# ----------- +# +# admin# show protocols bgp +# family inet { +# unicast { +# local-ipv4-address 9.9.9.9; +# extended-nexthop; +# extended-nexthop-color; +# } +# flow { +# loops 4; +# no-install; +# output-queue-priority expedited; +# legacy-redirect-ip-action { +# receive; +# send; +# } +# secondary-independent-resolution; +# } +# any { +# accepted-prefix-limit { +# maximum 20; +# teardown 99 idle-timeout 2000; +# } +# damping; +# delay-route-advertisements { +# minimum-delay { +# routing-uptime 23000; +# inbound-convergence 32000; +# } +# maximum-delay { +# route-age 20; +# routing-uptime 32000; +# } +# } +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# graceful-restart { +# forwarding-state-bit from-fib; +# } +# } +# labeled-unicast { +# prefix-limit { +# maximum 20; +# teardown 99 idle-timeout forever; +# } +# route-refresh-priority priority 3; +# per-prefix-label; +# per-group-label; +# rib { +# inet.3; +# } +# explicit-null connected-only; +# resolve-vpn; +# entropy-label { +# no-next-hop-validation; +# } +# } +# } +# family evpn { +# signaling { +# accepted-prefix-limit { +# maximum 20; +# teardown 98 idle-timeout 2001; +# } +# damping; +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# } +# } + +# +# Using replaced +# +# Before state +# ------------ +# +# admin# show protocols bgp +# preference 2; +# hold-time 5; +# advertise-inactive; +# out-delay 10; +# bgp-error-tolerance { +# malformed-route-limit 40000000; +# } +# authentication-algorithm md5; +# advertise-bgp-static { +# policy static-to-bgp; +# } +# family inet { +# unicast { +# local-ipv4-address 9.9.9.9; +# extended-nexthop; +# extended-nexthop-color; +# } +# flow { +# loops 4; +# no-install; +# output-queue-priority expedited; +# legacy-redirect-ip-action { +# receive; +# send; +# } +# secondary-independent-resolution; +# } +# any { +# accepted-prefix-limit { +# maximum 20; +# teardown 99 idle-timeout 2000; +# } +# damping; +# delay-route-advertisements { +# minimum-delay { +# routing-uptime 23000; +# inbound-convergence 32000; +# } +# maximum-delay { +# route-age 20; +# routing-uptime 32000; +# } +# } +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# graceful-restart { +# forwarding-state-bit from-fib; +# } +# } +# labeled-unicast { +# prefix-limit { +# maximum 20; +# teardown 99 idle-timeout forever; +# } +# route-refresh-priority priority 3; +# per-prefix-label; +# per-group-label; +# rib { +# inet.3; +# } +# explicit-null connected-only; +# resolve-vpn; +# entropy-label { +# no-next-hop-validation; +# } +# } +# } +# family evpn { +# signaling { +# accepted-prefix-limit { +# maximum 20; +# teardown 98 idle-timeout 2001; +# } +# damping; +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# } +# } + +- name: Replace existing Junos BGP address family config with provided config + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'evpn' + af_type: + - type: 'signaling' + accepted_prefix_limit: + maximum: 21 + limit_threshold: 99 + idle_timeout_value: 2002 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + damping: true + state: replaced + +# Task Output: +# ------------ +# +# before: +# address_family: +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2001 +# limit_threshold: 98 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# type: signaling +# afi: evpn +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2000 +# limit_threshold: 99 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# delay_route_advertisements: +# max_delay_route_age: 20 +# max_delay_routing_uptime: 32000 +# min_delay_inbound_convergence: 32000 +# min_delay_routing_uptime: 23000 +# graceful_restart_forwarding_state_bit: from-fib +# type: any +# - legacy_redirect_ip_action: +# receive: true +# send: true +# loops: 4 +# no_install: true +# output_queue_priority_expedited: true +# secondary_independent_resolution: true +# type: flow +# - entropy_label: +# no_next_hop_validation: true +# explicit_null: +# connected_only: true +# per_group_label: true +# per_prefix_label: true +# prefix_limit: +# forever: true +# limit_threshold: 99 +# maximum: 20 +# resolve_vpn: true +# rib: inet.3 +# route_refresh_priority_priority: 3 +# type: labeled-unicast +# - extended_nexthop: true +# extended_nexthop_color: true +# local_ipv4_address: 9.9.9.9 +# type: unicast +# afi: inet +# +# commands: +# - +# +# 2199 +# 2002 +# 20 +# 32000 +# 3200023000 +# +# - +# +# after: +# address_family: +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2002 +# limit_threshold: 99 +# maximum: 21 +# damping: true +# delay_route_advertisements: +# max_delay_route_age: 20 +# max_delay_routing_uptime: 32000 +# min_delay_inbound_convergence: 32000 +# min_delay_routing_uptime: 23000 +# type: signaling +# afi: evpn +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2000 +# limit_threshold: 99 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# delay_route_advertisements: +# max_delay_route_age: 20 +# max_delay_routing_uptime: 32000 +# min_delay_inbound_convergence: 32000 +# min_delay_routing_uptime: 23000 +# graceful_restart_forwarding_state_bit: from-fib +# type: any +# - legacy_redirect_ip_action: +# receive: true +# send: true +# loops: 4 +# no_install: true +# output_queue_priority_expedited: true +# secondary_independent_resolution: true +# type: flow +# - entropy_label: +# no_next_hop_validation: true +# explicit_null: +# connected_only: true +# per_group_label: true +# per_prefix_label: true +# prefix_limit: +# forever: true +# limit_threshold: 99 +# maximum: 20 +# resolve_vpn: true +# rib: inet.3 +# route_refresh_priority_priority: 3 +# type: labeled-unicast +# - extended_nexthop: true +# extended_nexthop_color: true +# local_ipv4_address: 9.9.9.9 +# type: unicast +# afi: inet +# +# After state +# ----------- +# +# admin# show protocols bgp +# family inet { +# unicast { +# local-ipv4-address 9.9.9.9; +# extended-nexthop; +# extended-nexthop-color; +# } +# flow { +# loops 4; +# no-install; +# output-queue-priority expedited; +# legacy-redirect-ip-action { +# receive; +# send; +# } +# secondary-independent-resolution; +# } +# any { +# accepted-prefix-limit { +# maximum 20; +# teardown 99 idle-timeout 2000; +# } +# damping; +# delay-route-advertisements { +# minimum-delay { +# routing-uptime 23000; +# inbound-convergence 32000; +# } +# maximum-delay { +# route-age 20; +# routing-uptime 32000; +# } +# } +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# graceful-restart { +# forwarding-state-bit from-fib; +# } +# } +# labeled-unicast { +# prefix-limit { +# maximum 20; +# teardown 99 idle-timeout forever; +# } +# route-refresh-priority priority 3; +# per-prefix-label; +# per-group-label; +# rib { +# inet.3; +# } +# explicit-null connected-only; +# resolve-vpn; +# entropy-label { +# no-next-hop-validation; +# } +# } +# } +# family evpn { +# signaling { +# accepted-prefix-limit { +# maximum 21; +# teardown 99 idle-timeout 2002; +# } +# damping; +# delay-route-advertisements { +# minimum-delay { +# routing-uptime 23000; +# inbound-convergence 32000; +# } +# maximum-delay { +# route-age 20; +# routing-uptime 32000; +# } +# } +# } +# } + +# Using overridden +# +# Before state +# ------------ +# +# admin# show protocols bgp +# family inet { +# unicast { +# local-ipv4-address 9.9.9.9; +# extended-nexthop; +# extended-nexthop-color; +# } +# flow { +# loops 4; +# no-install; +# output-queue-priority expedited; +# legacy-redirect-ip-action { +# receive; +# send; +# } +# secondary-independent-resolution; +# } +# any { +# accepted-prefix-limit { +# maximum 20; +# teardown 99 idle-timeout 2000; +# } +# damping; +# delay-route-advertisements { +# minimum-delay { +# routing-uptime 23000; +# inbound-convergence 32000; +# } +# maximum-delay { +# route-age 20; +# routing-uptime 32000; +# } +# } +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# graceful-restart { +# forwarding-state-bit from-fib; +# } +# } +# labeled-unicast { +# prefix-limit { +# maximum 20; +# teardown 99 idle-timeout forever; +# } +# route-refresh-priority priority 3; +# per-prefix-label; +# per-group-label; +# rib { +# inet.3; +# } +# explicit-null connected-only; +# resolve-vpn; +# entropy-label { +# no-next-hop-validation; +# } +# } +# } +# family evpn { +# signaling { +# accepted-prefix-limit { +# maximum 20; +# teardown 98 idle-timeout 2001; +# } +# damping; +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# } +# } + +- name: Override Junos BGP address family config + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'evpn' + af_type: + - type: 'signaling' + accepted_prefix_limit: + maximum: 21 + limit_threshold: 99 + idle_timeout_value: 2002 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + damping: true + state: overridden + +# Task Output: +# ------------ +# +# before: +# address_family: +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2002 +# limit_threshold: 99 +# maximum: 21 +# damping: true +# delay_route_advertisements: +# max_delay_route_age: 20 +# max_delay_routing_uptime: 32000 +# min_delay_inbound_convergence: 32000 +# min_delay_routing_uptime: 23000 +# type: signaling +# afi: evpn +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2000 +# limit_threshold: 99 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# delay_route_advertisements: +# max_delay_route_age: 20 +# max_delay_routing_uptime: 32000 +# min_delay_inbound_convergence: 32000 +# min_delay_routing_uptime: 23000 +# graceful_restart_forwarding_state_bit: from-fib +# type: any +# - legacy_redirect_ip_action: +# receive: true +# send: true +# loops: 4 +# no_install: true +# output_queue_priority_expedited: true +# secondary_independent_resolution: true +# type: flow +# - entropy_label: +# no_next_hop_validation: true +# explicit_null: +# connected_only: true +# per_group_label: true +# per_prefix_label: true +# prefix_limit: +# forever: true +# limit_threshold: 99 +# maximum: 20 +# resolve_vpn: true +# rib: inet.3 +# route_refresh_priority_priority: 3 +# type: labeled-unicast +# - extended_nexthop: true +# extended_nexthop_color: true +# local_ipv4_address: 9.9.9.9 +# type: unicast +# afi: inet +# +# commands: +# - +# +# 21 +# 992002 +# +# 2032000 +# 32000 +# 23000 +# +# - +# +# After state +# ----------- +# +# admin# show protocols bgp +# family evpn { +# signaling { +# accepted-prefix-limit { +# maximum 21; +# teardown 99 idle-timeout 2002; +# } +# damping; +# delay-route-advertisements { +# minimum-delay { +# routing-uptime 23000; +# inbound-convergence 32000; +# } +# maximum-delay { +# route-age 20; +# routing-uptime 32000; +# } +# } +# } +# } + +# Using deleted +# +# Before state +# ------------ +# +# admin# show protocols bgp +# preference 2; +# hold-time 5; +# advertise-inactive; +# out-delay 10; +# family inet { +# unicast { +# local-ipv4-address 9.9.9.9; +# extended-nexthop; +# extended-nexthop-color; +# } +# flow { +# loops 4; +# no-install; +# output-queue-priority expedited; +# legacy-redirect-ip-action { +# receive; +# send; +# } +# secondary-independent-resolution; +# } +# any { +# accepted-prefix-limit { +# maximum 20; +# teardown 99 idle-timeout 2000; +# } +# damping; +# delay-route-advertisements { +# minimum-delay { +# routing-uptime 23000; +# inbound-convergence 32000; +# } +# maximum-delay { +# route-age 20; +# routing-uptime 32000; +# } +# } +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# graceful-restart { +# forwarding-state-bit from-fib; +# } +# } +# labeled-unicast { +# prefix-limit { +# maximum 20; +# teardown 99 idle-timeout forever; +# } +# route-refresh-priority priority 3; +# per-prefix-label; +# per-group-label; +# rib { +# inet.3; +# } +# explicit-null connected-only; +# resolve-vpn; +# entropy-label { +# no-next-hop-validation; +# } +# } +# } +# family evpn { +# signaling { +# accepted-prefix-limit { +# maximum 20; +# teardown 98 idle-timeout 2001; +# } +# damping; +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# } +# } + +- name: Delete Junos BGP address family config based on the afi + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'inet' + state: deleted + +# Task Output: +# ------------ +# +# before: +# address_family: +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2001 +# limit_threshold: 98 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# type: signaling +# afi: evpn +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2000 +# limit_threshold: 99 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# delay_route_advertisements: +# max_delay_route_age: 20 +# max_delay_routing_uptime: 32000 +# min_delay_inbound_convergence: 32000 +# min_delay_routing_uptime: 23000 +# graceful_restart_forwarding_state_bit: from-fib +# type: any +# - legacy_redirect_ip_action: +# receive: true +# send: true +# loops: 4 +# no_install: true +# output_queue_priority_expedited: true +# secondary_independent_resolution: true +# type: flow +# - entropy_label: +# no_next_hop_validation: true +# explicit_null: +# connected_only: true +# per_group_label: true +# per_prefix_label: true +# prefix_limit: +# forever: true +# limit_threshold: 99 +# maximum: 20 +# resolve_vpn: true +# rib: inet.3 +# route_refresh_priority_priority: 3 +# type: labeled-unicast +# - extended_nexthop: true +# extended_nexthop_color: true +# local_ipv4_address: 9.9.9.9 +# type: unicast +# afi: inet +# +# commands: +# - +# +# - +# +# after: +# address_family: +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2001 +# limit_threshold: 98 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# type: signaling +# afi: evpn +# +# After state +# ----------- +# +# admin# show protocols bgp +# family evpn { +# signaling { +# accepted-prefix-limit { +# maximum 20; +# teardown 98 idle-timeout 2001; +# } +# damping; +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# } +# } + +# Using deleted +# +# Before state +# ------------ +# +# admin# show protocols bgp +# family inet { +# unicast { +# local-ipv4-address 9.9.9.9; +# extended-nexthop; +# extended-nexthop-color; +# } +# flow { +# loops 4; +# no-install; +# output-queue-priority expedited; +# legacy-redirect-ip-action { +# receive; +# send; +# } +# secondary-independent-resolution; +# } +# any { +# accepted-prefix-limit { +# maximum 20; +# teardown 99 idle-timeout 2000; +# } +# damping; +# delay-route-advertisements { +# minimum-delay { +# routing-uptime 23000; +# inbound-convergence 32000; +# } +# maximum-delay { +# route-age 20; +# routing-uptime 32000; +# } +# } +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# graceful-restart { +# forwarding-state-bit from-fib; +# } +# } +# labeled-unicast { +# prefix-limit { +# maximum 20; +# teardown 99 idle-timeout forever; +# } +# route-refresh-priority priority 3; +# per-prefix-label; +# per-group-label; +# rib { +# inet.3; +# } +# explicit-null connected-only; +# resolve-vpn; +# entropy-label { +# no-next-hop-validation; +# } +# } +# } +# family evpn { +# signaling { +# accepted-prefix-limit { +# maximum 20; +# teardown 98 idle-timeout 2001; +# } +# damping; +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# } +# } + +- name: Delete complete Junos BGP address family config + junipernetworks.junos.junos_bgp_address_family: + config: + state: deleted + +# Task Output: +# ------------ +# +# before: +# address_family: +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2001 +# limit_threshold: 98 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# type: signaling +# afi: evpn +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2000 +# limit_threshold: 99 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# delay_route_advertisements: +# max_delay_route_age: 20 +# max_delay_routing_uptime: 32000 +# min_delay_inbound_convergence: 32000 +# min_delay_routing_uptime: 23000 +# graceful_restart_forwarding_state_bit: from-fib +# type: any +# - legacy_redirect_ip_action: +# receive: true +# send: true +# loops: 4 +# no_install: true +# output_queue_priority_expedited: true +# secondary_independent_resolution: true +# type: flow +# - entropy_label: +# no_next_hop_validation: true +# explicit_null: +# connected_only: true +# per_group_label: true +# per_prefix_label: true +# prefix_limit: +# forever: true +# limit_threshold: 99 +# maximum: 20 +# resolve_vpn: true +# rib: inet.3 +# route_refresh_priority_priority: 3 +# type: labeled-unicast +# - extended_nexthop: true +# extended_nexthop_color: true +# local_ipv4_address: 9.9.9.9 +# type: unicast +# afi: inet +# commands: +# - +# +# +# - +# +# after: {} + +# After state +# ----------- +# +# admin# show protocols bgp +# + +# Using gathered +# +# Before state +# ------------ +# +# admin# show protocols bgp +# family inet { +# unicast { +# local-ipv4-address 9.9.9.9; +# extended-nexthop; +# extended-nexthop-color; +# } +# flow { +# loops 4; +# no-install; +# output-queue-priority expedited; +# legacy-redirect-ip-action { +# receive; +# send; +# } +# secondary-independent-resolution; +# } +# any { +# accepted-prefix-limit { +# maximum 20; +# teardown 99 idle-timeout 2000; +# } +# damping; +# delay-route-advertisements { +# minimum-delay { +# routing-uptime 23000; +# inbound-convergence 32000; +# } +# maximum-delay { +# route-age 20; +# routing-uptime 32000; +# } +# } +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# graceful-restart { +# forwarding-state-bit from-fib; +# } +# } +# labeled-unicast { +# prefix-limit { +# maximum 20; +# teardown 99 idle-timeout forever; +# } +# route-refresh-priority priority 3; +# per-prefix-label; +# per-group-label; +# rib { +# inet.3; +# } +# explicit-null connected-only; +# resolve-vpn; +# entropy-label { +# no-next-hop-validation; +# } +# } +# } +# family evpn { +# signaling { +# accepted-prefix-limit { +# maximum 20; +# teardown 98 idle-timeout 2001; +# } +# damping; +# defer-initial-multipath-build { +# maximum-delay 2; +# } +# } +# } + +- name: Gather Junos BGP address family config + junipernetworks.junos.junos_bgp_address_family: + config: + state: gathered +# +# +# Task Output: +# ------------ +# +# gathered: +# address_family: +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2001 +# limit_threshold: 98 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# type: signaling +# afi: evpn +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2000 +# limit_threshold: 99 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# delay_route_advertisements: +# max_delay_route_age: 20 +# max_delay_routing_uptime: 32000 +# min_delay_inbound_convergence: 32000 +# min_delay_routing_uptime: 23000 +# graceful_restart_forwarding_state_bit: from-fib +# type: any +# - legacy_redirect_ip_action: +# receive: true +# send: true +# loops: 4 +# no_install: true +# output_queue_priority_expedited: true +# secondary_independent_resolution: true +# type: flow +# - entropy_label: +# no_next_hop_validation: true +# explicit_null: +# connected_only: true +# per_group_label: true +# per_prefix_label: true +# prefix_limit: +# forever: true +# limit_threshold: 99 +# maximum: 20 +# resolve_vpn: true +# rib: inet.3 +# route_refresh_priority_priority: 3 +# type: labeled-unicast +# - extended_nexthop: true +# extended_nexthop_color: true +# local_ipv4_address: 9.9.9.9 +# type: unicast +# afi: inet + +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# +# 2 +# 5 +# +# 10 +# +# +# +# 9.9.9.9 +# +# +# +# +# +# 4 +# +# +# +# +# +# +# +# +# +# +# +# +# +# 20 +# +# 99 +# +# 2000 +# +# +# +# +# +# +# 23000 +# 32000 +# +# +# 20 +# 32000 +# +# +# +# 2 +# +# +# from-fib +# +# +# +# +# 20 +# +# 99 +# +# +# +# +# +# +# 3 +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# 20 +# +# 98 +# +# 2001 +# +# +# +# +# +# 2 +# +# +# +# +# +# +# +# 0.0.0.100 +# +# 200 +# +# +# so-0/0/0.0 +# 5 +# 3 +# +# +# +# +# +# +# +# 172.16.17.0/24 +# +# +# +# 10.200.16.75 +# +# 65432 +# +# +# +# + + +- name: Parsed the bgp address family running config to get the facts + junipernetworks.junos.junos_bgp_address_family: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# Task Output: +# ------------ +# +# parsed: +# address_family: +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2001 +# limit_threshold: 98 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# type: signaling +# afi: evpn +# - af_type: +# - accepted_prefix_limit: +# idle_timeout_value: 2000 +# limit_threshold: 99 +# maximum: 20 +# damping: true +# defer_initial_multipath_build: +# maximum_delay: 2 +# delay_route_advertisements: +# max_delay_route_age: 20 +# max_delay_routing_uptime: 32000 +# min_delay_inbound_convergence: 32000 +# min_delay_routing_uptime: 23000 +# graceful_restart_forwarding_state_bit: from-fib +# type: any +# - legacy_redirect_ip_action: +# receive: true +# send: true +# loops: 4 +# no_install: true +# output_queue_priority_expedited: true +# secondary_independent_resolution: true +# type: flow +# - entropy_label: +# no_next_hop_validation: true +# explicit_null: +# connected_only: true +# per_group_label: true +# per_prefix_label: true +# prefix_limit: +# forever: true +# limit_threshold: 99 +# maximum: 20 +# resolve_vpn: true +# rib: inet.3 +# route_refresh_priority_priority: 3 +# type: labeled-unicast +# - extended_nexthop: true +# extended_nexthop_color: true +# local_ipv4_address: 9.9.9.9 +# type: unicast +# afi: inet + +# Using rendered +# +- name: Render the commands for provided configuration + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'evpn' + af_type: + - type: 'signaling' + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + - afi: 'inet' + af_type: + - type: 'flow' + legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + + - type: 'unicast' + extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: '9.9.9.9' + + - type: 'labeled-unicast' + entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_prefix_label: true + per_group_label: true + prefix_limit: + maximum: 20 + limit_threshold: 99 + forever: true + resolve_vpn: true + rib: 'inet.3' + route_refresh_priority_expedited: true + route_refresh_priority_priority: 3 + + - type: 'any' + accepted_prefix_limit: + maximum: 20 + limit_threshold: 99 + idle_timeout_value: 2000 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: 'from-fib' + state: rendered + +# Task Output: +# ------------ +# +# rendered: " +# 20 +# 982001 +# +# 2 +# +# 4 +# +# +# 9.9.9.9 +# +# +# 20 +# 99 +# +# 3 +# 20 +# 992000 +# +# 2 +# +# 2032000 +# 32000 +# 23000 +# from-fib +# " +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + type: dict + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration model invocation. + 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: [' + + 2199 + 2002 + + + 2032000 + 32000 + 23000 + ', 'xml 2', 'xml 3'] +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - +gathered: + description: Facts about the network resource gathered from the remote device as structured data. + returned: when I(state) is C(gathered) + type: list + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. + returned: when I(state) is C(parsed) + type: list + sample: > + This output will always be in the same format as the + module argspec. +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.bgp_address_family.bgp_address_family import ( + Bgp_address_familyArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.bgp_address_family.bgp_address_family import ( + Bgp_address_family, +) + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + required_if = [ + ("state", "merged", ("config",)), + ("state", "replaced", ("config",)), + ("state", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_config",)), + ] + module = AnsibleModule( + argument_spec=Bgp_address_familyArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + result = Bgp_address_family(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_bgp_global.py b/ansible_collections/juniper/device/plugins/modules/junos_bgp_global.py new file mode 100644 index 00000000..cdfea246 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_bgp_global.py @@ -0,0 +1,1867 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2020 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 junos_bgp_global +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +ANSIBLE_METADATA = { + "metadata_version": "1.1", + "status": ["preview"], + "supported_by": "network", +} + +DOCUMENTATION = """ +--- +module: junos_bgp_global +version_added: "1.3.0" +short_description: Manages BGP Global configuration on devices running Juniper JUNOS. +description: + - This module manages global bgp configuration on devices running Juniper JUNOS. +author: Rohit Thakur (@rohitthakur2590) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). + - Tested against JunOS v18.4R1 +options: + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show protocols bgp). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + config: + description: A list of BGP process configuration. + type: dict + suboptions: + as_number: + description: Specify Autonomous system number. + type: str + loops: + description: Specify maximum number of times this AS can be in an AS path. + type: int + asdot_notation: + description: Enable AS-Dot notation to display true 4 byte AS numbers. + type: bool + accept_remote_nexthop: &accept_remote_nexthop + description: Allow import policy to specify a non-directly connected next-hop. + type: bool + add_path_display_ipv4_address: &add_path_display_ipv4_address + description: Display add-path path-id in IPv4 address format. + type: bool + advertise_bgp_static: &advertise_bgp_static + description: Advertise bgp-static routes. + type: dict + suboptions: + set: + description: Set Advertise bgp-static routes. + type: bool + policy: + description: Specify static route advertisement policy. + type: str + advertise_external: &advertise_external + description: Advertise best external routes. + type: dict + suboptions: + set: + description: Set Advertise best external routes. + type: bool + conditional: + description: Route matches active route upto med-comparison rule. + type: bool + advertise_from_main_vpn_tables: + description: Advertise VPN routes from bgp.Xvpn.0 tables in master instance. + type: bool + advertise_inactive: &advertise_inactive + description: Advertise inactive routes. + type: bool + advertise_peer_as: &advertise_peer_as + description: Advertise routes received from the same autonomous system. + type: bool + authentication_algorithm: &authentication_algorithm + description: Specify authentication algorithm name. + type: str + choices: ["aes-128-cmac-96", "hmac-sha-1-96", "md5"] + authentication_key: &authentication_key + description: Specify MD5 authentication key. + type: str + authentication_key_chain: &authentication_key_chain + description: Specify authentication key chain name. + type: str + bfd_liveness_detection: &bfd_liveness_detection + description: Bidirectional Forwarding Detection (BFD) options. + type: dict + suboptions: + authentication: + description: Authentication options. + type: dict + suboptions: + algorithm: + description: Specify algorithm name. + type: str + choices: ["keyed-md5", "keyed-sha-1", "meticulous-keyed-md5", "meticulous-keyed-sha-1", "simple-password"] + key_chain: + description: Specify Key chain name. + type: str + loose_check: + description: Verify authentication only if authentication is negotiated. + type: bool + detection_time: + description: Specify Detection-time optionss. + type: dict + suboptions: + threshold: + description: Specify high detection-time triggering a trap (milliseconds). + type: int + holddown_interval: + description: Specify time to hold the session-UP notification to the client. + type: int + minimum_interval: + description: Specify minimum transmit and receive interval. + type: int + minimum_receive_interval: + description: Specify minimum receive interval. + type: int + multiplier: + description: Specify detection time multiplier. + type: int + no_adaptation: + description: Disable adaptation. + type: bool + session_mode: + description: BFD single-hop or multihop session-mode. + type: str + choices: ["automatic", "multihop", "single-hop"] + transmit_interval: + description: Transmit-interval options. + type: dict + suboptions: + minimum_interval: + description: Specify Minimum transmit interval. + type: int + threshold: + description: Specify high transmit interval triggering a trap. + type: int + version: + description: Specify BFD protocol version number. + type: str + choices: ["0", "1", "automatic"] + bgp_error_tolerance: &bgp_error_tolerance + description: Handle BGP malformed updates softly. + type: dict + suboptions: + set: + description: Set BGP malformed updates softly. + type: bool + malformed_route_limit: + description: Maximum number of malformed routes from a peer. + type: int + malformed_update_log_interval: + description: Time used when logging malformed update. + type: int + no_malformed_route_limit: + description: Specify no malformed route limit. + type: bool + bmp: &bmp + description: Specific settings to override the routing-options settings. + type: dict + suboptions: + monitor: + description: Enable/Disable monitoring. + type: bool + route_monitoring: + description: Control route monitoring settings. + type: dict + suboptions: + none: + description: Do not send route montoring messages. + type: bool + post_policy: + description: Send post policy route montoring messages. + type: bool + post_policy_exclude_non_eligible: + description: Send post policy route montoring messages and exclude unresolved routes, etc. + type: bool + pre_policy: + description: Send pre policy route montoring messages. + type: bool + post_policy_exclude_non_feasible: + description: Send pre policy route montoring messages and exclude looped routes, etc. + type: bool + cluster_id: &cluster_id + description: Specify cluster identifier. + type: str + damping: &damping + description: Enable route flap damping. + type: bool + description: &description + description: Specify text description. + type: str + disable: + description: Disable BGP. + type: bool + egress_te: &egress_te + description: Use Egress Peering traffic engineering. + type: dict + suboptions: + set: + description: Set the attribute. + type: bool + backup_path: + description: The 'egress-te-backup-paths template' to use for this peer. + type: str + egress_te_backup_paths: + description: Backup-path for Egress-TE peer interface failure. + type: dict + suboptions: + templates: + description: Specify Backup-path template. + type: list + elements: dict + suboptions: + path_name: + description: Name of Egress-TE backup path. + type: str + required: true + ip_forward: + description: Use IP-forward backup path for Egress TE. + type: dict + suboptions: + set: + description: Set use IP-forward backup path for Egress TE. + type: bool + rti_name: + description: Routing-instance to use as IP forward backup-path. + type: str + peers: + description: Specify address of BGP peer to use as backup next-hop. + type: list + elements: str + remote_nexthop: + description: Specify address of remote-nexthop to use as backup path. + type: str + egress_te_set_segment: + description: Configure BGP-Peer-Set segment. + type: list + elements: dict + suboptions: + name: + description: The BGP-Peer-Set segment name. + type: str + required: true + label: + description: Backup segment label value from static label pool. + type: int + egress_te_backup_segment_label: + description: BGP-Peer-Set SID label value from static label pool. + type: int + egress_te_sid_stats: + description: Create BGP-Peer-SID sensor. + type: bool + enforce_first_as: &enforce_first_as + description: Enforce neighbor AS is the first AS in AS-PATH attribute (EBGP). + type: bool + export: &export + description: Specify export policy. + type: str + forwarding_context: &forwarding_context + description: Specify routing-instance used for data-forwarding and transport-session. + type: str + graceful_restart: &graceful_restart + description: BGP graceful restart options. + type: dict + suboptions: + set: + description: Set BGP graceful restart options. + type: bool + disable: + description: Disable graceful restart. + type: bool + dont_help_shared_fate_bfd_down: + description: Honor BFD-Down(C=0) if GR-restart not in progress. + type: bool + forwarding_state_bit: + description: Control forwarding-state flag negotiation. + type: dict + suboptions: + as_rr_client: + description: As for a route reflector client. + type: bool + from_fib: + description: Always use state of associated FIB(s). + type: bool + long_lived: + description: Long-lived graceful restart options. + type: dict + suboptions: + advertise_to_non_llgr_neighbor: + description: Advertise stale routes to non-LLGR neighbors. + type: dict + suboptions: + set: + description: Set Advertise stale routes to non-LLGR neighbors. + type: bool + omit_no_export: + description: Set Advertise stale routes to non-LLGR neighbors. + type: bool + receiver_disable: + description: Disable receiver (helper) functionality. + type: bool + restart_time: + description: Restart time used when negotiating with a peer. + type: int + stale_routes_time: + description: Maximum time for which stale routes are kept. + type: int + hold_time: &hold_time + description: Specify hold time used when negotiating with a peer. + type: int + holddown_all_stale_labels: + description: Hold all BGP stale-labels, facilating make-before-break for new label advertisements. + type: bool + idle_after_switch_over: &idle_after_switch_over + description: Stop peer session from coming up after nonstop-routing switch-over. + type: dict + suboptions: + timeout: + description: Specify timeout value, in seconds, for starting peer after switch over. + type: int + forever: + description: Idle the peer until the user intervenes. + type: bool + import: &import + description: Specify import policy. + type: list + elements: str + include_mp_next_hop: &include_mp_next_hop + description: Include NEXT-HOP attribute in multiprotocol updates. + type: bool + ipsec_sa: &ipsec_sa + description: Specify IPSec SA name. + type: str + keep: &keep + description: Specify how to retain routes in the routing table. + type: str + choices: ["all", "none"] + local_address: &local_address + description: Specify Address of local end of BGP session. + type: str + local_as: &local_as + description: Local autonomous system number. + type: dict + suboptions: + as_num: + description: Autonomous system number in plain number or (asdot notation) format. + type: str + required: true + alias: + description: Treat this AS as an alias to the system AS. + type: bool + loops: + description: Maximum number of times this AS can be in an AS path. + type: int + no_prepend_global_as: + description: Maximum number of times this AS can be in an AS path. + type: bool + private: + description: Hide this local AS in paths learned from this peering. + type: bool + local_interface: &local_interface + description: Specify Local interface for IPv6 link local EBGP peering. + type: str + local_preference: &local_preference + description: Specify value of LOCAL_PREF path attribute. + type: str + log_updown: &log_updown + description: Enable log a message for peer state transitions. + type: bool + metric_out: &metric_out + description: Specify route metric sent in MED. + type: dict + suboptions: + metric_value: + description: Specify metric value. + type: int + igp: + description: Track the IGP metric. + type: dict + suboptions: + set: + description: Set track the IGP metric. + type: bool + metric_offset: + description: Specify metric offset for MED. + type: int + delay_med_update: + description: Delay updating MED when IGP metric increases. + type: bool + minimum_igp: + description: Track the minimum IGP metric. + type: dict + suboptions: + set: + description: Set track the minimum IGP metric. + type: bool + metric_offset: + description: Specify metric offset for MED. + type: int + mtu_discovery: &mtu_discovery + description: Enable TCP path MTU discovery. + type: bool + multihop: &multihop + description: Configure an EBGP multihop session. + type: dict + suboptions: + set: + description: Set an EBGP multihop session. + type: bool + no_nexthop_change: + description: Do not change next hop to self in advertisements. + type: bool + ttl: + description: TTL value for the session. + type: int + multipath: &multipath + description: Allow load sharing among multiple BGP paths. + type: dict + suboptions: + set: + description: Set allow load sharing among multiple BGP paths. + type: bool + disable: + description: Disable Multipath. + type: bool + multiple_as: + description: Use paths received from different ASs. + type: bool + multiple_as_disable: + description: Disable multipath. + type: bool + multipath_build_priority: + description: Configure the multipath build priority. + type: str + choices: ["low", "medium"] + no_advertise_peer_as: &no_advertise_peer_as + description: Allows to not advertise routes received from the same autonomous system. + type: bool + no_aggregator_id: &no_aggregator_id + description: Set router ID in aggregator path attribute to 0. + type: bool + no_client_reflect: &no_client_reflect + description: Disable intracluster route redistribution. + type: bool + no_precision_timers: &no_precision_timers + description: Specify not to use precision timers for scheduling keepalives. + type: bool + out_delay: &out_delay + description: Specify how long before exporting routes from routing table. + type: int + outbound_route_filter: &outbound_route_filter + description: Dynamically negotiated cooperative route filtering. + type: dict + suboptions: + bgp_orf_cisco_mode: + description: Using BGP ORF capability code 130 and Prefix ORF type 128. + type: bool + prefix_based: + description: Prefix-based outbound route filtering. + type: dict + suboptions: + set: + description: Set prefix-based outbound route filtering. + type: bool + accept: + description: Honor Prefix-based ORFs from remote peers. + type: dict + suboptions: + set: + description: Set honor Prefix-based ORFs from remote peers. + type: bool + inet: + description: Honor IPv4 prefix filters. + type: bool + inet6: + description: Honor IPv6 prefix filters. + type: bool + output_queue_priority: + description: BGP output queue priority scheduler for updates. + type: dict + suboptions: + defaults: + description: Map policy's priority class and BGP output-queue. + type: dict + suboptions: + high: + description: Assign the 'high' priority class to this output-queue. + type: dict + suboptions: + expedited: + description: Expedited queue; highest priority. + type: bool + priority: + description: Specify output queue priorit. + type: int + low: + description: Assign the 'low' priority class to this output-queue. + type: dict + suboptions: + expedited: + description: Expedited queue; highest priority. + type: bool + priority: + description: Specify output queue priorit. + type: int + medium: + description: Assign the 'medium' priority class to this output-queue. + type: dict + suboptions: + expedited: + description: Expedited queue; highest priority. + type: bool + priority: + description: Specify output queue priorit. + type: int + expedited_update_tokens: + description: Expedited queue; highest priority for number of tokens. + type: int + priority_update_tokens: + description: Output queue priority; higher is better. + type: list + elements: dict + suboptions: + priority: + description: Specify the priority. + type: int + required: true + update_tokens: + description: Specify update_tokens. + type: int + required: true + passive: &passive + description: Specify to not send open messages to a peer. + type: bool + path_selection: + description: Configure path selection strategy. + type: dict + suboptions: + always_compare_med: + description: Compare MED on paths from different AS. + type: bool + as_path_ignore: + description: Ignore AS path comparison during path selection. + type: bool + cisco_non_deterministic: + description: Use Cisco IOS nondeterministic path selection algorithm. + type: bool + external_router_id: + description: Compare router ID on BGP externals. + type: bool + l2vpn_use_bgp_rules: + description: Use standard BGP rules during L2VPN path selection. + type: bool + med_plus_igp: + description: Add IGP cost to next-hop to MED before comparing MED values. + type: dict + suboptions: + set: + description: Set med-plus-igp attribute. + type: bool + igp_multiplier: + description: Specify multiplier for IGP cost to next-hop. + type: int + med_multiplier: + description: Specify Multiplier for MED. + type: int + peer_as: &peer_as + description: Specify Autonomous system number in plain number or 'higher 16bits'.'Lower 16 bits' format. + type: str + precision_timers: + description: Use precision timers for scheduling keepalives. + type: bool + preference: &preference + description: Specify preference value. + type: str + remove_private: &remove_private + description: Remove well-known private AS numbers. + type: dict + suboptions: + set: + description: Remove well-known private AS numbers. + type: bool + all: + description: Remove all private AS numbers and do not stop at the first public AS number. + type: bool + all_replace: + description: Specify private AS replacement. + type: bool + all_replace_nearest: + description: Use closest public AS number to replace a private AS number. + type: bool + no_peer_loop_check: + description: Remove peer loop-check. + type: bool + rfc6514_compliant_safi129: &rfc6514_compliant_safi129 + description: Specify Compliance with RFC6514 SAFI129 format. + type: bool + route_server_client: &route_server_client + description: Enable route server client behavior. + type: bool + send_addpath_optimization: + description: Enable BGP addpath advertisement optimization. + type: bool + snmp_options: + description: Customize SNMP behaviors specifically for BGP MIBs. + type: dict + suboptions: + backward_traps_only_from_established: + description: Limit traps for backward transitions to only those moving from Established state. + type: bool + emit_inet_address_length_in_oid: + description: Emit Length in OID for InetAddress MIB type. + type: bool + sr_preference_override: + description: Replace received segment routing traffic engineering preference value with override value. + type: str + stale_labels_holddown_period: + description: Specify duration (sec) MPLS labels allocated by BGP are kept after they go stale. + type: int + tcp_aggressive_transmission: &tcp_aggressive_transmission + description: Enable aggressive transmission of pure TCP ACKs and retransmissions. + type: bool + tcp_mss: &tcp_mss + description: Specify maximum TCP segment size. + type: int + traceoptions: &traceoptions + description: Configure trace options for BGP. + type: dict + suboptions: + file: + description: Specify trace file options. + type: dict + suboptions: + filename: + description: Specify name of file in which to write trace information. + type: str + required: true + files: + description: Specify maximum number of trace files. + type: int + no_world_readable: + description: Don't allow any user to read the log file. + type: bool + world_readable: + description: Allow any user to read the log file. + type: bool + size: + description: Specify maximum trace file size. + type: int + flag: + description: Specify tracing parameters. + type: list + elements: dict + suboptions: + name: + description: specify event name + type: str + choices: + - 4byte-as + - add-path + - all + - bfd + - damping + - egress-te + - general + - graceful-restart + - keepalive + - normal + - nsr-synchronization + - open + - packets + - policy + - refresh + - route + - state + - task + - thread-io + - thread-update-io + - timer + - update + required: true + detail: + description: Trace detailed information. + type: bool + disable: + description: Disable this trace flag. + type: bool + receive: + description: Trace received packets. + type: bool + send: + description: Trace transmitted packets. + type: bool + filter: + description: Filter to apply to this flag. + type: dict + suboptions: + set: + description: Set filter to apply to this flag. + type: bool + match_on_prefix: + description: Specify filter based on prefix. + type: bool + policy: + description: Specify filter policy. + type: str + traffic_statistics_labeled_path: + description: Collect periodic ingress labeled statistics for BGP label-switched paths. + type: dict + suboptions: + file: + description: Specify statistics file options. + type: dict + suboptions: + filename: + description: Specify name of file in which to write trace information. + type: str + files: + description: Specify maximum number of trace files. + type: int + no_world_readable: + description: Don't allow any user to read the log file. + type: bool + world_readable: + description: Allow any user to read the log file. + type: bool + size: + description: Specify maximum trace file size. + type: int + interval: + description: Specify time interval to collect statistics. + type: int + ttl: &ttl + description: Specify TTL value for the single-hop peer. + type: int + unconfigured_peer_graceful_restart: + description: Specify BGP unconfigured peer graceful restart options. + type: bool + vpn_apply_export: + description: Apply BGP export policy when exporting VPN routes. + type: bool + groups: + description: Specify name of the group. + type: list + elements: dict + suboptions: + name: + description: Specify the name of the group + type: str + accept_remote_nexthop: *accept_remote_nexthop + add_path_display_ipv4_address: *add_path_display_ipv4_address + advertise_bgp_static: *advertise_bgp_static + advertise_external: *advertise_external + advertise_inactive: *advertise_inactive + advertise_peer_as: *advertise_peer_as + allow: + description: Configure peer connections for specific networks. + type: list + elements: str + as_override: &as_override + description: Replace neighbor AS number with our AS number + type: bool + authentication_algorithm: *authentication_algorithm + authentication_key: *authentication_key + authentication_key_chain: *authentication_key_chain + bfd_liveness_detection: *bfd_liveness_detection + bgp_error_tolerance: *bgp_error_tolerance + bmp: *bmp + cluster_id: *cluster_id + damping: *damping + description: *description + egress_te: *egress_te + enforce_first_as: *enforce_first_as + export: *export + forwarding_context: *forwarding_context + graceful_restart: *graceful_restart + hold_time: *hold_time + idle_after_switch_over: *idle_after_switch_over + import: *import + include_mp_next_hop: *include_mp_next_hop + ipsec_sa: *ipsec_sa + keep: *keep + local_address: *local_address + local_as: *local_as + local_interface: *local_interface + local_preference: *local_preference + log_updown: *log_updown + metric_out: *metric_out + mtu_discovery: *mtu_discovery + multihop: *multihop + multipath: *multipath + no_advertise_peer_as: *no_advertise_peer_as + no_aggregator_id: *no_aggregator_id + no_client_reflect: *no_client_reflect + optimal_route_reflection: + description: Enable optimal route reflection for this client group. + type: dict + suboptions: + igp_backup: + description: Backup node identifier for this client group. + type: str + igp_primary: + description: Primary node identifier for this client group. + type: str + out_delay: *out_delay + outbound_route_filter: *outbound_route_filter + passive: *passive + peer_as: *peer_as + preference: *preference + remove_private: *remove_private + rfc6514_compliant_safi129: *rfc6514_compliant_safi129 + route_server_client: *route_server_client + tcp_aggressive_transmission: *tcp_aggressive_transmission + tcp_mss: *tcp_mss + traceoptions: *traceoptions + ttl: *ttl + type: + description: Specify BGP group type. + type: str + choices: ['external', 'internal'] + unconfigured_peer_graceful_restart: &unconfigured_peer_graceful_restart + description: Specify BGP unconfigured peer graceful restart options. + type: bool + vpn_apply_export: &vpn_apply_export + description: Apply BGP export policy when exporting VPN routes. + type: bool + neighbors: + description: Specify list of neighbors. + type: list + elements: dict + suboptions: + neighbor_address: + description: Specify neighbor address. + type: str + accept_remote_nexthop: *accept_remote_nexthop + add_path_display_ipv4_address: *add_path_display_ipv4_address + advertise_bgp_static: *advertise_bgp_static + advertise_external: *advertise_external + advertise_inactive: *advertise_inactive + advertise_peer_as: *advertise_peer_as + as_override: *as_override + authentication_algorithm: *authentication_algorithm + authentication_key: *authentication_key + authentication_key_chain: *authentication_key_chain + bfd_liveness_detection: *bfd_liveness_detection + bgp_error_tolerance: *bgp_error_tolerance + bmp: *bmp + cluster_id: *cluster_id + damping: *damping + description: + description: Specify neighbor description. + type: str + egress_te: *egress_te + enforce_first_as: *enforce_first_as + export: *export + forwarding_context: *forwarding_context + graceful_restart: *graceful_restart + hold_time: *hold_time + idle_after_switch_over: *idle_after_switch_over + import: *import + include_mp_next_hop: *include_mp_next_hop + ipsec_sa: *ipsec_sa + keep: *keep + local_address: *local_address + local_as: *local_as + local_interface: *local_interface + local_preference: *local_preference + log_updown: *log_updown + metric_out: *metric_out + mtu_discovery: *mtu_discovery + multihop: *multihop + multipath: *multipath + no_advertise_peer_as: *no_advertise_peer_as + no_aggregator_id: *no_aggregator_id + no_client_reflect: *no_client_reflect + out_delay: *out_delay + outbound_route_filter: *outbound_route_filter + passive: *passive + peer_as: *peer_as + preference: *preference + remove_private: *remove_private + rfc6514_compliant_safi129: *rfc6514_compliant_safi129 + route_server_client: *route_server_client + tcp_aggressive_transmission: *tcp_aggressive_transmission + tcp_mss: *tcp_mss + traceoptions: *traceoptions + ttl: *ttl + unconfigured_peer_graceful_restart: *unconfigured_peer_graceful_restart + vpn_apply_export: *vpn_apply_export + + state: + description: + - The state the configuration should be left in. + - State I(purged) removes all (routing-options autonomous-system, bgp global, bgp groups, bgp neighbors, bgp family + and bgp group and neighbor family) the BGP configurations from the + target device. Use caution with this state. + - State I(deleted) only removes BGP attributes that this modules + manages and does not negate the BGP process completely. Thereby, preserving + address-family related configurations under BGP context. + - Running states I(deleted) and I(replaced) will result in an error if there + are address-family configuration lines present under a neighbor.Please use the + M(junipernetworks.junos.junos_bgp_address_family) + modules for prior cleanup. + - Refer to examples for more details. + type: str + choices: + - purged + - merged + - replaced + - overridden + - deleted + - gathered + - parsed + - rendered + default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state: +# ------------- +# +# vsrx# show bgp summary +# BGP is not running + +# vsrx# show routing-options autonomous-system + +- name: Merge provided bgp config with device configuration + junipernetworks.junos.junos_bgp_global: + config: + as_number: "65534" + loops: 3 + asdot_notation: true + accept_remote_nexthop: true + add_path_display_ipv4_address: true + advertise_from_main_vpn_tables: true + advertise_inactive: true + authentication_algorithm: "md5" + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + egress_te_sid_stats: true + hold_time: 5 + holddown_all_stale_labels: true + include_mp_next_hop: true + log_updown: true + no_advertise_peer_as: true + no_aggregator_id: true + no_client_reflect: true + out_delay: 10 + precision_timers: true + preference: 2 + state: merged + +# Task Output: +# ------------ +# before: {} +# +# commands: +# - +# +# - +# 655343 +# +# after: +# accept_remote_nexthop: true +# add_path_display_ipv4_address: true +# advertise_from_main_vpn_tables: true +# advertise_inactive: true +# as_number: '65534' +# asdot_notation: true +# authentication_algorithm: md5 +# bgp_error_tolerance: +# malformed_route_limit: 20000000 +# bmp: +# monitor: true +# damping: true +# description: This is configured with Junos_bgp resource module +# egress_te_sid_stats: true +# hold_time: 5 +# holddown_all_stale_labels: true +# include_mp_next_hop: true +# log_updown: true +# loops: 3 +# no_advertise_peer_as: true +# no_aggregator_id: true +# no_client_reflect: true +# out_delay: 10 +# precision_timers: true +# preference: '2' + +# After state: +# ------------ +# +# vsrx# show routing-options autonomous-system +# 65534 loops 3 asdot-notation; + +# vsrx# show protocols bgp +# precision-timers; +# advertise-from-main-vpn-tables; +# holddown-all-stale-labels; +# description "This is configured with Junos_bgp resource module"; +# accept-remote-nexthop; +# preference 2; +# hold-time 5; +# advertise-inactive; +# no-advertise-peer-as; +# no-aggregator-id; +# out-delay 10; +# log-updown; +# damping; +# bgp-error-tolerance { +# malformed-route-limit 20000000; +# } +# authentication-algorithm md5; +# no-client-reflect; +# include-mp-next-hop; +# bmp { +# monitor enable; +# } +# add-path-display-ipv4-address; +# egress-te-sid-stats; + +# Using replaced +# +# Before state: +# ------------- +# +# vsrx# show routing-options autonomous-system +# [edit] +# vsrx# show protocols bgp +# precision-timers; +# advertise-from-main-vpn-tables; +# holddown-all-stale-labels; +# description "This is configured with Junos_bgp resource module"; +# accept-remote-nexthop; +# preference 2; +# hold-time 5; +# advertise-inactive; +# no-advertise-peer-as; +# no-aggregator-id; +# out-delay 10; +# log-updown; +# damping; +# bgp-error-tolerance { +# malformed-route-limit 20000000; +# } +# authentication-algorithm md5; +# no-client-reflect; +# include-mp-next-hop; +# bmp { +# monitor enable; +# } +# add-path-display-ipv4-address; +# egress-te-sid-stats; + +- name: Replace running config with provided config + junipernetworks.junos.junos_bgp_global: + config: + advertise_inactive: true + authentication_algorithm: "md5" + bfd_liveness_detection: + minimum_receive_interval: 8 + multiplier: 30 + no_adaptation: true + transmit_interval: + minimum_interval: 4 + version: "automatic" + bgp_error_tolerance: + malformed_route_limit: 40000000 + description: "Replace running bgp config" + egress_te_sid_stats: true + hold_time: 5 + out_delay: 10 + preference: "2" + state: replaced + +# Task Output: +# ------------ +# +# before: +# accept_remote_nexthop: true +# add_path_display_ipv4_address: true +# advertise_from_main_vpn_tables: true +# advertise_inactive: true +# as_number: '65534' +# asdot_notation: true +# authentication_algorithm: md5 +# bgp_error_tolerance: +# malformed_route_limit: 20000000 +# bmp: +# monitor: true +# damping: true +# description: This is configured with Junos_bgp resource module +# egress_te_sid_stats: true +# hold_time: 5 +# holddown_all_stale_labels: true +# include_mp_next_hop: true +# log_updown: true +# loops: 3 +# no_advertise_peer_as: true +# no_aggregator_id: true +# no_client_reflect: true +# out_delay: 10 +# precision_timers: true +# preference: '2' + +# commands: +# - +# +# +# md5Replace running bgp conf> +# - + +# +# after: +# advertise_inactive: true +# authentication_algorithm: md5 +# bfd_liveness_detection: +# minimum_receive_interval: 8 +# multiplier: 30 +# no_adaptation: true +# transmit_interval: +# minimum_interval: 4 +# version: automatic +# bgp_error_tolerance: +# malformed_route_limit: 40000000 +# description: Replace running bgp config +# egress_te_sid_stats: true +# hold_time: 5 +# out_delay: 10 +# preference: '2' + +# After state: +# ------------ +# +# varx# show protocols bgp +# description "Replace running bgp config"; +# preference 2; +# hold-time 5; +# advertise-inactive; +# out-delay 10; +# bgp-error-tolerance { +# malformed-route-limit 40000000; +# } +# authentication-algorithm md5; +# bfd-liveness-detection { +# version automatic; +# minimum-receive-interval 8; +# multiplier 30; +# no-adaptation; +# transmit-interval { +# minimum-interval 4; +# } +# } +# egress-te-sid-stats; + +# vsrx# show routing-options autonomous-system + +# Using overridden +# "(NOTE: This will work same as replaced operation)" +# +# Before state: +# ------------- +# +# vsrx# show routing-options autonomous-system +# [edit] +# vsrx# show protocols bgp +# precision-timers; +# advertise-from-main-vpn-tables; +# holddown-all-stale-labels; +# description "This is configured with Junos_bgp resource module"; +# accept-remote-nexthop; +# preference 2; +# hold-time 5; +# advertise-inactive; +# no-advertise-peer-as; +# no-aggregator-id; +# out-delay 10; +# log-updown; +# damping; +# bgp-error-tolerance { +# malformed-route-limit 20000000; +# } +# authentication-algorithm md5; +# no-client-reflect; +# include-mp-next-hop; +# bmp { +# monitor enable; +# } +# add-path-display-ipv4-address; +# egress-te-sid-stats; + +- name: Override running config with provided config + junipernetworks.junos.junos_bgp_global: + config: + advertise_inactive: true + authentication_algorithm: "md5" + bfd_liveness_detection: + minimum_receive_interval: 8 + multiplier: 30 + no_adaptation: true + transmit_interval: + minimum_interval: 4 + version: "automatic" + bgp_error_tolerance: + malformed_route_limit: 40000000 + description: "Replace running bgp config" + egress_te_sid_stats: true + hold_time: 5 + out_delay: 10 + preference: "2" + state: overridden + +# Task Output: +# ------------ +# +# before: +# accept_remote_nexthop: true +# add_path_display_ipv4_address: true +# advertise_from_main_vpn_tables: true +# advertise_inactive: true +# as_number: '65534' +# asdot_notation: true +# authentication_algorithm: md5 +# bgp_error_tolerance: +# malformed_route_limit: 20000000 +# bmp: +# monitor: true +# damping: true +# description: This is configured with Junos_bgp resource module +# egress_te_sid_stats: true +# hold_time: 5 +# holddown_all_stale_labels: true +# include_mp_next_hop: true +# log_updown: true +# loops: 3 +# no_advertise_peer_as: true +# no_aggregator_id: true +# no_client_reflect: true +# out_delay: 10 +# precision_timers: true +# preference: '2' + +# commands: +# - +# +# +# md5Replace running bgp conf> +# - + +# +# after: +# advertise_inactive: true +# authentication_algorithm: md5 +# bfd_liveness_detection: +# minimum_receive_interval: 8 +# multiplier: 30 +# no_adaptation: true +# transmit_interval: +# minimum_interval: 4 +# version: automatic +# bgp_error_tolerance: +# malformed_route_limit: 40000000 +# description: Replace running bgp config +# egress_te_sid_stats: true +# hold_time: 5 +# out_delay: 10 +# preference: '2' + +# After state: +# ------------ +# +# varx# show protocols bgp +# description "Replace running bgp config"; +# preference 2; +# hold-time 5; +# advertise-inactive; +# out-delay 10; +# bgp-error-tolerance { +# malformed-route-limit 40000000; +# } +# authentication-algorithm md5; +# bfd-liveness-detection { +# version automatic; +# minimum-receive-interval 8; +# multiplier 30; +# no-adaptation; +# transmit-interval { +# minimum-interval 4; +# } +# } +# egress-te-sid-stats; + +# vsrx# show routing-options autonomous-system + +# Using deleted +# "(NOTE: This WILL delete the bgp global attributes)" +# Before state +# ------------ +# +# vsrx# show protocols bgp +# description "Replace running bgp config"; +# preference 2; +# hold-time 5; +# advertise-inactive; +# out-delay 10; +# bgp-error-tolerance { +# malformed-route-limit 40000000; +# } +# authentication-algorithm md5; +# bfd-liveness-detection { +# version automatic; +# minimum-receive-interval 8; +# multiplier 30; +# no-adaptation; +# transmit-interval { +# minimum-interval 4; +# } +# } +# egress-te-sid-stats; + +- name: Delete bgp section of running config + junipernetworks.junos.junos_bgp_global: + config: + state: deleted + +# Task Output: +# ------------ + +# before: +# advertise_inactive: true +# authentication_algorithm: md5 +# bfd_liveness_detection: +# minimum_receive_interval: 8 +# multiplier: 30 +# no_adaptation: true +# transmit_interval: +# minimum_interval: 4 +# version: automatic +# bgp_error_tolerance: +# malformed_route_limit: 40000000 +# description: Replace running bgp config +# egress_te_sid_stats: true +# hold_time: 5 +# out_delay: 10 +# preference: '2' + +# commands: +# - +# +# +# - + +# after: {} + +# After state: +# ------------ +# vsrx# show protocols bgp + +# vsrx# show routing-options autonomous-system + +# Using gathered +# +# Before state: +# ------------- +# +# vsrx# show protocols bgp +# precision-timers; +# advertise-from-main-vpn-tables; +# holddown-all-stale-labels; +# description "This is configured with Junos_bgp resource module"; +# accept-remote-nexthop; +# preference 2; +# hold-time 5; +# advertise-inactive; +# no-advertise-peer-as; +# no-aggregator-id; +# out-delay 10; +# log-updown; +# damping; +# bgp-error-tolerance { +# malformed-route-limit 20000000; +# } +# authentication-algorithm md5; +# no-client-reflect; +# include-mp-next-hop; +# bmp { +# monitor enable; +# } +# add-path-display-ipv4-address; +# egress-te-sid-stats; + +- name: Gather BGP facts from running config + junipernetworks.junos.junos_bgp_global: + config: + state: gathered + +# Task Output: +# ------------ + +# gathered: +# accept_remote_nexthop: true +# add_path_display_ipv4_address: true +# advertise_from_main_vpn_tables: true +# advertise_inactive: true +# as_number: '65534' +# asdot_notation: true +# authentication_algorithm: md5 +# bgp_error_tolerance: +# malformed_route_limit: 20000000 +# bmp: +# monitor: true +# damping: true +# description: This is configured with Junos_bgp resource module +# egress_te_sid_stats: true +# hold_time: 5 +# holddown_all_stale_labels: true +# include_mp_next_hop: true +# log_updown: true +# loops: 3 +# no_advertise_peer_as: true +# no_aggregator_id: true +# no_client_reflect: true +# out_delay: 10 +# precision_timers: true +# preference: '2' + +# Using purged +# "(NOTE: This WILL delete the configured global BGP, and BGP address family config)" + +# Before state: +# ------------- +# +# vsrx# show protocols bgp +# precision-timers; +# advertise-from-main-vpn-tables; +# holddown-all-stale-labels; +# description "This is configured with Junos_bgp resource module"; +# accept-remote-nexthop; +# preference 2; +# hold-time 5; +# advertise-inactive; +# no-advertise-peer-as; +# no-aggregator-id; +# out-delay 10; +# log-updown; +# damping; +# bgp-error-tolerance { +# malformed-route-limit 20000000; +# } +# authentication-algorithm md5; +# no-client-reflect; +# include-mp-next-hop; +# bmp { +# monitor enable; +# } +# add-path-display-ipv4-address; +# egress-te-sid-stats; + +- name: Purge BGP config from running config + junipernetworks.junos.junos_bgp_global: + config: + state: purged + +# Task Output: +# ------------ + +# before: +# accept_remote_nexthop: true +# add_path_display_ipv4_address: true +# advertise_from_main_vpn_tables: true +# advertise_inactive: true +# as_number: '65534' +# asdot_notation: true +# authentication_algorithm: md5 +# bgp_error_tolerance: +# malformed_route_limit: 20000000 +# bmp: +# monitor: true +# damping: true +# description: This is configured with Junos_bgp resource module +# egress_te_sid_stats: true +# hold_time: 5 +# holddown_all_stale_labels: true +# include_mp_next_hop: true +# log_updown: true +# loops: 3 +# no_advertise_peer_as: true +# no_aggregator_id: true +# no_client_reflect: true +# out_delay: 10 +# precision_timers: true +# preference: '2' + +# commands: +# - +# - +# + +# after: {} + +# After state: +# ------------ +# vsrx# show protocols bgp + +# vsrx# show routing-options autonomous-system + +# Using rendered + +- name: Render the commands for provided configuration + junipernetworks.junos.junos_bgp_global: + config: + as_number: "65534" + loops: 3 + asdot_notation: true + accept_remote_nexthop: true + add_path_display_ipv4_address: true + advertise_from_main_vpn_tables: true + advertise_inactive: true + authentication_algorithm: "md5" + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + egress_te_sid_stats: true + hold_time: 5 + holddown_all_stale_labels: true + include_mp_next_hop: true + log_updown: true + no_advertise_peer_as: true + no_aggregator_id: true + no_client_reflect: true + out_delay: 10 + precision_timers: true + preference: 2 + state: rendered + +# Task Output: +# ------------ + +# rendered: +# +# +# + +# +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# +# +# +# +# This is configured with Junos_bgp resource module +# +# 2 +# 5 +# +# +# +# 10 +# +# +# +# 20000000 +# +# md5 +# +# +# +# +# disable +# +# +# +# +# +# static-to-bgp +# +# +# +# automatic +# 4 +# 10 +# +# +# 2 +# +# +# 300000 +# +# +# +# +# internal +# 8 +# +# +# external +# 9 +# +# +# inboun +# internal +# +# +# ibgp +# internal +# 10.2.2.2 +# static-to-bgp +# +# 10.1.1.1 +# +# +# +# +# +# 0.0.0.100 +# +# 200 +# +# +# so-0/0/0.0 +# 5 +# 3 +# +# +# +# +# +# +# +# 172.16.17.0/24 +# +# +# +# 10.200.16.75 +# +# 65432 +# +# +# +# + + +- name: Parsed the device configuration to get ansible facts + junipernetworks.junos.junos_bgp_global: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + +# Task Output: +# ------------ + +# parsed: +# accept_remote_nexthop: true +# add_path_display_ipv4_address: true +# advertise_bgp_static: +# policy: static-to-bgp +# advertise_from_main_vpn_tables: true +# advertise_inactive: true +# as_number: '65432' +# authentication_algorithm: md5 +# bfd_liveness_detection: +# detection_time: +# threshold: 300000 +# minimum_receive_interval: 4 +# multiplier: 10 +# no_adaptation: true +# transmit_interval: +# minimum_interval: 2 +# version: automatic +# bgp_error_tolerance: +# malformed_route_limit: 20000000 +# bmp: +# monitor: false +# route_monitoring: +# none: true +# damping: true +# description: This is configured with Junos_bgp resource module +# egress_te_sid_stats: true +# groups: +# - name: internal +# out_delay: 8 +# - name: external +# out_delay: 9 +# - name: inboun +# type: internal +# - export: static-to-bgp +# local_address: 10.2.2.2 +# name: ibgp +# neighbors: +# - neighbor_address: 10.1.1.1 +# type: internal +# hold_time: 5 +# holddown_all_stale_labels: true +# include_mp_next_hop: true +# log_updown: true +# no_advertise_peer_as: true +# no_aggregator_id: true +# no_client_reflect: true +# out_delay: 10 +# precision_timers: true +# preference: '2' +# remove_private: +# set: true +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + type: dict + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration model invocation. + 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: [' + + + + + md5 + This is configured with Junos_bgp resource module + 5 + + + 2 + + 4 + 10 + + automatic + + + 20000000 + + + enable + + + ', 'xml 2', 'xml 3'] +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - +gathered: + description: Facts about the network resource gathered from the remote device as structured data. + returned: when I(state) is C(gathered) + type: list + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. + returned: when I(state) is C(parsed) + type: list + sample: > + This output will always be in the same format as the + module argspec. +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.bgp_global.bgp_global import ( + Bgp_globalArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.bgp_global.bgp_global import ( + Bgp_global, +) + + +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",)), + ] + + module = AnsibleModule( + argument_spec=Bgp_globalArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + + result = Bgp_global(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_command.py b/ansible_collections/juniper/device/plugins/modules/junos_command.py new file mode 100644 index 00000000..f7746271 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_command.py @@ -0,0 +1,480 @@ +#!/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 + + +DOCUMENTATION = """ +module: junos_command +author: Peter Sprygada (@privateip) +short_description: Run arbitrary commands on an Juniper JUNOS device +description: +- Sends an arbitrary set of commands to an JUNOS 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. +version_added: 1.0.0 +extends_documentation_fragment: +- junipernetworks.junos.junos +options: + commands: + description: + - The commands to send to the remote junos device. 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 I(retries) has been exceeded. + type: list + elements: str + rpcs: + description: + - The C(rpcs) argument accepts a list of RPCs to be executed over a netconf session + and the results from the RPC execution is return to the playbook via the modules + results dictionary. + type: list + elements: str + wait_for: + description: + - Specifies what to evaluate from the output of the command and what conditionals + to apply. This argument will cause the task to wait for a particular conditional + to be true before moving forward. If the conditional is not true by the configured + retries, the task fails. See examples. + type: list + elements: str + aliases: + - waitfor + 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 I(wait_for) must be satisfied. If + the value is set to C(any) then only one of the values must be satisfied. + type: str + default: all + choices: + - any + - all + retries: + description: + - Specifies the number of retries a command should be tried before it is considered + failed. The command is run on the target device every retry and evaluated against + the I(wait_for) conditionals. + type: int + default: 10 + interval: + description: + - Configures the interval in seconds to wait between retries of the command. If + the command does not pass the specified conditional, the interval indicates + how to long to wait before trying the command again. + type: int + default: 1 + display: + description: + - Encoding scheme to use when serializing output from the device. This handles + how to properly understand the output and apply the conditionals path to the + result set. For I(rpcs) argument default display is C(xml) and for I(commands) + argument default display is C(text). Value C(set) is applicable only for fetching + configuration from device. + type: str + aliases: + - format + - output + choices: + - text + - json + - xml + - set +requirements: +- jxmlease +- ncclient (>=v0.5.2) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. +- Recommended connection is C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +- This module also works with C(network_cli) connections and with C(local) connections + for legacy playbooks. +""" + +EXAMPLES = """ +- name: run show version on remote devices + junipernetworks.junos.junos_command: + commands: show version + +- name: run show version and check to see if output contains Juniper + junipernetworks.junos.junos_command: + commands: show version + wait_for: result[0] contains Juniper + +- name: run multiple commands on remote nodes + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces + +- name: run multiple commands and evaluate the output + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces + wait_for: + - result[0] contains Juniper + - result[1] contains Loopback0 + +- name: run commands and specify the output format + junipernetworks.junos.junos_command: + commands: show version + display: json + +- name: run rpc on the remote device + junipernetworks.junos.junos_command: + commands: show configuration + display: set + +- name: run rpc on the remote device + junipernetworks.junos.junos_command: + rpcs: get-software-information +""" + +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: [['...', '...'], ['...'], ['...']] +output: + description: The set of transformed xml to json format from the commands responses + returned: If the I(display) is in C(xml) format. + type: list + sample: ['...', '...'] +failed_conditions: + description: The list of conditionals that have failed + returned: failed + type: list + sample: ['...', '...'] +""" +import re +import shlex +import time + +from ansible.module_utils._text import to_text +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import ConnectionError +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf import ( + exec_rpc, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.parsing import ( + Conditional, + FailedConditionalError, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_lines + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + get_capabilities, + get_configuration, + get_connection, + tostring, +) + + +try: + from lxml.etree import Element, SubElement +except ImportError: + from xml.etree.ElementTree import Element, SubElement + +try: + import jxmlease + + HAS_JXMLEASE = True +except ImportError: + HAS_JXMLEASE = False + +USE_PERSISTENT_CONNECTION = True + + +def rpc(module, items): + responses = list() + for item in items: + name = item["name"] + xattrs = item["xattrs"] + fetch_config = False + + args = item.get("args") + text = item.get("text") + + name = str(name).replace("_", "-") + + if all((module.check_mode, not name.startswith("get"))): + module.fail_json(msg="invalid rpc for running in check_mode") + + if name == "command" and text == "show configuration" or name == "get-configuration": + fetch_config = True + + element = Element(name, xattrs) + + if text: + element.text = text + + elif args: + for key, value in iteritems(args): + key = str(key).replace("_", "-") + if isinstance(value, list): + for item in value: + child = SubElement(element, key) + if item is not True: + child.text = item + else: + child = SubElement(element, key) + if value is not True: + child.text = value + if fetch_config: + reply = get_configuration(module, format=xattrs["format"]) + else: + reply = exec_rpc(module, tostring(element), ignore_warning=False) + + if xattrs["format"] == "text": + if len(reply) >= 1: + if fetch_config: + data = reply.find(".//configuration-text") + else: + if text and text.startswith("show configuration"): + data = reply.find(".//configuration-output") + else: + data = reply.find(".//output") + + if data is None: + module.fail_json(msg=tostring(reply)) + + responses.append(data.text.strip()) + else: + responses.append(reply.text.strip()) + + elif xattrs["format"] == "json": + responses.append(module.from_json(reply.text.strip())) + + elif xattrs["format"] == "set": + data = reply.find(".//configuration-set") + if data is None: + module.fail_json( + msg="Display format 'set' is not supported by remote device.", + ) + responses.append(data.text.strip()) + + else: + responses.append(tostring(reply)) + + return responses + + +def split(value): + lex = shlex.shlex(value) + lex.quotes = '"' + lex.whitespace_split = True + lex.commenters = "" + return list(lex) + + +def parse_rpcs(module): + items = list() + + for rpc in module.params["rpcs"] or list(): + parts = shlex.split(rpc) + + name = parts.pop(0) + args = dict() + + for item in parts: + key, value = item.split("=") + if str(value).upper() in ["TRUE", "FALSE"]: + args[key] = bool(value) + elif re.match(r"^[0-9]+$", value): + args[key] = int(value) + else: + args[key] = str(value) + + display = module.params["display"] or "xml" + + if display == "set" and rpc != "get-configuration": + module.fail_json( + msg="Invalid display option '%s' given for rpc '%s'" % ("set", name), + ) + + xattrs = {"format": display} + items.append({"name": name, "args": args, "xattrs": xattrs}) + + return items + + +def parse_commands(module, warnings): + items = list() + + for command in module.params["commands"] or list(): + if module.check_mode and not command.startswith("show"): + warnings.append( + "Only show commands are supported when using check_mode, not " + "executing %s" % command, + ) + continue + + parts = command.split("|") + text = parts[0] + + display = module.params["display"] or "text" + + if "| display json" in command: + display = "json" + + elif "| display xml" in command: + display = "xml" + + if display == "set" or "| display set" in command: + if command.startswith("show configuration"): + display = "set" + else: + module.fail_json( + msg="Invalid display option '%s' given for command '%s'" % ("set", command), + ) + + xattrs = {"format": display} + items.append({"name": "command", "xattrs": xattrs, "text": text}) + + return items + + +def main(): + """entry point for module execution""" + argument_spec = dict( + commands=dict(type="list", elements="str"), + rpcs=dict(type="list", elements="str"), + display=dict( + choices=["text", "json", "xml", "set"], + aliases=["format", "output"], + ), + wait_for=dict(type="list", aliases=["waitfor"], elements="str"), + match=dict(default="all", choices=["all", "any"]), + retries=dict(default=10, type="int"), + interval=dict(default=1, type="int"), + ) + + required_one_of = [("commands", "rpcs")] + + module = AnsibleModule( + argument_spec=argument_spec, + required_one_of=required_one_of, + supports_check_mode=True, + ) + + warnings = list() + conn = get_connection(module) + capabilities = get_capabilities(module) + + if capabilities.get("network_api") == "cliconf": + if any( + ( + module.params["wait_for"], + module.params["match"], + module.params["rpcs"], + ), + ): + module.warn( + "arguments wait_for, match, rpcs are not supported when using transport=cli", + ) + commands = module.params["commands"] + + output = list() + display = module.params["display"] + for cmd in commands: + # if display format is not mentioned in command, add the display format + # from the modules params + if ("display json" not in cmd) and ("display xml" not in cmd): + if display and display != "text": + cmd += " | display {0}".format(display) + try: + output.append(conn.get(command=cmd)) + except ConnectionError as exc: + module.fail_json( + msg=to_text(exc, errors="surrogate_then_replace"), + ) + + lines = [out.split("\n") for out in output] + result = {"changed": False, "stdout": output, "stdout_lines": lines} + module.exit_json(**result) + + items = list() + items.extend(parse_commands(module, warnings)) + items.extend(parse_rpcs(module)) + + wait_for = module.params["wait_for"] or list() + conditionals = [Conditional(c) for c in wait_for] + + retries = module.params["retries"] + interval = module.params["interval"] + match = module.params["match"] + while retries > 0: + responses = rpc(module, items) + transformed = list() + output = list() + for item, resp in zip(items, responses): + if item["xattrs"]["format"] == "xml": + if not HAS_JXMLEASE: + module.fail_json( + msg="jxmlease is required but does not appear to be installed. " + "It can be installed using `pip install jxmlease`", + ) + + try: + json_resp = jxmlease.parse(resp) + transformed.append(json_resp) + output.append(json_resp) + except Exception: + raise ValueError(resp) + else: + transformed.append(resp) + + for item in list(conditionals): + try: + if item(transformed): + if match == "any": + conditionals = list() + break + conditionals.remove(item) + except FailedConditionalError: + pass + + 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 = { + "changed": False, + "warnings": warnings, + "stdout": responses, + "stdout_lines": list(to_lines(responses)), + } + + if output: + result["output"] = output + + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_config.py b/ansible_collections/juniper/device/plugins/modules/junos_config.py new file mode 100644 index 00000000..773489ea --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_config.py @@ -0,0 +1,537 @@ +#!/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 + + +DOCUMENTATION = """ +module: junos_config +author: Peter Sprygada (@privateip) +short_description: Manage configuration on devices running Juniper JUNOS +description: +- This module provides an implementation for working with the active configuration + running on Juniper JUNOS devices. It provides a set of arguments for loading configuration, + performing rollback operations and zeroing the active configuration on the device. +version_added: 1.0.0 +extends_documentation_fragment: +- junipernetworks.junos.junos +options: + lines: + description: + - This argument takes a list of C(set) or C(delete) configuration lines to push + into the remote device. Each line must start with either C(set) or C(delete). This + argument is mutually exclusive with the I(src) argument. + type: list + aliases: + - commands + elements: str + src: + description: + - The I(src) argument provides a path to the configuration file to load into the + remote system. The path can either be a full system path to the configuration + file if the value starts with / or relative to the root of the implemented role + or playbook. This argument is mutually exclusive with the I(lines) argument. + type: path + src_format: + description: + - The I(src_format) argument specifies the format of the configuration found int + I(src). If the I(src_format) argument is not provided, the module will attempt + to determine the format of the configuration file specified in I(src). + type: str + choices: + - xml + - set + - text + - json + rollback: + description: + - The C(rollback) argument instructs the module to rollback the current configuration + to the identifier specified in the argument. If the specified rollback identifier + does not exist on the remote device, the module will fail. To rollback to the + most recent commit, set the C(rollback) argument to 0. + type: int + zeroize: + description: + - The C(zeroize) argument is used to completely sanitize the remote device configuration + back to initial defaults. This argument will effectively remove all current + configuration statements on the remote device. + type: bool + default: false + confirm: + description: + - The C(confirm) argument will configure a time out value in minutes for the commit + to be confirmed before it is automatically rolled back. If the value for this argument + is set to 0, the commit is confirmed immediately which is also the default behaviour. + type: int + default: 0 + comment: + description: + - The C(comment) argument specifies a text string to be used when committing the + configuration. If the C(confirm) argument is set to False, this argument is + silently ignored. + default: configured by junos_config + type: str + replace: + description: + - The C(replace) argument will instruct the remote device to replace the current + configuration hierarchy with the one specified in the corresponding hierarchy + of the source configuration loaded from this module. + - Note this argument should be considered deprecated. To achieve the equivalent, + set the I(update) argument to C(replace). This argument will be removed in a + future release. The C(replace) and C(update) argument is mutually exclusive. + type: bool + 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: false + update: + description: + - This argument will decide how to load the configuration data particularly when + the candidate configuration and loaded configuration contain conflicting statements. + Following are accepted values. C(merge) combines the data in the loaded configuration + with the candidate configuration. If statements in the loaded configuration + conflict with statements in the candidate configuration, the loaded statements + replace the candidate ones. C(override) discards the entire candidate configuration + and replaces it with the loaded configuration. C(replace) substitutes each hierarchy + level in the loaded configuration for the corresponding level. C(update) is + similar to the override option. The new configuration completely replaces the + existing configuration. The difference comes when the configuration is later + committed. This option performs a 'diff' between the new candidate configuration + and the existing committed configuration. It then only notifies system processes + responsible for the changed portions of the configuration, and only marks the + actual configuration changes as 'changed'. + type: str + default: merge + choices: + - merge + - override + - replace + - update + confirm_commit: + description: + - This argument will execute commit operation on remote device. It can be used + to confirm a previous commit. + type: bool + default: false + check_commit: + description: + - This argument will check correctness of syntax; do not apply changes. + - Note that this argument can be used to confirm verified configuration done via + commit confirmed operation + type: bool + default: false + 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(true), + if C(backup) is set to I(false) 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.@ + type: str + 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 + backup_format: + description: + - This argument specifies the format of the configuration the backup file will + be stored as. If the argument is not specified, the module will use the 'set' + format. + type: str + default: set + choices: + - xml + - set + - text + - json + type: dict +requirements: +- ncclient (>=v0.5.2) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Abbreviated commands are NOT idempotent, see L(Network FAQ,../network/user_guide/faq.html) +- Loading JSON-formatted configuration I(json) is supported starting in Junos OS Release + 16.1 onwards. +- Update C(override) not currently compatible with C(set) notation. +- Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. +- Recommended connection is C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +- This module also works with C(local) connections for legacy playbooks. +""" + +EXAMPLES = """ +- name: load configure file into device + junipernetworks.junos.junos_config: + src: srx.cfg + comment: update config + +- name: load configure lines into device + junipernetworks.junos.junos_config: + lines: + - set interfaces ge-0/0/1 unit 0 description "Test interface" + - set vlans vlan01 description "Test vlan" + comment: update config + +- name: Set routed VLAN interface (RVI) IPv4 address + junipernetworks.junos.junos_config: + lines: + - set vlans vlan01 vlan-id 1 + - set interfaces irb unit 10 family inet address 10.0.0.1/24 + - set vlans vlan01 l3-interface irb.10 + +- name: Check correctness of commit configuration + junipernetworks.junos.junos_config: + check_commit: true + +- name: rollback the configuration to id 10 + junipernetworks.junos.junos_config: + rollback: 10 + +- name: zero out the current configuration + junipernetworks.junos.junos_config: + zeroize: true + +- name: Set VLAN access and trunking + junipernetworks.junos.junos_config: + lines: + - set vlans vlan02 vlan-id 6 + - set interfaces ge-0/0/6.0 family ethernet-switching interface-mode access vlan + members vlan02 + - set interfaces ge-0/0/6.0 family ethernet-switching interface-mode trunk vlan + members vlan02 + +- name: confirm a previous commit + junipernetworks.junos.junos_config: + confirm_commit: true + +- name: for idempotency, use full-form commands + junipernetworks.junos.junos_config: + lines: + - set interfaces ge-0/0/1 unit 0 description "Test interface" + +- name: configurable backup path + junipernetworks.junos.junos_config: + src: srx.cfg + backup: true + backup_options: + filename: backup.cfg + dir_path: /home/user + +- name: Set description with timer to confirm commit + junipernetworks.junos.junos_config: + lines: + - set interfaces fxp0 description "wait for a commit confirmation for 3 minutes; otherwise, it will be rolled back." + confirm: 3 + +- name: Perform confirm commit + junipernetworks.junos.junos_config: + confirm_commit: true +""" + +RETURN = """ +backup_path: + description: The full path to the backup file + returned: when backup is true + type: str + sample: /playbooks/ansible/backup/config.2016-07-16@22:28:34 +filename: + description: The name of the backup file + returned: when backup is true and filename is not specified in backup options + type: str + sample: junos01_config.2016-07-16@22:28:34 +shortname: + description: The full path to the backup file excluding the timestamp + returned: when backup is true and filename is not specified in backup options + type: str + sample: /playbooks/ansible/backup/junos01_config +date: + description: The date extracted from the backup file name + returned: when backup is true + type: str + sample: "2016-07-16" +time: + description: The time extracted from the backup file name + returned: when backup is true + type: str + sample: "22:28:34" +""" +import json +import re + +from ansible.module_utils._text import to_native, to_text +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import string_types +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf import ( + exec_rpc, +) + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + commit_configuration, + discard_changes, + get_configuration, + get_diff, + load_config, + load_configuration, + locked_config, + tostring, +) + + +try: + from lxml.etree import Element, fromstring +except ImportError: + from xml.etree.ElementTree import Element, fromstring + +try: + from lxml.etree import ParseError +except ImportError: + try: + from xml.etree.ElementTree import ParseError + except ImportError: + # for Python < 2.7 + from xml.parsers.expat import ExpatError + + ParseError = ExpatError + +USE_PERSISTENT_CONNECTION = True +DEFAULT_COMMENT = "configured by junos_config" + + +def check_args(module, warnings): + if module.params["replace"] is not None: + module.fail_json(msg="argument replace is deprecated, use update") + + +def zeroize(module): + return exec_rpc( + module, + tostring(Element("request-system-zeroize")), + ignore_warning=False, + ) + + +def rollback(ele, id="0"): + return get_diff(ele, id) + + +def guess_format(config): + try: + json.loads(config) + return "json" + except ValueError: + pass + + try: + fromstring(config) + return "xml" + except ParseError: + pass + + if config.startswith("set") or config.startswith("delete"): + return "set" + + return "text" + + +def filter_delete_statements(module, candidate): + reply = get_configuration(module, format="set") + match = reply.find(".//configuration-set") + if match is None: + # Could not find configuration-set in reply, perhaps device does not support it? + return candidate + config = to_native(match.text, encoding="latin-1") + + modified_candidate = candidate[:] + for index, line in reversed(list(enumerate(candidate))): + if line.startswith("delete"): + newline = re.sub("^delete", "set", line) + if newline not in config: + del modified_candidate[index] + + return modified_candidate + + +def configure_device(module, warnings, candidate): + kwargs = {} + config_format = None + + if module.params["src"]: + config_format = module.params["src_format"] or guess_format( + str(candidate), + ) + if config_format == "set": + kwargs.update({"format": "text", "action": "set"}) + else: + kwargs.update( + {"format": config_format, "action": module.params["update"]}, + ) + + if isinstance(candidate, string_types): + candidate = candidate.split("\n") + + # this is done to filter out `delete ...` statements which map to + # nothing in the config as that will cause an exception to be raised + if any((module.params["lines"], config_format == "set")): + candidate = filter_delete_statements(module, candidate) + kwargs["format"] = "text" + kwargs["action"] = "set" + + return load_config(module, candidate, warnings, **kwargs) + + +def main(): + """main entry point for module execution""" + backup_spec = dict( + filename=dict(), + dir_path=dict(type="path"), + backup_format=dict( + default="set", + choices=["xml", "text", "set", "json"], + ), + ) + argument_spec = dict( + lines=dict(aliases=["commands"], type="list", elements="str"), + src=dict(type="path"), + src_format=dict(choices=["xml", "text", "set", "json"]), + # update operations + update=dict( + default="merge", + choices=["merge", "override", "replace", "update"], + ), + # deprecated replace in Ansible 2.3 + replace=dict(type="bool"), + confirm=dict(default=0, type="int"), + comment=dict(default=DEFAULT_COMMENT), + confirm_commit=dict(type="bool", default=False), + check_commit=dict(type="bool", default=False), + # config operations + backup=dict(type="bool", default=False), + backup_options=dict(type="dict", options=backup_spec), + rollback=dict(type="int"), + zeroize=dict(default=False, type="bool"), + ) + + mutually_exclusive = [("lines", "src", "rollback", "zeroize")] + + module = AnsibleModule( + argument_spec=argument_spec, + mutually_exclusive=mutually_exclusive, + supports_check_mode=True, + ) + + warnings = list() + check_args(module, warnings) + + candidate = module.params["lines"] or module.params["src"] + commit = not module.check_mode + + result = {"changed": False, "warnings": warnings} + + if module.params["backup"]: + if module.params["backup_options"] is not None: + conf_format = module.params["backup_options"]["backup_format"] + else: + conf_format = "set" + reply = get_configuration(module, format=conf_format) + if reply is None: + module.fail_json(msg="unable to retrieve device configuration") + else: + if conf_format in ["set", "text"]: + reply = reply.find( + ".//configuration-%s" % conf_format, + ).text.strip() + elif conf_format in "xml": + reply = str( + tostring(reply.find(".//configuration"), pretty_print=True), + ).strip() + elif conf_format in "json": + reply = str(reply.xpath("//rpc-reply/text()")[0]).strip() + if not isinstance(reply, str): + module.fail_json( + msg="unable to format retrieved device configuration", + ) + result["__backup__"] = reply + + rollback_id = module.params["rollback"] + if isinstance(rollback_id, int) and rollback_id >= 0: + diff = rollback(module, rollback_id) + if commit: + kwargs = {"comment": module.params["comment"]} + with locked_config(module): + load_configuration(module, rollback=rollback_id) + commit_configuration(module, **kwargs) + if module._diff: + result["diff"] = {"prepared": diff} + result["changed"] = True + + elif module.params["zeroize"]: + if commit: + zeroize(module) + result["changed"] = True + + else: + if candidate: + with locked_config(module): + diff = configure_device(module, warnings, candidate) + if diff: + if commit: + kwargs = { + "comment": module.params["comment"], + "check": module.params["check_commit"], + } + + confirm = module.params["confirm"] + if confirm > 0: + kwargs.update( + { + "confirm": True, + "confirm_timeout": to_text( + confirm, + errors="surrogate_then_replace", + ), + }, + ) + commit_configuration(module, **kwargs) + else: + discard_changes(module) + result["changed"] = True + + if module._diff: + result["diff"] = {"prepared": diff} + + elif module.params["check_commit"]: + commit_configuration(module, check=True) + + elif module.params["confirm_commit"]: + with locked_config(module): + # confirm a previous commit + commit_configuration(module) + + result["changed"] = True + + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_facts.py b/ansible_collections/juniper/device/plugins/modules/junos_facts.py new file mode 100644 index 00000000..6b45889f --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_facts.py @@ -0,0 +1,146 @@ +#!/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 + + +DOCUMENTATION = """ +module: junos_facts +author: Nathaniel Case (@Qalthos) +short_description: Collect facts from remote devices running Juniper Junos +description: +- Collects fact information from a remote device running the Junos operating system. By + default, the module will collect basic fact information from the device to be included + with the hostvars. Additional fact information can be collected based on the configured + set of arguments. +version_added: 1.0.0 +extends_documentation_fragment: +- juniper.device.junos +options: + gather_subset: + description: + - When supplied, this argument will restrict the facts collected to a given subset. Possible + values for this argument include C(all), C(hardware), C(config), C(interfaces) and C(min). Can + specify a list of values to include a larger subset. Values can also be used + with an initial C(!) to specify that a specific subset should not be collected. + To maintain backward compatibility old style facts can be retrieved by explicitly + adding C(ofacts) to value, this requires junos-eznc to be installed as a prerequisite. + Valid value of gather_subset are default, hardware, config, interfaces, ofacts. + If C(ofacts) is present in the list it fetches the old style facts (fact keys + without 'ansible_' prefix) and it requires junos-eznc library to be installed. + required: false + default: + - 'min' + type: list + elements: str + config_format: + description: + - The I(config_format) argument specifies the format of the configuration when + serializing output from the device. This argument is applicable only when C(config) + value is present in I(gather_subset). The I(config_format) should be supported + by the junos version running on device. This value is not applicable while fetching + old style facts that is when C(ofacts) value is present in value if I(gather_subset) + value. This option is valid only for C(gather_subset) values. + type: str + required: false + default: text + choices: + - xml + - text + - set + - json + 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(!) to specify that a specific subset should + not be collected. Valid subsets are 'all', 'interfaces', 'lacp', 'lacp_interfaces', + 'lag_interfaces', 'l2_interfaces', 'l3_interfaces', 'lldp_global', 'lldp_interfaces', + 'vlans'. + required: false + type: list + elements: str + available_network_resources: + description: When 'True' a list of network resources for which resource modules are available will be provided. + type: bool + default: false +requirements: +- ncclient (>=v0.5.2) +notes: +- Ensure I(config_format) used to retrieve configuration from device is supported + by junos version running on device. +- With I(config_format = json), configuration in the results will be a dictionary(and + not a JSON string) +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. +- Recommended connection is C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +- This module also works with C(local) connections for legacy playbooks. +""" + +EXAMPLES = """ +- name: collect default set of facts + juniper.device.junos_facts: + +- name: collect default set of facts and configuration + juniper.device.junos_facts: + gather_subset: config + +- name: Gather legacy and resource facts + juniper.device.junos_facts: + gather_subset: all + gather_network_resources: all +""" + +RETURN = """ +ansible_facts: + description: Returns the facts collect from the device + returned: always + type: dict +""" +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.facts.facts import ( + FactsArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.facts.facts import ( + FACT_RESOURCE_SUBSETS, + Facts, +) + + +def main(): + """ + Main entry point for module execution + + :returns: ansible_facts + """ + argument_spec = FactsArgs.argument_spec + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + warnings = [] + ansible_facts = {} + if module.params.get("available_network_resources"): + ansible_facts["available_network_resources"] = sorted( + FACT_RESOURCE_SUBSETS.keys(), + ) + result = Facts(module).get_facts() + additional_facts, additional_warnings = result + ansible_facts.update(additional_facts) + warnings.extend(additional_warnings) + module.exit_json(ansible_facts=ansible_facts, warnings=warnings) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/ansible_collections/juniper/device/plugins/modules/junos_hostname.py b/ansible_collections/juniper/device/plugins/modules/junos_hostname.py new file mode 100644 index 00000000..f61a1742 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_hostname.py @@ -0,0 +1,361 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# 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 junos_hostname +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +ANSIBLE_METADATA = { + "metadata_version": "1.1", + "status": ["preview"], + "supported_by": "network", +} + +DOCUMENTATION = """ +--- +module: junos_hostname +version_added: 2.9.0 +short_description: Manage Hostname server configuration on Junos devices. +description: This module manages hostname configuration on devices running Junos. +author: Rohit Thakur (@rohitthakur2590) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection C(netconf). + - See L(the Junos OS Platform Options,https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html). + - Tested against JunOS v18.4R1 +options: + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show system hostname). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result. + type: str + config: + description: A dictionary of system Hostname configuration. + type: dict + suboptions: + hostname: + description: Specify the hostname. + 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 states I(merged), I(replaced) and I(overridden) have identical + behaviour for this module. + - 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 system hostname) executed on device. For state I(parsed) active + connection to remote host is not required. + type: str + choices: + - merged + - replaced + - deleted + - overridden + - parsed + - gathered + - rendered + default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# vagrant@vsrx# show system hostname +# +# [edit] +- name: Merge provided HOSTNAME configuration into running configuration. + junipernetworks.junos.junos_hostname: + config: + hostname: 'vsrx-18.4R1' + state: merged +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "hostname": "vsrx-18.4R1" +# }, +# "before": {}, +# "changed": true, +# "commands": [ +# " +# "vsrx-18.4R1" +# ] +# After state +# ----------- +# +# vagrant@vsrx-18.4R1# show system host-name +# host-name vsrx-18.4R1; +# +# Using replaced +# +# Before state +# ------------ +# +# vagrant@vsrx-18.4R1# show system host-name +# host-name vsrx-18.4R1; +# +# [edit] +- name: Replaced target config with provided config. + junipernetworks.junos.junos_hostname: + config: + hostname: 'vsrx-12' + state: replaced +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "hostname": "vsrx-12" +# }, +# "before": { +# "hostname": "vsrx-18.4R1" +# }, +# "changed": true, +# "commands": [ +# " +# "vsrx-12" +# ] +# After state +# ----------- +# +# vagrant@vsrx-18.4R1# show system host-name +# host-name vsrx-12; +# +# Using overridden +# +# Before state +# ------------ +# +# vagrant@vsrx-18.4R1# show system host-name +# host-name vsrx-18.4R1; +# +# [edit] +- name: Replaced target config with provided config. + junipernetworks.junos.junos_hostname: + config: + hostname: 'vsrx-12' + state: overridden +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "hostname": "vsrx-12" +# }, +# "before": { +# "hostname": "vsrx-18.4R1" +# }, +# "changed": true, +# "commands": [ +# " +# "vsrx-12" +# ] +# After state +# ----------- +# +# vagrant@vsrx-18.4R1# show system host-name +# host-name vsrx-12; +# +# Using deleted +# +# Before state +# ------------ +# +# vagrant@vsrx-18.4R1# show system host-name +# host-name vsrx-12; +# +- name: Delete running HOSTNAME global configuration + junipernetworks.junos.junos_hostname: + config: + state: deleted +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": {}, +# "before": { +# "hostname": "vsrx-12" +# }, +# "changed": true, +# "commands": [ +# " +# " +# ] +# After state +# ----------- +# +# vagrant@vsrx# show system ntp +# +# [edit] +# Using gathered +# +# Before state +# ------------ +# +# vagrant@vsrx-18.4R1# show system host-name +# host-name vsrx-12; +# +- name: Gather running HOSTNAME global configuration + junipernetworks.junos.junos_hostname: + state: gathered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "gathered": { +# "hostname": "vsrx-12", +# }, +# "changed": false, +# Using rendered +# +# Before state +# ------------ +# +- name: Render xml for provided facts. + junipernetworks.junos.junos_hostname: + config: + boot_server: '78.46.194.186' + state: rendered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "rendered": [ +# "" +# "78.46.194.186" +# ] +# +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# vsrx-18.4R1 +# +# +# +# +- name: Parse HOSTNAME running config + junipernetworks.junos.junos_hostname: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "parsed": { +# "hostname": "vsrx-18.4R1" +# } +# +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: dict +after: + description: The resulting configuration model invocation. + returned: when changed + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: dict +commands: + description: The set of commands pushed to the remote device. + returned: always + type: list + sample: ['"78.46.194.186"'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.hostname.hostname import ( + HostnameArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.hostname.hostname import ( + Hostname, +) + + +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",)), + ] + module = AnsibleModule( + argument_spec=HostnameArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + + result = Hostname(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_interfaces.py b/ansible_collections/juniper/device/plugins/modules/junos_interfaces.py new file mode 100644 index 00000000..a1bb88d9 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_interfaces.py @@ -0,0 +1,966 @@ +#!/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 junos_interfaces +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_interfaces +short_description: Junos Interfaces resource module +description: This module manages the interfaces on Juniper Junos OS network devices. +version_added: 1.0.0 +author: Ganesh Nalawade (@ganeshrn) +options: + config: + description: The provided configuration + type: list + elements: dict + suboptions: + name: + description: + - Full name of interface, e.g. ge-0/0/0. + type: str + required: true + description: + description: + - Interface description. + type: str + 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: + - automatic + - full-duplex + - half-duplex + enabled: + default: true + description: + - Administrative state of the interface. + - Set the value to C(true) to administratively enabled the interface or C(false) + to disable it. + type: bool + hold_time: + description: + - The hold time for given interface name. + type: dict + suboptions: + down: + description: + - The link down hold time in milliseconds. + type: int + up: + description: + - The link up hold time in milliseconds. + type: int + mtu: + description: + - MTU for a specific interface. + - Applicable for Ethernet interfaces only. + type: int + speed: + description: + - Interface link speed. Applicable for Ethernet interfaces only. + type: str + units: + description: + - Specify Logical interfaces units. + type: list + elements: dict + suboptions: + name: + description: + - Specify interface unit number. + type: int + description: + description: Specify logical interface description. + type: str + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show interfaces). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result. + type: str + state: + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - parsed + - rendered + default: merged + description: + - The state of the configuration after module completion + type: str +requirements: +- ncclient (>=v0.6.4) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 18.4R1. +- This module works with connection C(netconf). + See U(https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html) +- The module examples uses callback plugin (stdout_callback = yaml) to generate task + output in yaml format. +""" +EXAMPLES = """ +# Using merged + +# Before state: +# ------------- +# +# user@junos01# show interfaces +# ge-0/0/1 { +# description "test interface"; +# speed 1g; +# } +# fe-0/0/2 { +# vlan-tagging; +# unit 10 { +# vlan-id 10; +# } +# unit 11 { +# vlan-id 11; +# } +# } +# ge-0/0/3 { +# description "Configured by Ansible-3"; +# } +# fxp0 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# lo0 { +# unit 0 { +# family inet { +# address 192.0.2.1/32; +# } +# } +# } + +- name: Merge provided configuration with device configuration (default operation + is merge) + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/1 + description: Configured by Ansible-1 + enabled: true + units: + - name: 0 + description: "This is logical intf unit0" + mtu: 1800 + - name: ge-0/0/2 + description: Configured by Ansible-2 + enabled: false + state: merged + +# Task Output +# ----------- +# +# before: +# - description: test interface +# enabled: true +# name: ge-0/0/1 +# speed: 1g +# - enabled: true +# name: fe-0/0/2 +# - description: Configured by Ansible-3 +# enabled: true +# name: ge-0/0/3 +# - enabled: true +# name: fxp0 +# - enabled: true +# name: lo0 +# commands: +# - ge-0/0/1 +# Configured by Ansible-118000 +# This is logical intf unit0ge-0/0/2 +# Configured by Ansible-2 +# after: +# - description: Configured by Ansible-1 +# enabled: true +# mtu: 1800 +# name: ge-0/0/1 +# speed: 1g +# units: +# - description: This is logical intf unit0 +# name: 0 +# - enabled: true +# name: fe-0/0/2 +# - description: Configured by Ansible-2 +# enabled: false +# name: ge-0/0/2 +# - description: Configured by Ansible-3 +# enabled: true +# name: ge-0/0/3 +# - enabled: true +# name: fxp0 +# - enabled: true +# name: lo0 + +# After state: +# ------------ +# +# user@junos01# show interfaces +# ge-0/0/1 { +# description "Configured by Ansible-1"; +# speed 1g; +# mtu 1800; +# unit 0 { +# description "This is logical intf unit0"; +# } +# } +# fe-0/0/2 { +# vlan-tagging; +# unit 10 { +# vlan-id 10; +# } +# unit 11 { +# vlan-id 11; +# } +# } +# ge-0/0/2 { +# description "Configured by Ansible-2"; +# disable; +# } +# ge-0/0/3 { +# description "Configured by Ansible-3"; +# } +# fxp0 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# lo0 { +# unit 0 { +# family inet { +# address 192.0.2.1/32; +# } +# } +# } + +# Using deleted + +# Before state: +# ------------- +# +# ge-0/0/1 { +# description "Configured by Ansible-1"; +# speed 1g; +# mtu 1800; +# unit 0 { +# description "This is logical intf unit0"; +# } +# } +# fe-0/0/2 { +# vlan-tagging; +# unit 10 { +# vlan-id 10; +# } +# unit 11 { +# vlan-id 11; +# } +# } +# ge-0/0/2 { +# description "Configured by Ansible-2"; +# disable; +# } +# ge-0/0/3 { +# description "Configured by Ansible-3"; +# } +# fxp0 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# lo0 { +# unit 0 { +# family inet { +# address 192.0.2.1/32; +# } +# } +# } + +- name: "Delete given options for the interface (Note: This won't delete the interface itself if any other values are configured for interface)" + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/1 + description: Configured by Ansible-1 + speed: 1g + mtu: 1800 + - name: ge-0/0/2 + description: Configured by Ansible -2 + state: deleted + +# Task Output +# ----------- +# +# before: +# - description: Configured by Ansible-1 +# enabled: true +# mtu: 1800 +# name: ge-0/0/1 +# speed: 1g +# units: +# - description: This is logical intf unit0 +# name: 0 +# - enabled: true +# name: fe-0/0/2 +# - description: Configured by Ansible-2 +# enabled: false +# name: ge-0/0/2 +# - description: Configured by Ansible-3 +# enabled: true +# name: ge-0/0/3 +# - enabled: true +# name: fxp0 +# - enabled: true +# name: lo0 +# commands: +# - +# ge-0/0/1 +# +# +# 0ge-0/0/2 +# +# +# +# after: +# - enabled: true +# name: ge-0/0/1 +# - enabled: true +# name: fe-0/0/2 +# - description: Configured by Ansible-3 +# enabled: true +# name: ge-0/0/3 +# - enabled: true +# name: fxp0 +# - enabled: true +# name: lo0 + +# After state: +# ------------ +# +# user@junos01# show interfaces +# ge-0/0/1 { +# unit 0; +# } +# fe-0/0/2 { +# vlan-tagging; +# unit 10 { +# vlan-id 10; +# } +# unit 11 { +# vlan-id 11; +# } +# } +# ge-0/0/3 { +# description "Configured by Ansible-3"; +# } +# fxp0 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# lo0 { +# unit 0 { +# family inet { +# address 192.0.2.1/32; +# } +# } +# } + +# Using overridden + +# Before state: +# ------------- +# +# user@junos01# show interfaces +# ge-0/0/1 { +# unit 0; +# } +# fe-0/0/2 { +# vlan-tagging; +# unit 10 { +# vlan-id 10; +# } +# unit 11 { +# vlan-id 11; +# } +# } +# ge-0/0/3 { +# description "Configured by Ansible-3"; +# } +# fxp0 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# lo0 { +# unit 0 { +# family inet { +# address 192.0.2.1/32; +# } +# } +# } + +- name: Override device configuration of all interfaces with provided configuration + junipernetworks.junos.junos_interfaces: + config: + - enabled: true + name: ge-0/0/1 + - name: fe-0/0/2 + description: Configured by Ansible-2 + enabled: false + mtu: 2800 + - description: Updated by Ansible-3 + enabled: true + name: ge-0/0/3 + - enabled: true + name: fxp0 + - enabled: true + name: lo0 + state: overridden + +# Task Output +# ----------- +# +# before: +# - enabled: true +# name: ge-0/0/1 +# - enabled: true +# name: fe-0/0/2 +# - description: Configured by Ansible-3 +# enabled: true +# name: ge-0/0/3 +# - enabled: true +# name: fxp0 +# - enabled: true +# name: lo0 +# commands: +# - +# ge-0/0/1 +# +# +# fe-0/0/2 +# +# +# ge-0/0/3 +# +# +# fxp0 +# +# +# lo0 +# +# +# ge-0/0/1 +# fe-0/0/2 +# Configured by Ansible-2 +# 2800 +# ge-0/0/3Updated by Ansible-3 +# fxp0 +# lo0 +# after: +# - enabled: true +# name: ge-0/0/1 +# - description: Configured by Ansible-2 +# enabled: false +# mtu: 2800 +# name: fe-0/0/2 +# - description: Updated by Ansible-3 +# enabled: true +# name: ge-0/0/3 +# - enabled: true +# name: fxp0 +# - enabled: true +# name: lo0 + +# After state: +# ------------ +# +# user@junos01# show interfaces +# ge-0/0/1 { +# unit 0; +# } +# fe-0/0/2 { +# description "Configured by Ansible-2"; +# disable; +# vlan-tagging; +# mtu 2800; +# unit 10 { +# vlan-id 10; +# } +# unit 11 { +# vlan-id 11; +# } +# } +# ge-0/0/3 { +# description "Updated by Ansible-3"; +# } +# fxp0 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# lo0 { +# unit 0 { +# family inet { +# address 192.0.2.1/32; +# } +# } +# } + + +# Using replaced + +# Before state: +# ------------- +# +# user@junos01# show interfaces +# ge-0/0/1 { +# unit 0; +# } +# fe-0/0/2 { +# description "Configured by Ansible-2"; +# disable; +# vlan-tagging; +# mtu 2800; +# unit 10 { +# vlan-id 10; +# } +# unit 11 { +# vlan-id 11; +# } +# } +# ge-0/0/3 { +# description "Updated by Ansible-3"; +# } +# fxp0 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# lo0 { +# unit 0 { +# family inet { +# address 192.0.2.1/32; +# } +# } +# } + +- name: Replace device configuration of listed interfaces with provided configuration + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/2 + description: Configured by Ansible-2 + enabled: false + mtu: 2800 + - name: ge-0/0/3 + description: Configured by Ansible-3 + state: replaced + +# Task Output +# ----------- +# +# before: +# - enabled: true +# name: ge-0/0/1 +# - description: Configured by Ansible-2 +# enabled: false +# mtu: 2800 +# name: fe-0/0/2 +# - description: Updated by Ansible-3 +# enabled: true +# name: ge-0/0/3 +# - enabled: true +# name: fxp0 +# - enabled: true +# name: lo0 +# commands: +# - +# ge-0/0/2 +# +# +# ge-0/0/3 +# +# ge-0/0/2 +# Configured by Ansible-22800 +# ge-0/0/3Configured by Ansible-3 +# after: +# - enabled: true +# name: ge-0/0/1 +# - description: Configured by Ansible-2 +# enabled: false +# mtu: 2800 +# name: fe-0/0/2 +# - description: Configured by Ansible-2 +# enabled: false +# mtu: 2800 +# name: ge-0/0/2 +# - description: Configured by Ansible-3 +# enabled: true +# name: ge-0/0/3 +# - enabled: true +# name: fxp0 +# - enabled: true +# name: lo0 + +# After state: +# ------------ +# +# user@junos01# show interfaces +# ge-0/0/1 { +# unit 0; +# } +# fe-0/0/2 { +# description "Configured by Ansible-2"; +# disable; +# vlan-tagging; +# mtu 2800; +# unit 10 { +# vlan-id 10; +# } +# unit 11 { +# vlan-id 11; +# } +# } +# ge-0/0/2 { +# description "Configured by Ansible-2"; +# disable; +# mtu 2800; +# } +# ge-0/0/3 { +# description "Configured by Ansible-3"; +# } +# fxp0 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# lo0 { +# unit 0 { +# family inet { +# address 192.0.2.1/32; +# } +# } +# } + +# Using gathered + +# Before state: +# ------------ +# +# vagrant@vsrx# show interfaces +# ge-0/0/1 { +# unit 0; +# } +# fe-0/0/2 { +# description "Configured by Ansible-2"; +# disable; +# vlan-tagging; +# mtu 2800; +# unit 10 { +# vlan-id 10; +# } +# unit 11 { +# vlan-id 11; +# } +# } +# ge-0/0/2 { +# description "Configured by Ansible-2"; +# disable; +# mtu 2800; +# } +# ge-0/0/3 { +# description "Configured by Ansible-3"; +# } +# fxp0 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# lo0 { +# unit 0 { +# family inet { +# address 192.0.2.1/32; +# } +# } +# } + +- name: Gather junos interfaces as in given arguments + junipernetworks.junos.junos_interfaces: + state: gathered + +# Task Output +# ----------- +# +# gathered: +# - enabled: true +# name: ge-0/0/1 +# - description: Configured by Ansible-2 +# enabled: false +# mtu: 2800 +# name: fe-0/0/2 +# - description: Configured by Ansible-2 +# enabled: false +# mtu: 2800 +# name: ge-0/0/2 +# - description: Configured by Ansible-3 +# enabled: true +# name: ge-0/0/3 +# - enabled: true +# name: fxp0 +# - enabled: true +# name: lo0 + +# Using parsed + +# parsed.cfg +# ------------ +# +# +# +# +# +# +# ge-0/0/1 +# Configured by Ansible +# +# 100m +# 1024 +# +# 2000 +# 2200 +# +# full-duplex +# +# 0 +# +# +# access +# +# vlan100 +# +# +# +# +# +# +# +# + +# - name: Convert interfaces config to structured data without connecting to the appliance +# junipernetworks.junos.junos_interfaces: +# running_config: "{{ lookup('file', './parsed.cfg') }}" +# state: parsed + +# Task Output +# ----------- +# +# parsed: +# - description: Configured by Ansible +# duplex: full-duplex +# enabled: false +# hold_time: +# down: 2200 +# up: 2000 +# mtu: 1024 +# name: ge-0/0/1 +# speed: 100m + +# Using rendered + +- name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/2 + description: Configured by Ansible + mtu: 2048 + speed: 20m + hold_time: + up: 3200 + down: 3200 + state: rendered + +# Task Output +# ----------- +# +# rendered: +# +# ge-0/0/2 +# Configured by Ansible +# 20m +# 2048 +# +# 3200 +# 3200 +# +# +# " +""" +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. +xml: + description: The set of xml rpc payload pushed to the remote device. + returned: always + type: list + sample: [' + + + + + ge-0/0/1 + Configured by Ansible + + 100m + 1024 + + 2000 + 2200 + + full-duplex + + 0 + + + access + + vlan100 + + + + + + + +', 'xml 2', 'xml 3'] +rendered: + description: The provided configuration in the + task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - +gathered: + description: Facts about the network resource gathered + from the remote device as structured data. + returned: when I(state) is C(gathered) + type: list + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed + into structured data as per module argspec. + returned: when I(state) is C(parsed) + type: list + sample: > + This output will always be in the same format as the + module argspec. +""" + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.interfaces.interfaces import ( + InterfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.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", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_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/ansible_collections/juniper/device/plugins/modules/junos_l2_interfaces.py b/ansible_collections/juniper/device/plugins/modules/junos_l2_interfaces.py new file mode 100644 index 00000000..c4bbd7ab --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_l2_interfaces.py @@ -0,0 +1,1062 @@ +#!/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 junos_l2_interfaces +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_l2_interfaces +short_description: L2 interfaces resource module +description: This module provides declarative management of a Layer-2 interface on + Juniper JUNOS devices. +version_added: 1.0.0 +author: Ganesh Nalawade (@ganeshrn) +options: + config: + description: A dictionary of Layer-2 interface options + type: list + elements: dict + suboptions: + name: + description: + - Full name of interface, e.g. ge-0/0/1. + type: str + required: true + unit: + description: + - Logical interface number. Value of C(unit) should be of type integer. + type: int + access: + description: + - Configure the interface as a Layer 2 access mode. + type: dict + suboptions: + vlan: + description: + - Configure the access VLAN ID. + type: str + trunk: + description: + - Configure the interface as a Layer 2 trunk mode. + type: dict + suboptions: + allowed_vlans: + description: + - List of VLANs to be configured in trunk port. It's used as the VLAN + range to ADD or REMOVE from the trunk. + type: list + elements: str + native_vlan: + description: + - Native VLAN to be configured in trunk port. It is used as the trunk + native VLAN ID. + type: str + enhanced_layer: + description: + - True if your device has Enhanced Layer 2 Software (ELS). If the l2 configuration + is under C(interface-mode) the value is True else if the l2 configuration + is under C(port-mode) value is False + type: bool + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show interfaces). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result. + type: str + state: + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - parsed + - rendered + default: merged + description: + - The state of the configuration after module completion + type: str +requirements: +- ncclient (>=v0.6.4) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 18.4R1. +- This module works with connection C(netconf). + See U(https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html) +- The module examples uses callback plugin (stdout_callback = yaml) to generate task + output in yaml format. +""" + +EXAMPLES = """ +# Using merged + +# Before state: +# ------------- +# +# ansible@junos01# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/3 { +# unit 0 { +# family ethernet-switching { +# interface-mode access; +# } +# } +# } +# ge-0/0/4 { +# unit 0 { +# family ethernet-switching { +# interface-mode access; +# } +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +- name: Merge provided configuration with device configuration + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/3 + access: + vlan: v101 + - name: ge-0/0/4 + trunk: + allowed_vlans: + - vlan30 + native_vlan: 50 + state: merged + +# Task Output +# ----------- +# +# before: +# - enhanced_layer: true +# name: ge-0/0/3 +# unit: 0 +# - enhanced_layer: true +# name: ge-0/0/4 +# unit: 0 +# commands: +# - +# +# ge-0/0/3 +# +# 0 +# +# +# access +# +# v101 +# +# +# +# +# +# +# ge-0/0/4 +# +# 0 +# +# +# trunk +# +# vlan30 +# +# +# +# +# 50 +# +# +# after: +# - access: +# vlan: v101 +# enhanced_layer: true +# name: ge-0/0/3 +# unit: 0 +# - enhanced_layer: true +# name: ge-0/0/4 +# trunk: +# allowed_vlans: +# - vlan30 +# native_vlan: '50' +# unit: 0 + +# After state: +# ------------ +# +# user@junos01# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/3 { +# unit 0 { +# family ethernet-switching { +# interface-mode access; +# vlan { +# members v101; +# } +# } +# } +# } +# ge-0/0/4 { +# native-vlan-id 50; +# unit 0 { +# family ethernet-switching { +# interface-mode trunk; +# vlan { +# members vlan30; +# } +# } +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + + +# Using overridden + +# Before state: +# ------------- +# ansible@junos01# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/3 { +# unit 0 { +# family ethernet-switching { +# interface-mode access; +# vlan { +# members v101; +# } +# } +# } +# } +# ge-0/0/4 { +# native-vlan-id 50; +# unit 0 { +# family ethernet-switching { +# interface-mode trunk; +# vlan { +# members vlan30; +# } +# } +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +- name: Override provided configuration with device configuration + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/4 + trunk: + allowed_vlans: + - v101 + native_vlan: 30 + state: overridden + +# Task Output +# ----------- +# +# before: +# - access: +# vlan: v101 +# enhanced_layer: true +# name: ge-0/0/3 +# unit: 0 +# - enhanced_layer: true +# name: ge-0/0/4 +# trunk: +# allowed_vlans: +# - vlan30 +# native_vlan: '50' +# unit: 0 +# commands: +# - +# +# ge-0/0/4 +# +# 0 +# +# +# +# +# +# +# +# +# +# +# ge-0/0/4 +# +# 0 +# +# +# trunk +# +# v101 +# +# +# +# +# 30 +# +# +# ge-0/0/3 +# +# 0 +# +# +# +# +# +# +# +# +# +# +# after: +# - enhanced_layer: true +# name: ge-0/0/4 +# trunk: +# allowed_vlans: +# - v101 +# native_vlan: '30' +# unit: 0 + +# After state: +# ------------ +# user@junos01# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/3 { +# unit 0 { +# family ethernet-switching; +# } +# } +# ge-0/0/4 { +# native-vlan-id 30; +# unit 0 { +# family ethernet-switching { +# interface-mode trunk; +# vlan { +# members v101; +# } +# } +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +# Using replaced + +# Before state: +# ------------- +# +# ansible@junos01# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/3 { +# unit 0 { +# family ethernet-switching; +# } +# } +# ge-0/0/4 { +# native-vlan-id 30; +# unit 0 { +# family ethernet-switching { +# interface-mode trunk; +# vlan { +# members v101; +# } +# } +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +- name: Replace provided configuration with device configuration + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/3 + access: + vlan: v101 + - name: ge-0/0/4 + trunk: + allowed_vlans: + - vlan30 + native_vlan: 50 + state: replaced + +# Task Output +# ----------- +# +# before: +# - enhanced_layer: true +# name: ge-0/0/4 +# trunk: +# allowed_vlans: +# - v101 +# native_vlan: '30' +# unit: 0 +# commands: +# - +# +# ge-0/0/4 +# +# 0 +# +# +# +# +# +# +# +# +# +# +# ge-0/0/3 +# +# 0 +# +# +# access +# +# v101 +# +# +# +# +# +# +# ge-0/0/4 +# +# 0 +# +# +# trunk +# +# vlan30 +# +# +# +# +# 50 +# +# +# after: +# - access: +# vlan: v101 +# enhanced_layer: true +# name: ge-0/0/3 +# unit: 0 +# - enhanced_layer: true +# name: ge-0/0/4 +# trunk: +# allowed_vlans: +# - vlan30 +# native_vlan: '50' +# unit: 0 + +# After state: +# ------------ +# +# user@junos01# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/3 { +# unit 0 { +# family ethernet-switching { +# interface-mode access; +# vlan { +# members v101; +# } +# } +# } +# } +# ge-0/0/4 { +# native-vlan-id 50; +# unit 0 { +# family ethernet-switching { +# interface-mode trunk; +# vlan { +# members vlan30; +# } +# } +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +# Using deleted + +# Before state: +# ------------- +# +# ansible@junos01# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/3 { +# unit 0 { +# family ethernet-switching { +# interface-mode access; +# vlan { +# members v101; +# } +# } +# } +# } +# ge-0/0/4 { +# native-vlan-id 50; +# unit 0 { +# family ethernet-switching { +# interface-mode trunk; +# vlan { +# members vlan30; +# } +# } +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +- name: "Delete L2 attributes of given interfaces (Note: This won't delete the + interface itself)." + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + state: deleted + +# Task Output +# ----------- +# +# before: +# - access: +# vlan: v101 +# enhanced_layer: true +# name: ge-0/0/3 +# unit: 0 +# - enhanced_layer: true +# name: ge-0/0/4 +# trunk: +# allowed_vlans: +# - vlan30 +# native_vlan: '50' +# unit: 0 +# commands: +# - +# +# ge-0/0/3 +# +# 0 +# +# +# +# +# +# +# +# +# +# +# after: +# - enhanced_layer: true +# name: ge-0/0/4 +# trunk: +# allowed_vlans: +# - vlan30 +# native_vlan: '50' +# unit: 0 + +# After state: +# ------------ +# +# ansible@junos01# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/3 { +# unit 0 { +# family ethernet-switching; +# } +# } +# ge-0/0/4 { +# native-vlan-id 50; +# unit 0 { +# family ethernet-switching { +# interface-mode trunk; +# vlan { +# members vlan30; +# } +# } +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +# Using gathered + +# Before state: +# ------------- +# +# user@junos01# show interfaces +# ge-0/0/1 { +# description "Configured by Ansible"; +# disable; +# speed 100m; +# mtu 1024; +# hold-time up 2000 down 2200; +# link-mode full-duplex; +# unit 0 { +# family ethernet-switching { +# interface-mode access; +# vlan { +# members vlan100; +# } +# } +# } +# } +# ge-0/0/2 { +# description "Configured by Ansible"; +# native-vlan-id 400; +# speed 10m; +# mtu 2048; +# hold-time up 3000 down 3200; +# unit 0 { +# family ethernet-switching { +# interface-mode trunk; +# vlan { +# members [ vlan200 vlan300 ]; +# } +# } +# } +# } +# em1 { +# description TEST; +# } +# fxp0 { +# description ANSIBLE; +# speed 1g; +# link-mode automatic; +# unit 0 { +# family inet { +# address 10.8.38.38/24; +# } +# } +# } + +- name: Gather junos layer 2 interfaces facts + junipernetworks.junos.junos_l2_interfaces: + state: gathered + +# Task Output +# ----------- +# +# gathered: +# - access: +# vlan: vlan100 +# enhanced_layer: true +# name: ge-0/0/1 +# unit: 0 +# - enhanced_layer: true +# name: ge-0/0/2 +# trunk: +# allowed_vlans: +# - vlan200 +# - vlan300 +# native_vlan: '400' +# unit: 0 + +# Using parsed + +# parsed.cfg +# ------------ +# +# +# +# +# +# +# ge-0/0/1 +# Configured by Ansible +# +# 100m +# 1024 +# +# 2000 +# 2200 +# +# full-duplex +# +# 0 +# +# +# access +# +# vlan100 +# +# +# +# +# +# +# +# + +- name: Convert interfaces config to argspec without connecting to the appliance + junipernetworks.junos.junos_l2_interfaces: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + +# Task Output +# ----------- +# +# parsed: +# - access: +# vlan: vlan100 +# enhanced_layer: true +# name: ge-0/0/1 +# unit: 0 +# - enhanced_layer: true +# name: ge-0/0/2 +# trunk: +# allowed_vlans: +# - vlan200 +# - vlan300 +# native_vlan: '400' +# unit: 0 + +# Using rendered + +- name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/1 + access: + vlan: vlan100 + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan200 + - vlan300 + native_vlan: '400' + state: rendered + +# Task Output +# ----------- +# +# "rendered": " +# +# ge-0/0/1 +# +# 0 +# +# +# access +# +# vlan100 +# +# +# +# +# +# +# ge-0/0/2 +# +# 0 +# +# +# trunk +# +# vlan200 +# vlan300 +# +# +# +# +# 400 +# +# " +""" + +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: [' + + ge-0/0/1 + + 0 + + + access + + vlan100 + + + + + + + ge-0/0/2 + + 0 + + + trunk + + vlan200 + vlan300 + + + + + 400 + +', 'xml 2', 'xml 3'] +rendered: + description: The provided configuration in the + task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - +gathered: + description: Facts about the network resource gathered + from the remote device as structured data. + returned: when I(state) is C(gathered) + type: list + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed + into structured data as per module argspec. + returned: when I(state) is C(parsed) + type: list + sample: > + This output will always be in the same format as the + module argspec. +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.l2_interfaces.l2_interfaces import ( + L2_interfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.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", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_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/ansible_collections/juniper/device/plugins/modules/junos_l3_interfaces.py b/ansible_collections/juniper/device/plugins/modules/junos_l3_interfaces.py new file mode 100644 index 00000000..9d5b7688 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_l3_interfaces.py @@ -0,0 +1,1026 @@ +#!/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 junos_l3_interfaces +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_l3_interfaces +short_description: L3 interfaces resource module +description: This module provides declarative management of a Layer 3 interface on + Juniper JUNOS devices +version_added: 1.0.0 +author: Daniel Mellado (@dmellado) +requirements: +- ncclient (>=v0.6.4) +notes: +- This module requires the netconf system service be enabled on the device being managed. +- Tested against JunOS v18.4R1 +- This module works with connection C(netconf). + See U(https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html) +- The module examples uses callback plugin (stdout_callback = yaml) to generate task + output in yaml format. +options: + config: + description: A dictionary of Layer 3 interface options + type: list + elements: dict + suboptions: + name: + description: + - Full name of interface, e.g. ge-0/0/1 + type: str + required: true + unit: + description: + - Logical interface number. Value of C(unit) should be of type integer + default: 0 + type: int + mtu: + description: + - Protocol family maximum transmission unit. + type: int + ipv4: + description: + - IPv4 addresses to be set for the Layer 3 logical interface mentioned in + I(name) option. The address format is /. The mask is + number in range 0-32 for example, 192.0.2.1/24, or C(dhcp) to query DHCP + for an IP address + type: list + elements: dict + suboptions: + address: + description: + - IPv4 address to be set for the specific interface + type: str + ipv6: + description: + - IPv6 addresses to be set for the Layer 3 logical interface mentioned in + I(name) option. The address format is /, the mask is + number in range 0-128 for example, 2001:db8:2201:1::1/64 or C(auto-config) + to use SLAAC + type: list + elements: dict + suboptions: + address: + description: + - IPv6 address to be set for the specific interface + type: str + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show interfaces). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + description: + - The state of the configuration after module completion + type: str + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - rendered + - parsed + default: merged +""" +EXAMPLES = """ +# Using merged + +# Before state +# ------------ +# +# admin# show interfaces +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } + +- name: Merge provided configuration with device configuration + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-0/0/1 + ipv4: + - address: 192.168.1.10/24 + ipv6: + - address: 8d8d:8d01::1/64 + - name: ge-0/0/2 + ipv4: + - address: dhcp + state: merged + +# Task Output +# ----------- +# +# before: +# - ipv4: +# - address: dhcp +# name: fxp0 +# unit: '0' +# commands: +# - +# +# ge-0/0/1 +# +# 0 +# +# +# +# 192.168.1.10/24 +# +# +# +# +# +# +# 8d8d:8d01::1/64 +# +# +# +# +# +# +# ge-0/0/2 +# +# 0 +# +# +# +# +# +# +# +# +# after: +# - ipv4: +# - address: 192.168.1.10/24 +# ipv6: +# - address: 8d8d:8d01::1/64 +# name: ge-0/0/1 +# unit: '0' +# - ipv4: +# - address: dhcp +# name: ge-0/0/2 +# unit: '0' +# - ipv4: +# - address: dhcp +# name: fxp0 +# unit: '0' + +# After state: +# ------------ +# +# admin# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet { +# address 192.168.1.10/24; +# } +# family inet6 { +# address 8d8d:8d01::1/64; +# } +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } + +# Using overridden + +# Before state +# ------------ +# +# admin# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet { +# address 192.168.1.10/24; +# } +# family inet6 { +# address 8d8d:8d01::1/64; +# } +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } + +- name: Override provided configuration with device configuration + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-0/0/1 + ipv4: + - address: 192.168.1.10/24 + - ipv4: + - address: dhcp + name: fxp0 + unit: '0' + state: overridden + +# Task Output +# ----------- +# +# before: +# - ipv4: +# - address: 192.168.1.10/24 +# ipv6: +# - address: 8d8d:8d01::1/64 +# name: ge-0/0/1 +# unit: '0' +# - ipv4: +# - address: dhcp +# name: ge-0/0/2 +# unit: '0' +# - ipv4: +# - address: dhcp +# name: fxp0 +# unit: '0' +# commands: +# - +# +# ge-0/0/1 +# +# 0 +# +# +# +# +# +# +# +# +# +# +# +# ge-0/0/2 +# +# 0 +# +# +# +# +# +# +# +# +# +# +# +# fxp0 +# +# 0 +# +# +# +# +# +# +# +# +# +# +# +# ge-0/0/1 +# +# 0 +# +# +# +# 192.168.1.10/24 +# +# +# +# +# +# +# fxp0 +# +# 0 +# +# +# +# +# +# +# +# +# after: +# - ipv4: +# - address: 192.168.1.10/24 +# name: ge-0/0/1 +# unit: '0' +# - name: ge-0/0/2 +# unit: '0' +# - ipv4: +# - address: dhcp +# name: fxp0 +# unit: '0' + +# After state: +# ------------ +# +# admin# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet { +# address 192.168.1.10/24; +# } +# family inet6; +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +# Using replaced + +# Before state +# ------------ +# +# admin# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet { +# address 192.168.1.10/24; +# } +# family inet6; +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +- name: Replace provided configuration with device configuration + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-0/0/1 + ipv4: + - address: 192.168.1.10/24 + ipv6: + - address: 8d8d:8d01::1/64 + - name: ge-0/0/2 + ipv4: + - address: dhcp + state: replaced + +# Task Output +# ----------- +# +# before: +# - ipv4: +# - address: 192.168.1.10/24 +# name: ge-0/0/1 +# unit: '0' +# - name: ge-0/0/2 +# unit: '0' +# - ipv4: +# - address: dhcp +# name: fxp0 +# unit: '0' +# commands: +# - +# +# ge-0/0/1 +# +# 0 +# +# +# +# +# +# +# +# +# +# +# +# ge-0/0/2 +# +# 0 +# +# +# +# +# +# +# +# +# +# ge-0/0/1 +# +# 0 +# +# +# +# 192.168.1.10/24 +# +# +# +# +# +# +# 8d8d:8d01::1/64 +# +# +# +# +# +# +# ge-0/0/2 +# +# 0 +# +# +# +# +# +# +# +# +# after: +# - ipv4: +# - address: 192.168.1.10/24 +# ipv6: +# - address: 8d8d:8d01::1/64 +# name: ge-0/0/1 +# unit: '0' +# - ipv4: +# - address: dhcp +# name: ge-0/0/2 +# unit: '0' +# - ipv4: +# - address: dhcp +# name: fxp0 +# unit: '0' + +# After state: +# ------------ +# +# admin# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet { +# address 192.168.1.10/24; +# } +# family inet6 { +# address 8d8d:8d01::1/64; +# } +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +# Using deleted + +# Before state: +# ------------- +# +# admin# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet { +# address 192.168.1.10/24; +# } +# family inet6 { +# address 8d8d:8d01::1/64; +# } +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +- name: Delete L3 logical interface + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + state: deleted + +# Task Output +# ----------- +# +# before: +# - ipv4: +# - address: 192.168.1.10/24 +# ipv6: +# - address: 8d8d:8d01::1/64 +# name: ge-0/0/1 +# unit: '0' +# - ipv4: +# - address: dhcp +# name: ge-0/0/2 +# unit: '0' +# - ipv4: +# - address: dhcp +# name: fxp0 +# unit: '0' +# commands: +# - +# +# ge-0/0/1 +# +# 0 +# +# +# +# +# +# +# +# +# +# +# +# ge-0/0/2 +# +# 0 +# +# +# +# +# +# +# +# +# +# +# +# after: +# - name: ge-0/0/1 +# unit: '0' +# - name: ge-0/0/2 +# unit: '0' +# - ipv4: +# - address: dhcp +# name: fxp0 +# unit: '0' + +# After state: +# ------------ +# +# admin# show interfaces +# ge-0/0/1 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet; +# family inet6; +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +# Using gathered + +# Before state: +# ------------ +# +# user@junos01# show interfaces +# ge-0/0/1 { +# description "Configured by Ansible"; +# disable; +# speed 100m; +# mtu 1024; +# hold-time up 2000 down 2200; +# link-mode full-duplex; +# unit 0 { +# family ethernet-switching { +# interface-mode access; +# vlan { +# members vlan100; +# } +# } +# } +# } +# ge-0/0/2 { +# description "Configured by Ansible"; +# native-vlan-id 400; +# speed 10m; +# mtu 2048; +# hold-time up 3000 down 3200; +# unit 0 { +# family ethernet-switching { +# interface-mode trunk; +# vlan { +# members [ vlan200 vlan300 ]; +# } +# } +# } +# } +# ge-1/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.1/24; +# address 10.200.16.20/24; +# } +# family inet6; +# } +# } +# ge-2/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.2/24; +# address 10.200.16.21/24; +# } +# family inet6; +# } +# } +# ge-3/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.3/24; +# address 10.200.16.22/24; +# } +# family inet6; +# } +# } +# em1 { +# description TEST; +# } +# fxp0 { +# description ANSIBLE; +# speed 1g; +# link-mode automatic; +# unit 0 { +# family inet { +# address 10.8.38.38/24; +# } +# } +# } + +- name: Gather layer3 interfaces facts + junipernetworks.junos.junos_l3_interfaces: + state: gathered + +# Task Output +# ----------- +# +# gathered: +# - ipv4: +# - address: 192.168.100.1/24 +# - address: 10.200.16.20/24 +# name: ge-1/0/0 +# unit: '0' +# - ipv4: +# - address: 192.168.100.2/24 +# - address: 10.200.16.21/24 +# name: ge-2/0/0 +# unit: '0' +# - ipv4: +# - address: 192.168.100.3/24 +# - address: 10.200.16.22/24 +# name: ge-3/0/0 +# unit: '0' +# - ipv4: +# - address: 10.8.38.38/24 +# name: fxp0 +# unit: '0' + +# Using parsed + +# parsed.cfg +# ------------ +# +# +# +# +# +# +# ge-1/0/0 +# +# 0 +# +# +#
+# 192.168.100.1/24 +#
+#
+# 10.200.16.20/24 +#
+#
+# +#
+#
+#
+# +# ge-2/0/0 +# +# 0 +# +# +#
+# 192.168.100.2/24 +#
+#
+# 10.200.16.21/24 +#
+#
+# +#
+#
+#
+#
+#
+#
+ +# - name: Convert interfaces config to argspec without connecting to the appliance +# junipernetworks.junos.junos_l3_interfaces: +# running_config: "{{ lookup('file', './parsed.cfg') }}" +# state: parsed + +# Task Output +# ----------- +# +# parsed: +# - ipv4: +# - address: 192.168.100.1/24 +# - address: 10.200.16.20/24 +# name: ge-1/0/0 +# unit: '0' +# - ipv4: +# - address: 192.168.100.2/24 +# - address: 10.200.16.21/24 +# name: ge-2/0/0 +# unit: '0' + +# Using rendered + +- name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-1/0/0 + ipv4: + - address: 192.168.100.1/24 + - address: 10.200.16.20/24 + unit: 0 + - name: ge-2/0/0 + ipv4: + - address: 192.168.100.2/24 + - address: 10.200.16.21/24 + unit: 0 + state: rendered + +# Task Output +# ----------- +# +# "rendered": " +# +# ge-1/0/0 +# +# 0 +# +# +# +# 192.168.100.1/24 +# +# +# 10.200.16.20/24 +# +# +# +# +# +# +# ge-2/0/0 +# +# 0 +# +# +# +# 192.168.100.2/24 +# +# +# 10.200.16.21/24 +# +# +# +# +# +# " +""" + +RETURN = """ +before: + description: The configuration as structured data prior to module invocation. + returned: always + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: list +after: + description: The configuration as structured data after module completion. + returned: when changed + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: list +commands: + description: The set of commands pushed to the remote device. + returned: always + type: list + sample: [' + + ge-1/0/0 + + 0 + + + + 192.168.100.1/24 + + + 10.200.16.20/24 + + + + +', 'xml 2', 'xml 3'] +rendered: + description: The provided configuration in the + task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - +gathered: + description: Facts about the network resource gathered + from the remote device as structured data. + returned: when I(state) is C(gathered) + type: list + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed + into structured data as per module argspec. + returned: when I(state) is C(parsed) + type: list + sample: > + This output will always be in the same format as the + module argspec. +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.l3_interfaces.l3_interfaces import ( + L3_interfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.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", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_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/ansible_collections/juniper/device/plugins/modules/junos_lacp.py b/ansible_collections/juniper/device/plugins/modules/junos_lacp.py new file mode 100644 index 00000000..40363d80 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_lacp.py @@ -0,0 +1,304 @@ +#!/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 junos_lacp +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_lacp +short_description: Global Link Aggregation Control Protocol (LACP) Junos resource + module +description: This module provides declarative management of global LACP on Juniper + Junos network devices. +version_added: 1.0.0 +author: Ganesh Nalawade (@ganeshrn) +options: + config: + description: A dictionary of LACP global options + type: dict + suboptions: + system_priority: + description: + - LACP priority for the system. + type: int + link_protection: + description: + - Enable LACP link-protection for the system. If the value is set to C(non-revertive) + it will not revert links when a better priority link comes up. By default + the link will be reverted. + type: str + choices: + - revertive + - non-revertive + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show chassis aggregated-devices ethernet lacp). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + description: + - The state of the configuration after module completion + type: str + choices: + - merged + - replaced + - deleted + - gathered + - rendered + - parsed + default: merged +requirements: +- ncclient (>=v0.6.4) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 18.1R1. +- This module works with connection C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +""" +EXAMPLES = """ +# Using deleted + +# Before state: +# ------------- +# user@junos01# show chassis aggregated-devices ethernet lacp +# system-priority 63; +# link-protection { +# non-revertive; +# } + +- name: Delete global LACP attributes + junipernetworks.junos.junos_lacp: + state: deleted + +# After state: +# ------------ +# user@junos01# show chassis aggregated-devices ethernet lacp +# + + +# Using merged + +# Before state: +# ------------- +# user@junos01# show chassis aggregated-devices ethernet lacp +# + +- name: Merge global LACP attributes + junipernetworks.junos.junos_lacp: + config: + system_priority: 63 + link_protection: revertive + state: merged + +# After state: +# ------------ +# user@junos01# show chassis aggregated-devices ethernet lacp +# system-priority 63; +# link-protection { +# non-revertive; +# } + + +# Using replaced + +# Before state: +# ------------- +# user@junos01# show chassis aggregated-devices ethernet lacp +# system-priority 63; +# link-protection { +# non-revertive; +# } + +- name: Replace global LACP attributes + junipernetworks.junos.junos_lacp: + config: + system_priority: 30 + link_protection: non-revertive + state: replaced + +# After state: +# ------------ +# user@junos01# show chassis aggregated-devices ethernet lacp +# system-priority 30; +# link-protection; +# +# Using gathered +# Before state: +# ------------ +# +# ansible@cm123456tr21# show chassis aggregated-devices ethernet lacp +# system-priority 63; +# link-protection; + +- name: Gather junos lacp as in given arguments + junipernetworks.junos.junos_lacp: + state: gathered +# Task Output (redacted) +# ----------------------- +# +# "gathered": { +# "link_protection": "revertive", +# "system_priority": 63 +# } +# After state: +# ------------ +# +# ansible@cm123456tr21# show chassis aggregated-devices ethernet lacp +# system-priority 63; +# link-protection; +# Using rendered +- name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_lacp: + config: + system_priority: 63 + link_protection: revertive + state: rendered +# Task Output (redacted) +# ----------------------- +# "rendered": " +# +# +# +# 63 +# +# +# +# +# +# +# +# +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# +# +# +# +# +# 63 +# +# +# +# +# +# +# +# +# - name: Convert lacp config to argspec without connecting to the appliance +# junipernetworks.junos.junos_lacp: +# running_config: "{{ lookup('file', './parsed.cfg') }}" +# state: parsed +# Task Output (redacted) +# ----------------------- +# "parsed": { +# "link_protection": "revertive", +# "system_priority": 63 +# } +""" +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. +xml: + description: The set of xml rpc payload pushed to the remote device. + returned: always + type: list + sample: [' + + + + 63 + + + + + + +', 'xml 2', 'xml 3'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.lacp.lacp import ( + LacpArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.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",)), + ("state", "rendered", ("config",)), + ("state", "parsed", ("running_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/ansible_collections/juniper/device/plugins/modules/junos_lacp_interfaces.py b/ansible_collections/juniper/device/plugins/modules/junos_lacp_interfaces.py new file mode 100644 index 00000000..0e2797c6 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_lacp_interfaces.py @@ -0,0 +1,966 @@ +#!/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 junos_lacp_interfaces +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_lacp_interfaces +short_description: LACP interfaces resource module +description: +- This module manages Link Aggregation Control Protocol (LACP) attributes of interfaces + on Juniper JUNOS devices. +version_added: 1.0.0 +author: Ganesh Nalawade (@ganeshrn) +options: + config: + description: The list of dictionaries of LACP interfaces options. + type: list + elements: dict + suboptions: + name: + description: + - Name Identifier of the interface or link aggregation group. + type: str + period: + description: + - Timer interval for periodic transmission of LACP packets. If the value is + set to C(fast) the packets are received every second and if the value is + C(slow) the packets are received every 30 seconds. This value is applicable + for aggregate interface only. + type: str + choices: + - fast + - slow + sync_reset: + description: + - The argument notifies minimum-link failure out of sync to peer. If the value + is C(disable) it disables minimum-link failure handling at LACP level and + if value is C(enable) it enables minimum-link failure handling at LACP level. + This value is applicable for aggregate interface only. + type: str + choices: + - disable + - enable + force_up: + description: + - This is a boolean argument to control if the port should be up in absence + of received link Aggregation Control Protocol Data Unit (LACPDUS). This + value is applicable for member interfaces only. + type: bool + port_priority: + description: + - Priority of the member port. This value is applicable for member interfaces + only. + - Refer to vendor documentation for valid values. + type: int + system: + description: + - This dict object contains configurable options related to LACP system parameters + for the link aggregation group. This value is applicable for aggregate interface + only. + type: dict + suboptions: + priority: + description: + - Specifies the system priority to use in LACP negotiations for the bundle. + - Refer to vendor documentation for valid values. + type: int + mac: + description: + - Specifies the system ID to use in LACP negotiations for the bundle, + encoded as a MAC address. + type: dict + suboptions: + address: + description: + - The system ID to use in LACP negotiations. + type: str + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show interface). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result. + type: str + state: + description: + - The state of the configuration after module completion. + type: str + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - parsed + - rendered + default: merged +""" +EXAMPLES = """ +# Using merged +# Before state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/2 { +# ether-options { +# 802.3ad ae4; +# } +# } +# ge-0/0/3 { +# ether-options { +# 802.3ad ae0; +# } +# } +# ae0 { +# description "lag interface merged"; +# aggregated-ether-options { +# lacp { +# passive; +# } +# } +# } +# ae4 { +# description "test aggregate interface"; +# aggregated-ether-options { +# lacp { +# passive; +# link-protection; +# } +# } +# } + +- name: Merge provided configuration with device configuration + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + - name: ge-0/0/3 + port_priority: 100 + force_up: true + state: merged + +# After state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/2 { +# ether-options { +# 802.3ad ae4; +# } +# } +# ge-0/0/3 { +# ether-options { +# 802.3ad { +# lacp { +# force-up; +# port-priority 100; +# } +# ae0; +# } +# } +# } +# ae0 { +# description "lag interface merged"; +# aggregated-ether-options { +# lacp { +# passive; +# periodic fast; +# sync-reset enable; +# system-priority 100; +# system-id 00:00:00:00:00:02; +# } +# } +# } +# ae4 { +# description "test aggregate interface"; +# aggregated-ether-options { +# lacp { +# passive; +# link-protection; +# } +# } +# } + +# Using replaced +# Before state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/2 { +# ether-options { +# 802.3ad ae4; +# } +# } +# ge-0/0/3 { +# ether-options { +# 802.3ad { +# lacp { +# force-up; +# port-priority 100; +# } +# ae0; +# } +# } +# } +# ae0 { +# description "lag interface merged"; +# aggregated-ether-options { +# lacp { +# passive; +# periodic fast; +# sync-reset enable; +# system-priority 100; +# system-id 00:00:00:00:00:02; +# } +# } +# } +# ae4 { +# description "test aggregate interface"; +# aggregated-ether-options { +# lacp { +# passive; +# link-protection; +# } +# } +# } + +- name: Replace device LACP interfaces configuration with provided configuration + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + period: slow + state: replaced + +# After state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/2 { +# ether-options { +# 802.3ad ae4; +# } +# } +# ge-0/0/3 { +# ether-options { +# 802.3ad { +# lacp { +# force-up; +# port-priority 100; +# } +# ae0; +# } +# } +# } +# ae0 { +# description "lag interface merged"; +# aggregated-ether-options { +# lacp { +# passive; +# periodic slow; +# } +# } +# } +# ae4 { +# description "test aggregate interface"; +# aggregated-ether-options { +# lacp { +# passive; +# link-protection; +# } +# } +# } + +# Using overridden +# Before state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/2 { +# ether-options { +# 802.3ad ae4; +# } +# } +# ge-0/0/3 { +# ether-options { +# 802.3ad { +# lacp { +# force-up; +# port-priority 100; +# } +# ae0; +# } +# } +# } +# ae0 { +# description "lag interface merged"; +# aggregated-ether-options { +# lacp { +# passive; +# periodic slow; +# } +# } +# } +# ae4 { +# description "test aggregate interface"; +# aggregated-ether-options { +# lacp { +# passive; +# link-protection; +# } +# } +# } + +- name: Overrides all device LACP interfaces configuration with provided configuration + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + system: + priority: 300 + mac: + address: 00:00:00:00:00:03 + - name: ge-0/0/2 + port_priority: 200 + force_up: false + state: overridden + +# After state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/2 { +# ether-options { +# 802.3ad { +# lacp { +# port-priority 200; +# } +# ae4; +# } +# } +# } +# ge-0/0/3 { +# ether-options { +# 802.3ad { +# lacp { +# force-up; +# port-priority 100; +# } +# ae0; +# } +# } +# } +# ae0 { +# description "lag interface merged"; +# aggregated-ether-options { +# lacp { +# passive; +# system-priority 300; +# system-id 00:00:00:00:00:03; +# } +# } +# } +# ae4 { +# description "test aggregate interface"; +# aggregated-ether-options { +# lacp { +# passive; +# link-protection; +# } +# } +# } + +# Using deleted +# Before state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/2 { +# ether-options { +# 802.3ad { +# lacp { +# port-priority 200; +# } +# ae4; +# } +# } +# } +# ge-0/0/3 { +# ether-options { +# 802.3ad { +# lacp { +# force-up; +# port-priority 100; +# } +# ae0; +# } +# } +# } +# ae0 { +# description "lag interface merged"; +# aggregated-ether-options { +# lacp { +# passive; +# system-priority 300; +# system-id 00:00:00:00:00:03; +# } +# } +# } +# ae4 { +# description "test aggregate interface"; +# aggregated-ether-options { +# lacp { +# passive; +# link-protection; +# } +# } +# } + +- name: "Delete LACP interfaces attributes of given interfaces (Note: This won't delete the interface itself)" + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + - name: ge-0/0/3 + - name: ge-0/0/2 + state: deleted + +# After state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/2 { +# ether-options { +# 802.3ad ae4; +# } +# } +# ge-0/0/3 { +# ether-options { +# 802.3ad ae0; +# } +# } +# ae0 { +# description "lag interface merged"; +# aggregated-ether-options { +# lacp { +# passive; +# } +# } +# } +# ae4 { +# description "test aggregate interface"; +# aggregated-ether-options { +# lacp { +# passive; +# link-protection; +# } +# } +# } +# Using gathered +# Before state: +# ------------ +# +# user@junos01# show interfaces +# ansible@cm123456tr21# show interfaces +# ge-0/0/1 { +# ether-options { +# 802.3ad { +# lacp { +# force-up; +# port-priority 100; +# } +# ae1; +# } +# } +# } +# ge-0/0/2 { +# ether-options { +# 802.3ad ae1; +# } +# } +# ge-0/0/3 { +# ether-options { +# 802.3ad ae2; +# } +# } +# ge-0/0/4 { +# ether-options { +# 802.3ad ae2; +# } +# } +# ge-1/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.1/24; +# address 10.200.16.20/24; +# } +# family inet6; +# } +# } +# ge-2/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.2/24; +# address 10.200.16.21/24; +# } +# family inet6; +# } +# } +# ge-3/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.3/24; +# address 10.200.16.22/24; +# } +# family inet6; +# } +# } +# ae1 { +# description "Configured by Ansible"; +# aggregated-ether-options { +# lacp { +# periodic fast; +# sync-reset enable; +# system-priority 100; +# system-id 00:00:00:00:00:02; +# } +# } +# } +# ae2 { +# description "Configured by Ansible"; +# } +# em1 { +# description TEST; +# } +# fxp0 { +# description ANSIBLE; +# speed 1g; +# link-mode automatic; +# unit 0 { +# family inet { +# address 10.8.38.38/24; +# } +# } +# } +- name: Gather junos lacp interfaces as in given arguments + junipernetworks.junos.junos_lacp_interfaces: + state: gathered +# Task Output (redacted) +# ----------------------- +# +# "gathered": [ +# { +# "force_up": true, +# "name": "ge-0/0/1", +# "port_priority": 100 +# }, +# { +# "name": "ae1", +# "period": "fast", +# "sync_reset": "enable", +# "system": { +# "mac": { +# "address": "00:00:00:00:00:02" +# }, +# "priority": 100 +# } +# } +# ] +# After state: +# ------------ +# +# ansible@cm123456tr21# show interfaces +# ge-0/0/1 { +# ether-options { +# 802.3ad { +# lacp { +# force-up; +# port-priority 100; +# } +# ae1; +# } +# } +# } +# ge-0/0/2 { +# ether-options { +# 802.3ad ae1; +# } +# } +# ge-0/0/3 { +# ether-options { +# 802.3ad ae2; +# } +# } +# ge-0/0/4 { +# ether-options { +# 802.3ad ae2; +# } +# } +# ge-1/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.1/24; +# address 10.200.16.20/24; +# } +# family inet6; +# } +# } +# ge-2/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.2/24; +# address 10.200.16.21/24; +# } +# family inet6; +# } +# } +# ge-3/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.3/24; +# address 10.200.16.22/24; +# } +# family inet6; +# } +# } +# ae1 { +# description "Configured by Ansible"; +# aggregated-ether-options { +# lacp { +# periodic fast; +# sync-reset enable; +# system-priority 100; +# system-id 00:00:00:00:00:02; +# } +# } +# } +# ae2 { +# description "Configured by Ansible"; +# } +# em1 { +# description TEST; +# } +# fxp0 { +# description ANSIBLE; +# speed 1g; +# link-mode automatic; +# unit 0 { +# family inet { +# address 10.8.38.38/24; +# } +# } +# } +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# +# +# +# ge-0/0/1 +# +# +# +# +# 100 +# +# ae1 +# +# +# +# +# ge-0/0/2 +# +# +# ae1 +# +# +# +# +# ge-0/0/3 +# +# +# ae2 +# +# +# +# +# ge-0/0/4 +# +# +# ae2 +# +# +# +# +# ge-1/0/0 +# +# 0 +# +# +#
+# 192.168.100.1/24 +#
+#
+# 10.200.16.20/24 +#
+#
+# +# +#
+#
+#
+# +# ge-2/0/0 +# +# 0 +# +# +#
+# 192.168.100.2/24 +#
+#
+# 10.200.16.21/24 +#
+#
+# +# +#
+#
+#
+# +# ge-3/0/0 +# +# 0 +# +# +#
+# 192.168.100.3/24 +#
+#
+# 10.200.16.22/24 +#
+#
+# +# +#
+#
+#
+# +# ae1 +# Configured by Ansible +# +# +# fast +# enable +# 100 +# 00:00:00:00:00:02 +# +# +# +# +# ae2 +# Configured by Ansible +# +# +# em1 +# TEST +# +# +# fxp0 +# ANSIBLE +# 1g +# automatic +# +# 0 +# +# +#
+# 10.8.38.38/24 +#
+#
+#
+#
+#
+#
+#
+#
+# - name: Convert interfaces config to argspec without connecting to the appliance +# junipernetworks.junos.junos_lacp_interfaces: +# running_config: "{{ lookup('file', './parsed.cfg') }}" +# state: parsed +# Task Output (redacted) +# ----------------------- +# "parsed": [ +# { +# "force_up": true, +# "name": "ge-0/0/1", +# "port_priority": 100 +# }, +# { +# "name": "ae1", +# "period": "fast", +# "sync_reset": "enable", +# "system": { +# "mac": { +# "address": "00:00:00:00:00:02" +# }, +# "priority": 100 +# } +# } +# ] +# Using rendered +- name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + + - name: ge-0/0/1 + port_priority: 100 + force_up: true + state: rendered +# Task Output (redacted) +# ----------------------- +# "rendered": " +# +# ae1 +# +# +# fast +# enable +# 00:00:00:00:00:02 +# 100 +# +# +# +# +# ge-0/0/1 +# +# +# +# 100 +# +# +# +# +# +# " +""" + +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: [' + + ae1 + + + fast + enable + 00:00:00:00:00:02 + 100 + + + + + ge-0/0/1 + + + + 100 + + + + + +', 'xml 2', 'xml 3'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.lacp_interfaces.lacp_interfaces import ( + Lacp_interfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.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", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_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/ansible_collections/juniper/device/plugins/modules/junos_lag_interfaces.py b/ansible_collections/juniper/device/plugins/modules/junos_lag_interfaces.py new file mode 100644 index 00000000..dfef2da7 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_lag_interfaces.py @@ -0,0 +1,893 @@ +#!/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 junos_lag_interfaces +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_lag_interfaces +short_description: Link Aggregation Juniper JUNOS resource module +description: This module manages properties of Link Aggregation Group on Juniper JUNOS + devices. +version_added: 1.0.0 +author: Ganesh Nalawade (@ganeshrn) +options: + config: + description: A list of link aggregation group configurations. + type: list + elements: dict + suboptions: + name: + description: + - Name of the link aggregation group (LAG). + type: str + required: true + mode: + description: + - LAG mode. A value of C(passive) will enable LACP in C(passive) mode that + is it will respond to LACP packets and C(active) configures the link to + initiate transmission of LACP packets. + type: str + choices: + - active + - passive + link_protection: + description: + - This boolean option indicates if link protection should be enabled for the + LAG interface. If value is C(True) link protection is enabled on LAG and + if value is C(False) link protection is disabled. + type: bool + members: + description: + - List of member interfaces of the link aggregation group. The value can be + single interface or list of interfaces. + type: list + elements: dict + suboptions: + member: + description: + - Name of the member interface. + type: str + link_type: + description: + - The value of this options configures the member link as either C(primary) + or C(backup). Value C(primary) configures primary interface for link-protection + mode and C(backup) configures backup interface for link-protection mode. + type: str + choices: + - primary + - backup + ether_option_type: + description: Specify the type of ethernet interface. + choices: + - ether + - gigether + default: ether + type: str + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show interfaces). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + description: + - The state of the configuration after module completion + type: str + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - rendered + - parsed + default: merged +requirements: +- ncclient (>=v0.6.4) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 18.4R1. +- This module works with connection C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +""" +EXAMPLES = """ +# Using merged + +# Before state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/1 { +# description "Ansible configured interface 1"; +# ether-options { +# 802.3ad ae0; +# } +# } +# ge-0/0/2 { +# description "Ansible configured interface 2"; +# ether-options { +# 802.3ad ae0; +# } +# } +# ae0 { +# description "lag interface"; +# } +# ae1 { +# description "lag interface 1"; +# } + +- name: "Delete LAG attributes of given interfaces (Note: This won't delete the interface itself)" + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae0 + - name: ae1 + state: deleted + +# After state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/1 { +# description "Ansible configured interface 1"; +# } +# ge-0/0/2 { +# description "Ansible configured interface 2"; +# } + + +# Using merged + +# Before state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/1 { +# description "Ansible configured interface 1"; +# } +# ge-0/0/2 { +# description "Ansible configured interface 2"; +# } + +- name: Merge provided configuration with device configuration + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae0 + members: + - member: ge-0/0/1 + link_type: primary + - member: ge-0/0/2 + link_type: backup + state: merged + +# After state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/1 { +# description "Ansible configured interface 1"; +# ether-options { +# 802.3ad { +# ae0; +# primary; +# } +# } +# } +# ge-0/0/2 { +# description "Ansible configured interface 2"; +# ether-options { +# 802.3ad { +# ae0; +# backup; +# } +# } +# } + + +# Using merged + +# Before state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/1 { +# description "Ansible configured interface 1"; +# ether-options { +# 802.3ad ae0; +# } +# } +# ge-0/0/2 { +# description "Ansible configured interface 2"; +# ether-options { +# 802.3ad ae0; +# } +# } +# ae0 { +# description "lag interface"; +# } +# ae3 { +# description "lag interface 3"; +# } + +- name: Overrides all device LAG configuration with provided configuration + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae0 + members: + - member: ge-0/0/2 + - name: ae1 + members: + - member: ge-0/0/1 + mode: passive + state: overridden + +# After state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/1 { +# description "Ansible configured interface 1"; +# ether-options { +# 802.3ad ae1; +# } +# } +# ge-0/0/2 { +# description "Ansible configured interface 2"; +# ether-options { +# 802.3ad ae0; +# } +# } +# ae0 { +# description "lag interface"; +# } +# ae1 { +# aggregated-ether-options { +# lacp { +# active; +# } +# } +# } + + +# Using merged + +# Before state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/1 { +# description "Ansible configured interface 1"; +# } +# ge-0/0/2 { +# description "Ansible configured interface 2"; +# } +# ge-0/0/3 { +# description "Ansible configured interface 3"; +# } + +- name: Replace device LAG configuration with provided configuration + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae0 + members: + - member: ge-0/0/1 + mode: active + state: replaced + +# After state: +# ------------- +# user@junos01# show interfaces +# ge-0/0/1 { +# description "Ansible configured interface 1"; +# ether-options { +# 802.3ad ae0; +# } +# } +# ge-0/0/2 { +# description "Ansible configured interface 2"; +# } +# ae0 { +# aggregated-ether-options { +# lacp { +# active; +# } +# } +# } +# ge-0/0/3 { +# description "Ansible configured interface 3"; +# } +# Using gathered +# Before state: +# ------------ +# +# ansible@cm123456tr21# show interfaces +# ge-0/0/1 { +# ether-options { +# 802.3ad ae1; +# } +# } +# ge-0/0/2 { +# ether-options { +# 802.3ad ae1; +# } +# } +# ge-0/0/3 { +# ether-options { +# 802.3ad { +# ae2; +# primary; +# } +# } +# } +# ge-0/0/4 { +# ether-options { +# 802.3ad { +# ae2; +# backup; +# } +# } +# } +# ge-1/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.1/24; +# address 10.200.16.20/24; +# } +# family inet6; +# } +# } +# ge-2/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.2/24; +# address 10.200.16.21/24; +# } +# family inet6; +# } +# } +# ge-3/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.3/24; +# address 10.200.16.22/24; +# } +# family inet6; +# } +# } +# ae1 { +# description "Configured by Ansible"; +# aggregated-ether-options { +# lacp { +# active; +# } +# } +# } +# ae2 { +# description "Configured by Ansible"; +# aggregated-ether-options { +# link-protection; +# lacp { +# passive; +# } +# } +# } +# em1 { +# description TEST; +# } +# fxp0 { +# description ANSIBLE; +# speed 1g; +# link-mode automatic; +# unit 0 { +# family inet { +# address 10.8.38.38/24; +# } +# } +# } +- name: Gather junos lag interfaces as in given arguments + junipernetworks.junos.junos_lag_interfaces: + state: gathered +# Task Output (redacted) +# ----------------------- +# +# "gathered": [ +# { +# "members": [ +# { +# "member": "ge-0/0/1" +# }, +# { +# "member": "ge-0/0/2" +# } +# ], +# "mode": "active", +# "name": "ae1" +# }, +# { +# "link_protection": true, +# "members": [ +# { +# "link_type": "primary", +# "member": "ge-0/0/3" +# }, +# { +# "link_type": "backup", +# "member": "ge-0/0/4" +# } +# ], +# "mode": "passive", +# "name": "ae2" +# } +# ] +# After state: +# ------------ +# +# ansible@cm123456tr21# show interfaces +# ge-0/0/1 { +# ether-options { +# 802.3ad ae1; +# } +# } +# ge-0/0/2 { +# ether-options { +# 802.3ad ae1; +# } +# } +# ge-0/0/3 { +# ether-options { +# 802.3ad { +# ae2; +# primary; +# } +# } +# } +# ge-0/0/4 { +# ether-options { +# 802.3ad { +# ae2; +# backup; +# } +# } +# } +# ge-1/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.1/24; +# address 10.200.16.20/24; +# } +# family inet6; +# } +# } +# ge-2/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.2/24; +# address 10.200.16.21/24; +# } +# family inet6; +# } +# } +# ge-3/0/0 { +# unit 0 { +# family inet { +# address 192.168.100.3/24; +# address 10.200.16.22/24; +# } +# family inet6; +# } +# } +# ae1 { +# description "Configured by Ansible"; +# aggregated-ether-options { +# lacp { +# active; +# } +# } +# } +# ae2 { +# description "Configured by Ansible"; +# aggregated-ether-options { +# link-protection; +# lacp { +# passive; +# } +# } +# } +# em1 { +# description TEST; +# } +# fxp0 { +# description ANSIBLE; +# speed 1g; +# link-mode automatic; +# unit 0 { +# family inet { +# address 10.8.38.38/24; +# } +# } +# } +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# +# +# +# ge-0/0/1 +# +# +# ae1 +# +# +# +# +# ge-0/0/2 +# +# +# ae1 +# +# +# +# +# ge-0/0/3 +# +# +# ae2 +# +# +# +# +# +# ge-0/0/4 +# +# +# ae2 +# +# +# +# +# +# ge-1/0/0 +# +# 0 +# +# +#
+# 192.168.100.1/24 +#
+#
+# 10.200.16.20/24 +#
+#
+# +# +#
+#
+#
+# +# ge-2/0/0 +# +# 0 +# +# +#
+# 192.168.100.2/24 +#
+#
+# 10.200.16.21/24 +#
+#
+# +# +#
+#
+#
+# +# ge-3/0/0 +# +# 0 +# +# +#
+# 192.168.100.3/24 +#
+#
+# 10.200.16.22/24 +#
+#
+# +# +#
+#
+#
+# +# ae1 +# Configured by Ansible +# +# +# +# +# +# +# +# ae2 +# Configured by Ansible +# +# +# +# +# +# +# +# +# +# em1 +# TEST +# +# +# fxp0 +# ANSIBLE +# 1g +# automatic +# +# 0 +# +# +#
+# 10.8.38.38/24 +#
+#
+#
+#
+#
+#
+#
+#
+# - name: Convert interfaces config to argspec without connecting to the appliance +# junipernetworks.junos.junos_lag_interfaces: +# running_config: "{{ lookup('file', './parsed.cfg') }}" +# state: parsed +# Task Output (redacted) +# ----------------------- +# "parsed": [ +# { +# "members": [ +# { +# "member": "ge-0/0/1" +# }, +# { +# "member": "ge-0/0/2" +# } +# ], +# "mode": "active", +# "name": "ae1" +# }, +# { +# "link_protection": true, +# "members": [ +# { +# "link_type": "primary", +# "member": "ge-0/0/3" +# }, +# { +# "link_type": "backup", +# "member": "ge-0/0/4" +# } +# ], +# "mode": "passive", +# "name": "ae2" +# } +# ] +# Using rendered +- name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae1 + members: + - member: ge-0/0/1 + - member: ge-0/0/2 + mode: active + + - name: ae2 + link_protection: true + members: + - member: ge-0/0/3 + link_type: primary + - member: ge-0/0/4 + link_type: backup + mode: passive +# Task Output (redacted) +# ----------------------- +# "rendered": " +# +# ae1 +# +# +# +# +# +# +# +# ge-0/0/1 +# +# +# ae1 +# +# +# +# +# ge-0/0/2 +# +# +# ae1 +# +# +# +# +# ae2 +# +# +# +# +# +# +# +# +# ge-0/0/3 +# +# +# ae2 +# +# +# +# +# +# ge-0/0/4 +# +# +# ae2 +# +# +# +# +# " +""" +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. +xml: + description: The set of xml rpc payload pushed to the remote device. + returned: always + type: list + sample: [' + + ae1 + + + + + + + + ge-0/0/1 + + + ae1 + + + + + ge-0/0/2 + + + ae1 + + + + + ae2 + + + + + + + + + ge-0/0/3 + + + ae2 + + + + + + ge-0/0/4 + + + ae2 + + + + +', 'xml 2', 'xml 3'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.lag_interfaces.lag_interfaces import ( + Lag_interfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.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", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_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/ansible_collections/juniper/device/plugins/modules/junos_lldp_global.py b/ansible_collections/juniper/device/plugins/modules/junos_lldp_global.py new file mode 100644 index 00000000..44919124 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_lldp_global.py @@ -0,0 +1,331 @@ +#!/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 junos_lldp_global +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_lldp_global +short_description: LLDP resource module +description: +- This module manages link layer discovery protocol (LLDP) attributes on Juniper JUNOS + devices. +version_added: 1.0.0 +author: Ganesh Nalawade (@ganeshrn) +options: + config: + description: The list of link layer discovery protocol attribute configurations + type: dict + suboptions: + enabled: + description: + - This argument is a boolean value to enabled or disable LLDP. + type: bool + interval: + description: + - Frequency at which LLDP advertisements are sent (in seconds). + type: int + address: + description: + - This argument sets the management address from LLDP. + type: str + transmit_delay: + description: + - Specify the number of seconds the device waits before sending advertisements + to neighbors after a change is made in local system. + type: int + hold_multiplier: + description: + - Specify the number of seconds that LLDP information is held before it is + discarded. The multiplier value is used in combination with the C(interval) + value. + type: int + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show protocols lldp). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + description: + - The state of the configuration after module completion. + type: str + choices: + - merged + - replaced + - deleted + - gathered + - rendered + - parsed + default: merged +requirements: +- ncclient (>=v0.6.4) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 18.4R1. +- This module works with connection C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +""" +EXAMPLES = """ +# Using merged +# Before state: +# ------------- +# user@junos01# # show protocols lldp +# +- name: Merge provided configuration with device configuration + junipernetworks.junos.junos_lldp_global: + config: + interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + state: merged + +# After state: +# ------------- +# user@junos01# show protocols lldp +# management-address 10.1.1.1; +# advertisement-interval 10000; +# transmit-delay 400; +# hold-multiplier 10; + +# Using replaced +# Before state: +# ------------- +# user@junos01# show protocols lldp +# management-address 10.1.1.1; +# advertisement-interval 10000; +# transmit-delay 400; +# hold-multiplier 10; + +- name: Replace provided configuration with device configuration + junipernetworks.junos.junos_lldp_global: + config: + address: 20.2.2.2 + hold_multiplier: 30 + enabled: false + state: replaced + +# After state: +# ------------- +# user@junos01# show protocols lldp +# disable; +# management-address 20.2.2.2; +# hold-multiplier 30; + +# Using deleted +# Before state: +# ------------- +# user@junos01# show protocols lldp +# management-address 20.2.2.2; +# hold-multiplier 30; + +- name: Delete lldp configuration (this will by default remove all lldp configuration) + junipernetworks.junos.junos_lldp_global: + state: deleted + +# After state: +# ------------- +# user@junos01# # show protocols lldp +# +# +# Using gathered +# Before state: +# ------------ +# +# ansible@cm123456tr21# show protocols lldp +# management-address 10.1.1.1; +# advertisement-interval 10000; +# transmit-delay 400; +# hold-multiplier 10; +# interface ge-0/0/1; +# interface ge-0/0/2 { +# disable; +# } +- name: Gather junos lldp_global as in given arguments + junipernetworks.junos.junos_lldp_global: + state: gathered +# Task Output (redacted) +# ----------------------- +# +# "gathered": { +# "address": "10.1.1.1", +# "hold_multiplier": 10, +# "interval": 10000, +# "transmit_delay": 400 +# } +# After state: +# ------------ +# +# ansible@cm123456tr21# show protocols lldp +# management-address 10.1.1.1; +# advertisement-interval 10000; +# transmit-delay 400; +# hold-multiplier 10; +# interface ge-0/0/1; +# interface ge-0/0/2 { +# disable; +# } +# Using rendered +- name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_lldp_global: + config: + interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + state: rendered +# Task Output (redacted) +# ----------------------- +# "rendered": " +# +# 10.1.1.1 +# 10000 +# 400 +# 10 +# +# +# " +# +# parsed.cfg +# ------------ +# +# +# +# +# +# +# +# 0.0.0.0 +# +# ge-0/0/0.0 +# +# +# +# +# 10.1.1.1 +# 10000 +# 400 +# 10 +# +# ge-0/0/1 +# +# +# ge-0/0/2 +# +# +# +# +# +# +# - name: Convert lldp global config to argspec without connecting to the appliance +# junipernetworks.junos.junos_lldp_global: +# running_config: "{{ lookup('file', './parsed.cfg') }}" +# state: parsed +# Task Output (redacted) +# ----------------------- +# "parsed": { +# "address": "10.1.1.1", +# "hold_multiplier": 10, +# "interval": 10000, +# "transmit_delay": 400 +# } +""" +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: [' + + 10.1.1.1 + 10000 + 400 + 10 + + +', 'xml 2', 'xml 3'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.lldp_global.lldp_global import ( + Lldp_globalArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.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",)), + ("state", "rendered", ("config",)), + ("state", "parsed", ("running_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/ansible_collections/juniper/device/plugins/modules/junos_lldp_interfaces.py b/ansible_collections/juniper/device/plugins/modules/junos_lldp_interfaces.py new file mode 100644 index 00000000..5b48666a --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_lldp_interfaces.py @@ -0,0 +1,359 @@ +#!/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 junos_lldp_interfaces +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_lldp_interfaces +short_description: LLDP interfaces resource module +description: +- This module manages link layer discovery protocol (LLDP) attributes of interfaces + on Juniper JUNOS devices. +version_added: 1.0.0 +author: Ganesh Nalawade (@ganeshrn) +options: + config: + description: The list of link layer discovery protocol interface attribute configurations + type: list + elements: dict + suboptions: + name: + description: + - Name of the interface LLDP needs to be configured on. + type: str + required: true + enabled: + description: + - This is a boolean value to control disabling of LLDP on the interface C(name) + type: bool + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show protocols lldp). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + description: + - The state of the configuration after module completion. + type: str + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - rendered + - parsed + default: merged +""" +EXAMPLES = """ +# Using merged +# Before state: +# ------------- +# user@junos01# # show protocols lldp +# management-address 10.1.1.1; +# advertisement-interval 10000; + +- name: Merge provided configuration with device configuration + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + enabled: false + state: merged + +# After state: +# ------------- +# user@junos01# show protocols lldp +# management-address 10.1.1.1; +# advertisement-interval 10000; +# interface ge-0/0/1; +# interface ge-0/0/2 { +# disable; +# } + +# Using replaced +# Before state: +# ------------- +# user@junos01# show protocols lldp +# management-address 10.1.1.1; +# advertisement-interval 10000; +# interface ge-0/0/1; +# interface ge-0/0/2 { +# disable; +# } + +- name: Replace provided configuration with device configuration + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/2 + disable: false + - name: ge-0/0/3 + enabled: false + state: replaced + +# After state: +# ------------- +# user@junos01# show protocols lldp +# management-address 10.1.1.1; +# advertisement-interval 10000; +# interface ge-0/0/1; +# interface ge-0/0/2; +# interface ge-0/0/3 { +# disable; +# } + +# Using overridden +# Before state: +# ------------- +# user@junos01# show protocols lldp +# management-address 10.1.1.1; +# advertisement-interval 10000; +# interface ge-0/0/1; +# interface ge-0/0/2 { +# disable; +# } + +- name: Override provided configuration with device configuration + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/2 + enabled: false + state: overridden + +# After state: +# ------------- +# user@junos01# show protocols lldp +# management-address 10.1.1.1; +# advertisement-interval 10000; +# interface ge-0/0/2 { +# disable; +# } + +# Using deleted +# Before state: +# ------------- +# user@junos01# show protocols lldp +# management-address 10.1.1.1; +# advertisement-interval 10000; +# interface ge-0/0/1; +# interface ge-0/0/2; +# interface ge-0/0/3 { +# disable; +# } +- name: Delete lldp interface configuration (this will not delete other lldp configuration) + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/3 + state: deleted + +# After state: +# ------------- +# user@junos01# show protocols lldp +# management-address 10.1.1.1; +# advertisement-interval 10000; +# interface ge-0/0/2; +# interface ge-0/0/1; +# Using gathered +# Before state: +# ------------ +# +# ansible@cm123456tr21# show protocols lldp +# interface ge-0/0/1; +# interface ge-0/0/2 { +# disable; +# } +- name: Gather junos lldp interfaces as in given arguments + junipernetworks.junos.junos_lldp_interfaces: + state: gathered +# Task Output (redacted) +# ----------------------- +# +# "gathered": [ +# { +# "name": "ge-0/0/1" +# }, +# { +# "enabled": false, +# "name": "ge-0/0/2" +# } +# ] +# After state: +# ------------ +# +# ansible@cm123456tr21# show protocols lldp +# interface ge-0/0/1; +# interface ge-0/0/2 { +# disable; +# } +# Using rendered +- name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + enabled: false + state: rendered +# Task Output (redacted) +# ----------------------- +# "rendered": " +# +# +# ge-0/0/1 +# +# +# +# ge-0/0/2 +# +# +# +# " +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# +# +# +# +# 0.0.0.0 +# +# ge-0/0/0.0 +# +# +# +# +# +# ge-0/0/1 +# +# +# ge-0/0/2 +# +# +# +# +# +# +# - name: Convert lldp interfaces config to argspec without connecting to the appliance +# junipernetworks.junos.junos_lldp_interfaces: +# running_config: "{{ lookup('file', './parsed.cfg') }}" +# state: parsed +# Task Output (redacted) +# ----------------------- +# "parsed": [ +# { +# "name": "ge-0/0/1" +# }, +# { +# "enabled": false, +# "name": "ge-0/0/2" +# } +# ] +""" + +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: [' + + + ge-0/0/1 + + + + ge-0/0/2 + + + +', 'xml 2', 'xml 3'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.lldp_interfaces.lldp_interfaces import ( + Lldp_interfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.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", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_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/ansible_collections/juniper/device/plugins/modules/junos_logging_global.py b/ansible_collections/juniper/device/plugins/modules/junos_logging_global.py new file mode 100644 index 00000000..f4bfa5b5 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_logging_global.py @@ -0,0 +1,1743 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# 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 junos_logging_global +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +DOCUMENTATION = """ +--- +module: junos_logging_global +version_added: 2.4.0 +short_description: Manage logging configuration on Junos devices. +description: This module manages logging configuration on devices running Junos. +author: Rohit Thakur (@rohitthakur2590) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection C(netconf). + - See L(the Junos OS Platform Options,https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html). + - Tested against JunOS v18.4R1 +options: + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show system syslog). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result. + type: str + config: + description: A dictionary of logging configuration. + type: dict + suboptions: + allow_duplicates: &allow_duplicates + description: Do not suppress the repeated message for all targets. + type: bool + archive: + description: Specify archive file information. + type: dict + suboptions: + set: + description: Set archive file information. + type: bool + binary_data: + description: Mark file as if it contains binary data. + type: bool + files: + description: Specify number of files to be archived (1..1000). + type: int + no_binary_data: + description: Don't mark file as if it contains binary data. + type: bool + no_world_readable: + description: Don't allow any user to read the log file. + type: bool + file_size: + description: Size of files to be archived (65536..1073741824 bytes). + type: str + world_readable: + description: Allow any user to read the log file. + type: bool + console: + description: Set console logging parameters. + type: dict + suboptions: + any: &any + description: Set All facilities. + type: dict + suboptions: + level: &level + description: Set severity logging level. + type: str + required: true + choices: ["alert", "any", "critical", "emergency", "error", "info", "none", "notice", "warning"] + authorization: &authorization + description: Specify authorization system. + type: dict + suboptions: + level: *level + change_log: &change_log + description: Specify configuration change log. + type: dict + suboptions: + level: *level + conflict_log: &conflict_log + description: Specify configuration conflict log. + type: dict + suboptions: + level: *level + daemon: &daemon + description: Specify various system processes. + type: dict + suboptions: + level: *level + dfc: &dfc + description: Specify dynamic flow capture. + type: dict + suboptions: + level: *level + external: &external + description: Specify Local external applications. + type: dict + suboptions: + level: *level + firewall: &firewall + description: Specify Firewall filtering system. + type: dict + suboptions: + level: *level + ftp: &ftp + description: Specify FTP process. + type: dict + suboptions: + level: *level + interactive_commands: &interactive_commands + description: Specify commands executed by the UI. + type: dict + suboptions: + level: *level + kernel: &kernel + description: Specify Kernel specific logging. + type: dict + suboptions: + level: *level + ntp: &ntp + description: Specify NTP process specific logging. + type: dict + suboptions: + level: *level + pfe: &pfe + description: Specify Packet Forwarding Engine specific logging. + type: dict + suboptions: + level: *level + security: &security + description: Specify Security related logging. + type: dict + suboptions: + level: *level + user: &user + description: Specify user specific logging. + type: dict + suboptions: + level: *level + files: + description: Specify files logging. + type: list + elements: dict + suboptions: + name: + description: Specify filename in which to log data. + type: str + allow_duplicates: *allow_duplicates + any: *any + archive: + description: Specify archive file information. + type: dict + suboptions: + set: + description: Set archive file information. + type: bool + archive_sites: + description: Specify Primary and failover URLs to receive archive facilities. + type: list + elements: str + binary_data: + description: Mark file as if it contains binary data. + type: bool + files: + description: Specify number of files to be archived (1..1000). + type: int + no_binary_data: + description: Don't mark file as if it contains binary data. + type: bool + no_world_readable: + description: Don't allow any user to read the log file. + type: bool + file_size: + description: Size of files to be archived (65536..1073741824 bytes). + type: str + start_time: + description: Specify start time for file transmission (yyyy-mm-dd.hh:mm). + type: str + transfer_interval: + description: Specify frequency at which to transfer files to archive sites (5..2880 minutes). + type: int + world_readable: + description: Allow any user to read the log file. + type: bool + authorization: *authorization + change_log: *change_log + conflict_log: *conflict_log + daemon: *daemon + dfc: *dfc + explicit_priority: &explicit_priority + description: Include priority and facility in messages. + type: bool + external: *external + firewall: *firewall + ftp: *ftp + interactive_commands: *interactive_commands + kernel: *kernel + match: &match + description: Specify regular expression for lines to be logged. + type: str + match_strings: &match_strings + description: Specify matching string(s) for lines to be logged. + type: list + elements: str + ntp: *ntp + pfe: *pfe + security: *security + structured_data: &structured_data + description: Specify Log system message in structured format. + type: dict + suboptions: + set: + description: Set Log system message in structured format. + type: bool + brief: + description: Omit English-language text from end of logged messages. + type: bool + user: *user + hosts: &hosts + description: Specify hosts to be notified. + type: list + elements: dict + suboptions: + name: + description: Specify the host name. + type: str + allow_duplicates: *allow_duplicates + any: *any + authorization: *authorization + change_log: *change_log + conflict_log: *conflict_log + daemon: *daemon + dfc: *dfc + exclude_hostname: + description: Specify exclude hostname field in messages. + type: bool + explicit_priority: *explicit_priority + external: *external + facility_override: + description: Specify alternate facility for logging to remote host. + type: str + firewall: *firewall + ftp: *ftp + interactive_commands: *interactive_commands + kernel: *kernel + log_prefix: + description: Prefix for all logging to this host. + type: str + match: *match + match_strings: *match_strings + ntp: *ntp + pfe: *pfe + port: + description: Specify port number. + type: int + routing_instance: + description: Specify routing-instance. + type: str + security: *security + source_address: + description: Specify address as source address. + type: str + structured_data: *structured_data + user: *user + log_rotate_frequency: + description: Specify Rotate log frequency (1..59 minutes). + type: int + routing_instance: + description: Specify Routing routing-instance. + type: str + server: + description: Specify syslog server logging. + type: dict + suboptions: + set: + description: Enable syslog server. + type: bool + routing_instance: + description: nable/disable syslog server in routing-instances. + type: dict + suboptions: + all: + description: Enable/disable all routing instances. + type: bool + default: + description: Enable/disable default routing instances. + type: bool + routing_instances: + description: Specify routing-instances. + type: list + elements: dict + suboptions: + name: + description: Specify routing-instance name. + type: str + disable: + description: Disable syslog server in this routing instances. + type: bool + source_address: + description: Specify address as source address. + type: str + time_format: + description: Specify additional information to include in system log timestamp. + type: dict + suboptions: + set: + description: Set time-format + type: bool + millisecond: + description: Include milliseconds in timestamp. + type: bool + year: + description: Include year in timestamp. + type: bool + users: + description: Specify user logging + type: list + elements: dict + suboptions: + name: + description: Specify user name. + type: str + allow_duplicates: *allow_duplicates + any: *any + authorization: *authorization + change_log: *change_log + conflict_log: *conflict_log + daemon: *daemon + dfc: *dfc + external: *external + firewall: *firewall + ftp: *ftp + interactive_commands: *interactive_commands + kernel: *kernel + match: + description: Specify regular expression for lines to be logged. + type: str + match_strings: + description: Specify matching string(s) for lines to be logged. + type: list + elements: str + ntp: *ntp + pfe: *pfe + security: *security + user: *user + state: + description: + - The state the configuration should be left in. + - Refer to examples for more details. + type: str + choices: + - merged + - replaced + - deleted + - overridden + - parsed + - gathered + - rendered + default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# vagrant@vsrx# show system syslog +# +# [edit] +# vagrant@vsrx# show routing-instances +# inst11 { +# description inst11; +# } +- name: Merge provided logging configuration into running configuration. + junipernetworks.junos.junos_logging_global: + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: 65578 + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: 65578 + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: merged +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "allow_duplicates": true, +# "archive": { +# "file_size": 65578, +# "files": 10, +# "no_binary_data": true, +# "no_world_readable": true +# }, +# "console": { +# "any": { +# "level": "info" +# }, +# "authorization": { +# "level": "any" +# }, +# "change_log": { +# "level": "critical" +# }, +# "ftp": { +# "level": "none" +# } +# }, +# "files": [ +# { +# "allow_duplicates": true, +# "name": "file101" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "file102", +# "structured_data": { +# "set": true +# } +# }, +# { +# "archive": { +# "file_size": 65578, +# "files": 10, +# "no_binary_data": true, +# "no_world_readable": true +# }, +# "explicit_priority": true, +# "match": "^set*", +# "match_strings": [ +# "^delete", +# "^prompt" +# ], +# "name": "file103" +# } +# ], +# "hosts": [ +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "exclude_hostname": true, +# "facility_override": "ftp", +# "log_prefix": "field", +# "match": "^set*", +# "match_strings": [ +# "^delete", +# "^prompt" +# ], +# "name": "host111", +# "port": 1231, +# "routing_instance": "inst11", +# "source_address": "11.1.1.11", +# "structured_data": { +# "brief": true +# } +# } +# ], +# "log_rotate_frequency": 45, +# "routing_instance": "inst11", +# "source_address": "33.33.33.33", +# "time_format": { +# "millisecond": true, +# "year": true +# }, +# "users": [ +# { +# "allow_duplicates": true, +# "name": "user1" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "user2", +# "user": { +# "level": "info" +# } +# } +# ] +# }, +# "before": {}, +# "changed": true, +# "commands": [ +# "" +# "10" +# "65578" +# "change-log" +# "anyauthorization" +# "ftp" +# "file101file102" +# "any" +# "file10310" +# "65578" +# "^set*^delete" +# "^prompthost111" +# "any" +# "ftp" +# "field^set*^delete" +# "^prompt1231" +# "inst1111.1.1.11" +# "" +# "45inst11" +# "33.33.33.33" +# "user1" +# "user2any" +# "user" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show system syslog +# archive size 65578 files 10 no-world-readable no-binary-data; +# user user1 { +# allow-duplicates; +# } +# user user2 { +# any any; +# user info; +# allow-duplicates; +# } +# host host111 { +# any any; +# match "^set*"; +# allow-duplicates; +# port 1231; +# facility-override ftp; +# log-prefix field; +# source-address 11.1.1.11; +# routing-instance inst11; +# exclude-hostname; +# match-strings [ "^delete" "^prompt" ]; +# structured-data { +# brief; +# } +# } +# allow-duplicates; +# file file101 { +# allow-duplicates; +# } +# file file102 { +# any any; +# allow-duplicates; +# structured-data; +# } +# file file103 { +# match "^set*"; +# archive size 65578 files 10 no-world-readable no-binary-data; +# explicit-priority; +# match-strings [ "^delete" "^prompt" ]; +# } +# console { +# any info; +# authorization any; +# ftp none; +# change-log critical; +# } +# time-format year millisecond; +# source-address 33.33.33.33; +# routing-instance inst11; +# log-rotate-frequency 45; +# Using replaced +# +# Before state +# ------------ +# +# vagrant@vsrx# show system syslog +# archive size 65578 files 10 no-world-readable no-binary-data; +# user user1 { +# allow-duplicates; +# } +# user user2 { +# any any; +# user info; +# allow-duplicates; +# } +# host host111 { +# any any; +# match "^set*"; +# allow-duplicates; +# port 1231; +# facility-override ftp; +# log-prefix field; +# source-address 11.1.1.11; +# routing-instance inst11; +# exclude-hostname; +# match-strings [ "^delete" "^prompt" ]; +# structured-data { +# brief; +# } +# } +# allow-duplicates; +# file file101 { +# allow-duplicates; +# } +# file file102 { +# any any; +# allow-duplicates; +# structured-data; +# } +# file file103 { +# match "^set*"; +# archive size 65578 files 10 no-world-readable no-binary-data; +# explicit-priority; +# match-strings [ "^delete" "^prompt" ]; +# } +# console { +# any info; +# authorization any; +# ftp none; +# change-log critical; +# } +# time-format year millisecond; +# source-address 33.33.33.33; +# routing-instance inst11; +# log-rotate-frequency 45; +- name: Replaced running logging global configuration with provided configuration + junipernetworks.junos.junos_logging_global: + config: + files: + - name: "file104" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + hosts: + - name: host222 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: replaced +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "files": [ +# { +# "allow_duplicates": true, +# "name": "file104" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "file102", +# "structured_data": { +# "set": true +# } +# } +# ], +# "hosts": [ +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "exclude_hostname": true, +# "facility_override": "ftp", +# "log_prefix": "field", +# "match": "^set*", +# "match_strings": [ +# "^delete", +# "^prompt" +# ], +# "name": "host222", +# "port": 1231, +# "routing_instance": "inst11", +# "source_address": "11.1.1.11", +# "structured_data": { +# "brief": true +# } +# } +# ], +# "users": [ +# { +# "allow_duplicates": true, +# "name": "user1" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "user2", +# "user": { +# "level": "info" +# } +# } +# ] +# }, +# "before": { +# "allow_duplicates": true, +# "archive": { +# "file_size": 65578, +# "files": 10, +# "no_binary_data": true, +# "no_world_readable": true +# }, +# "console": { +# "any": { +# "level": "info" +# }, +# "authorization": { +# "level": "any" +# }, +# "change_log": { +# "level": "critical" +# }, +# "ftp": { +# "level": "none" +# } +# }, +# "files": [ +# { +# "allow_duplicates": true, +# "name": "file101" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "file102", +# "structured_data": { +# "set": true +# } +# }, +# { +# "archive": { +# "file_size": 65578, +# "files": 10, +# "no_binary_data": true, +# "no_world_readable": true +# }, +# "explicit_priority": true, +# "match": "^set*", +# "match_strings": [ +# "^delete", +# "^prompt" +# ], +# "name": "file103" +# } +# ], +# "hosts": [ +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "exclude_hostname": true, +# "facility_override": "ftp", +# "log_prefix": "field", +# "match": "^set*", +# "match_strings": [ +# "^delete", +# "^prompt" +# ], +# "name": "host111", +# "port": 1231, +# "routing_instance": "inst11", +# "source_address": "11.1.1.11", +# "structured_data": { +# "brief": true +# } +# } +# ], +# "log_rotate_frequency": 45, +# "routing_instance": "inst11", +# "source_address": "33.33.33.33", +# "time_format": { +# "millisecond": true, +# "year": true +# }, +# "users": [ +# { +# "allow_duplicates": true, +# "name": "user1" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "user2", +# "user": { +# "level": "info" +# } +# } +# ] +# }, +# "changed": true, +# "commands": [ +# "" +# "file104" +# "file102" +# "any" +# "host222any" +# "ftp" +# "field^set*" +# "^delete" +# "^prompt1231" +# "inst1111.1.1.11" +# "user1" +# "user2" +# "any" +# "user" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show system syslog +# user user1 { +# allow-duplicates; +# } +# user user2 { +# any any; +# user info; +# allow-duplicates; +# } +# host host222 { +# any any; +# match "^set*"; +# allow-duplicates; +# port 1231; +# facility-override ftp; +# log-prefix field; +# source-address 11.1.1.11; +# routing-instance inst11; +# exclude-hostname; +# match-strings [ "^delete" "^prompt" ]; +# structured-data { +# brief; +# } +# } +# file file104 { +# allow-duplicates; +# } +# file file102 { +# any any; +# allow-duplicates; +# structured-data; +# } +# Using overridden +# +# Before state +# ------------ +# +# vagrant@vsrx# show system syslog +# archive size 65578 files 10 no-world-readable no-binary-data; +# user user1 { +# allow-duplicates; +# } +# user user2 { +# any any; +# user info; +# allow-duplicates; +# } +# host host111 { +# any any; +# match "^set*"; +# allow-duplicates; +# port 1231; +# facility-override ftp; +# log-prefix field; +# source-address 11.1.1.11; +# routing-instance inst11; +# exclude-hostname; +# match-strings [ "^delete" "^prompt" ]; +# structured-data { +# brief; +# } +# } +# allow-duplicates; +# file file101 { +# allow-duplicates; +# } +# file file102 { +# any any; +# allow-duplicates; +# structured-data; +# } +# file file103 { +# match "^set*"; +# archive size 65578 files 10 no-world-readable no-binary-data; +# explicit-priority; +# match-strings [ "^delete" "^prompt" ]; +# } +# console { +# any info; +# authorization any; +# ftp none; +# change-log critical; +# } +# time-format year millisecond; +# source-address 33.33.33.33; +# routing-instance inst11; +# log-rotate-frequency 45; +- name: Override running logging global configuration with provided configuration + junipernetworks.junos.junos_logging_global: + config: + files: + - name: "file104" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + hosts: + - name: host222 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: overridden +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "files": [ +# { +# "allow_duplicates": true, +# "name": "file104" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "file102", +# "structured_data": { +# "set": true +# } +# } +# ], +# "hosts": [ +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "exclude_hostname": true, +# "facility_override": "ftp", +# "log_prefix": "field", +# "match": "^set*", +# "match_strings": [ +# "^delete", +# "^prompt" +# ], +# "name": "host222", +# "port": 1231, +# "routing_instance": "inst11", +# "source_address": "11.1.1.11", +# "structured_data": { +# "brief": true +# } +# } +# ], +# "users": [ +# { +# "allow_duplicates": true, +# "name": "user1" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "user2", +# "user": { +# "level": "info" +# } +# } +# ] +# }, +# "before": { +# "allow_duplicates": true, +# "archive": { +# "file_size": 65578, +# "files": 10, +# "no_binary_data": true, +# "no_world_readable": true +# }, +# "console": { +# "any": { +# "level": "info" +# }, +# "authorization": { +# "level": "any" +# }, +# "change_log": { +# "level": "critical" +# }, +# "ftp": { +# "level": "none" +# } +# }, +# "files": [ +# { +# "allow_duplicates": true, +# "name": "file101" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "file102", +# "structured_data": { +# "set": true +# } +# }, +# { +# "archive": { +# "file_size": 65578, +# "files": 10, +# "no_binary_data": true, +# "no_world_readable": true +# }, +# "explicit_priority": true, +# "match": "^set*", +# "match_strings": [ +# "^delete", +# "^prompt" +# ], +# "name": "file103" +# } +# ], +# "hosts": [ +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "exclude_hostname": true, +# "facility_override": "ftp", +# "log_prefix": "field", +# "match": "^set*", +# "match_strings": [ +# "^delete", +# "^prompt" +# ], +# "name": "host111", +# "port": 1231, +# "routing_instance": "inst11", +# "source_address": "11.1.1.11", +# "structured_data": { +# "brief": true +# } +# } +# ], +# "log_rotate_frequency": 45, +# "routing_instance": "inst11", +# "source_address": "33.33.33.33", +# "time_format": { +# "millisecond": true, +# "year": true +# }, +# "users": [ +# { +# "allow_duplicates": true, +# "name": "user1" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "user2", +# "user": { +# "level": "info" +# } +# } +# ] +# }, +# "changed": true, +# "commands": [ +# "" +# "file104" +# "file102" +# "any" +# "host222any" +# "ftp" +# "field^set*" +# "^delete" +# "^prompt1231" +# "inst1111.1.1.11" +# "user1" +# "user2" +# "any" +# "user" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show system syslog +# user user1 { +# allow-duplicates; +# } +# user user2 { +# any any; +# user info; +# allow-duplicates; +# } +# host host222 { +# any any; +# match "^set*"; +# allow-duplicates; +# port 1231; +# facility-override ftp; +# log-prefix field; +# source-address 11.1.1.11; +# routing-instance inst11; +# exclude-hostname; +# match-strings [ "^delete" "^prompt" ]; +# structured-data { +# brief; +# } +# } +# file file104 { +# allow-duplicates; +# } +# file file102 { +# any any; +# allow-duplicates; +# structured-data; +# } +# Using deleted +# +# Before state +# ------------ +# +# vagrant@vsrx# show system syslog +# user user1 { +# allow-duplicates; +# } +# user user2 { +# any any; +# user info; +# allow-duplicates; +# } +# host host222 { +# any any; +# match "^set*"; +# allow-duplicates; +# port 1231; +# facility-override ftp; +# log-prefix field; +# source-address 11.1.1.11; +# routing-instance inst11; +# exclude-hostname; +# match-strings [ "^delete" "^prompt" ]; +# structured-data { +# brief; +# } +# } +# file file104 { +# allow-duplicates; +# } +# file file102 { +# any any; +# allow-duplicates; +# structured-data; +# } +- name: Delete running logging global configuration + junipernetworks.junos.junos_logging_global: + config: + state: deleted +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": {}, +# "before": { +# "files": [ +# { +# "allow_duplicates": true, +# "name": "file104" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "file102", +# "structured_data": { +# "set": true +# } +# } +# ], +# "hosts": [ +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "exclude_hostname": true, +# "facility_override": "ftp", +# "log_prefix": "field", +# "match": "^set*", +# "match_strings": [ +# "^delete", +# "^prompt" +# ], +# "name": "host222", +# "port": 1231, +# "routing_instance": "inst11", +# "source_address": "11.1.1.11", +# "structured_data": { +# "brief": true +# } +# } +# ], +# "users": [ +# { +# "allow_duplicates": true, +# "name": "user1" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "user2", +# "user": { +# "level": "info" +# } +# } +# ] +# }, +# "changed": true, +# "commands": [ +# "" +# "" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show system syslog +# +# [edit] +# Using gathered +# +# Before state +# ------------ +# +# vagrant@vsrx# show system syslog +# user user1 { +# allow-duplicates; +# } +# user user2 { +# any any; +# user info; +# allow-duplicates; +# } +# host host222 { +# any any; +# match "^set*"; +# allow-duplicates; +# port 1231; +# facility-override ftp; +# log-prefix field; +# source-address 11.1.1.11; +# routing-instance inst11; +# exclude-hostname; +# match-strings [ "^delete" "^prompt" ]; +# structured-data { +# brief; +# } +# } +# file file104 { +# allow-duplicates; +# } +# file file102 { +# any any; +# allow-duplicates; +# structured-data; +# } +- name: Gather running logging global configuration + junipernetworks.junos.junos_logging_global: + state: gathered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "gathered": { +# "files": [ +# { +# "allow_duplicates": true, +# "name": "file104" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "file102", +# "structured_data": { +# "set": true +# } +# } +# ], +# "hosts": [ +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "exclude_hostname": true, +# "facility_override": "ftp", +# "log_prefix": "field", +# "match": "^set*", +# "match_strings": [ +# "^delete", +# "^prompt" +# ], +# "name": "host222", +# "port": 1231, +# "routing_instance": "inst11", +# "source_address": "11.1.1.11", +# "structured_data": { +# "brief": true +# } +# } +# ], +# "users": [ +# { +# "allow_duplicates": true, +# "name": "user1" +# }, +# { +# "allow_duplicates": true, +# "any": { +# "level": "any" +# }, +# "name": "user2", +# "user": { +# "level": "info" +# } +# } +# ] +# }, +# "changed": false, +# Using rendered +# +# Before state +# ------------ +# +- name: Render xml for provided facts. + junipernetworks.junos.junos_logging_global: + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: 65578 + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: 65578 + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: rendered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "rendered": [ +# "" +# "10" +# "65578" +# "change-log" +# "anyauthorization" +# "ftp" +# "file101file102" +# "any" +# "file10310" +# "65578" +# "^set*^delete" +# "^prompthost111" +# "any" +# "ftp" +# "field^set*^delete" +# "^prompt1231" +# "inst1111.1.1.11" +# "" +# "45inst11" +# "33.33.33.33" +# "user1" +# "user2any" +# "user" +# ] +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# +# +# * +# +# any +# +# +# +# +# messages +# +# any +# +# +# +# authorization +# +# +# +# +# interactive-commands +# +# interactive-commands +# +# +# +# +# +# +# +- name: Parse logging global running config + junipernetworks.junos.junos_routing_instances: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "parsed": { +# "files": [ +# { +# "any": { +# "level": "any" +# }, +# "authorization": { +# "level": "info" +# }, +# "name": "messages" +# }, +# { +# "interactive_commands": { +# "level": "any" +# }, +# "name": "interactive-commands" +# } +# ], +# "users": [ +# { +# "any": { +# "level": "emergency" +# }, +# "name": "*" +# } +# ] +# } +# +# +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: dict +after: + description: The resulting configuration model invocation. + returned: when changed + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: dict +commands: + description: The set of commands pushed to the remote device. + returned: always + type: list + sample: ['user2 + any + user + "', 'xml 2', 'xml 3'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.logging_global.logging_global import ( + Logging_globalArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.logging_global.logging_global import ( + Logging_global, +) + + +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",)), + ] + module = AnsibleModule( + argument_spec=Logging_globalArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + result = Logging_global(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_netconf.py b/ansible_collections/juniper/device/plugins/modules/junos_netconf.py new file mode 100644 index 00000000..d31e6eac --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_netconf.py @@ -0,0 +1,193 @@ +#!/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 + + +DOCUMENTATION = """ +module: junos_netconf +author: Peter Sprygada (@privateip) +short_description: Configures the Junos Netconf system service +description: +- This module provides an abstraction that enables and configures the netconf system + service running on Junos devices. This module can be used to easily enable the + Netconf API. Netconf provides a programmatic interface for working with configuration + and state resources as defined in RFC 6242. If the C(netconf_port) is not mentioned + in the task by default netconf will be enabled on port 830 only. +version_added: 1.0.0 +extends_documentation_fragment: +- junipernetworks.junos.junos +options: + netconf_port: + description: + - This argument specifies the port the netconf service should listen on for SSH + connections. The default port as defined in RFC 6242 is 830. + required: false + default: 830 + aliases: + - listens_on + type: int + state: + description: + - Specifies the state of the C(junos_netconf) resource on the remote device. If + the I(state) argument is set to I(present) the netconf service will be configured. If + the I(state) argument is set to I(absent) the netconf service will be removed + from the configuration. + type: str + required: false + default: present + choices: + - present + - absent +notes: +- Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. +- Recommended connection is C(network_cli). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +- This module also works with C(local) connections for legacy playbooks. +- If C(netconf_port) value is not mentioned in task by default it will be enabled + on port 830 only. Although C(netconf_port) value can be from 1 through 65535, avoid + configuring access on a port that is normally assigned for another service. This + practice avoids potential resource conflicts. +""" + +EXAMPLES = """ +- name: enable netconf service on port 830 + junipernetworks.junos.junos_netconf: + listens_on: 830 + state: present + +- name: disable netconf service + junipernetworks.junos.junos_netconf: + state: absent +""" + +RETURN = """ +commands: + description: Returns the command sent to the remote device + returned: when changed is True + type: str + sample: 'set system services netconf ssh port 830' +""" +import re + +from ansible.module_utils._text import to_text +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import ConnectionError +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_list + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + get_connection, +) + + +USE_PERSISTENT_CONNECTION = True + + +def map_obj_to_commands(updates, module): + want, have = updates + commands = list() + + if want["state"] == "absent": + if have["state"] == "present": + commands.append("delete system services netconf") + else: + if have["state"] == "absent" or want["netconf_port"] != have.get( + "netconf_port", + ): + commands.append( + "set system services netconf ssh port %s" % want["netconf_port"], + ) + + return commands + + +def parse_port(config): + match = re.search(r"port (\d+)", config) + if match: + return int(match.group(1)) + + +def map_config_to_obj(module): + conn = get_connection(module) + out = conn.get(command="show configuration system services netconf") + if out is None: + module.fail_json(msg="unable to retrieve current config") + config = str(out).strip() + + obj = {"state": "absent"} + if "ssh" in config: + obj.update({"state": "present", "netconf_port": parse_port(config)}) + return obj + + +def validate_netconf_port(value, module): + if not 1 <= value <= 65535: + module.fail_json(msg="netconf_port must be between 1 and 65535") + + +def map_params_to_obj(module): + obj = { + "netconf_port": module.params["netconf_port"], + "state": module.params["state"], + } + + for key, value in iteritems(obj): + # validate the param value (if validator func exists) + validator = globals().get("validate_%s" % key) + if callable(validator): + validator(value, module) + + return obj + + +def load_config(module, config, commit=False): + conn = get_connection(module) + try: + resp = conn.edit_config(to_list(config) + ["top"], commit) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) + + diff = resp.get("diff", "") + return to_text(diff, errors="surrogate_then_replace").strip() + + +def main(): + """main entry point for module execution""" + argument_spec = dict( + netconf_port=dict(type="int", default=830, aliases=["listens_on"]), + state=dict(default="present", choices=["present", "absent"]), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + 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((want, have), module) + result["commands"] = commands + + if commands: + commit = not module.check_mode + diff = load_config(module, commands, commit=commit) + if diff: + if module._diff: + result["diff"] = {"prepared": diff} + result["changed"] = True + + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_ntp_global.py b/ansible_collections/juniper/device/plugins/modules/junos_ntp_global.py new file mode 100644 index 00000000..6b33faea --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_ntp_global.py @@ -0,0 +1,1019 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# 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 junos_logging_global +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +DOCUMENTATION = """ +--- +module: junos_ntp_global +version_added: 2.6.0 +short_description: Manage NTP configuration on Junos devices. +description: This module manages NTP configuration on devices running Junos. +author: Rohit Thakur (@rohitthakur2590) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection C(netconf). + - See L(the Junos OS Platform Options,https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html). + - Tested against JunOS v18.4R1 +options: + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show system syslog). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result. + type: str + config: + description: A dictionary of NTP configuration. + type: dict + suboptions: + authentication_keys: + description: NTP authentication key. + type: list + elements: dict + suboptions: + id: + description: Authentication key number. + type: int + algorithm: + description: Authentication key type. + type: str + choices: ['md5', 'sha1', 'sha256'] + key: + description: Authentication key value. + type: str + boot_server: + description: Server to query during boot sequence. + type: str + broadcasts: + description: Broadcast parameters. + type: list + elements: dict + suboptions: + address: + description: Broadcast or multicast address to use. + type: str + key: + description: Authentication key. + type: str + routing_instance_name: + description: Routing intance name in which interface has address in broadcast subnet. + type: str + ttl: + description: TTL value to transmit. + type: int + version: + description: NTP version to use. + type: int + broadcast_client: + description: Listen to broadcast NTP. + type: bool + interval_range: + description: Set the minpoll and maxpoll interval range. + type: int + multicast_client: + description: Listen to multicast NTP address. + type: str + peers: + description: NTP Peers. + type: list + elements: dict + suboptions: &peers + peer: + description: Hostname/IP address of the NTP Peer. + type: str + key_id: + description: Key-id to be used while communicating. + type: int + prefer: + description: Prefer this peer. + type: bool + version: + description: NTP version to use. + type: int + servers: + description: NTP Servers. + type: list + elements: dict + suboptions: + server: + description: IP address or hostname of the server. + type: str + key_id: + description: Key-id to be used while communicating. + type: int + prefer: + description: Prefer this peer_serv. + type: bool + version: + description: NTP version to use. + type: int + routing_instance: + description: Routing instance through which server is reachable. + type: str + source_addresses: + description: Source-Address parameters. + type: list + elements: dict + suboptions: + source_address: + description: Use specified address as source address. + type: str + routing_instance: + description: Routing intance name in which source address is defined. + type: str + threshold: + description: Set the maximum threshold(sec) allowed for NTP adjustment. + type: dict + suboptions: + value: + description: The maximum value(sec) allowed for NTP adjustment. + type: int + action: + description: Select actions for NTP abnormal adjustment. + type: str + choices: ['accept', 'reject'] + trusted_keys: + description: List of trusted authentication keys. + type: list + elements: dict + suboptions: + key_id: + description: Trusted-Key number. + type: int + state: + description: + - The state the configuration should be left in. + - The states I(replaced) and I(overridden) have identical + behaviour for this module. + - Refer to examples for more details. + type: str + choices: + - merged + - replaced + - deleted + - overridden + - parsed + - gathered + - rendered + default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# vagrant@vsrx# show system ntp +# +# [edit] +# vagrant@vsrx# show routing-instances +# rt1 { +# description rt1; +# } +# rt2 { +- name: Merge provided NTP configuration into running configuration. + junipernetworks.junos.junos_ntp_global: + config: + boot_server: '78.46.194.186' + broadcasts: + - address: '172.16.255.255' + key: '50' + ttl: 200 + version: 3 + routing_instance_name: 'rt1' + - address: '192.16.255.255' + key: '50' + ttl: 200 + version: 3 + routing_instance_name: 'rt2' + broadcast_client: true + interval_range: 2 + multicast_client: "224.0.0.1" + peers: + - peer: "78.44.194.186" + - peer: "172.44.194.186" + key_id: 10000 + prefer: true + version: 3 + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: 'rt1' + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + source_addresses: + - source_address: "172.45.194.186" + routing_instance: 'rt1' + - source_address: "171.45.194.186" + routing_instance: 'rt2' + threshold: + value: 300 + action: "accept" + trusted_keys: + - key_id: 3000 + - key_id: 2000 + state: merged +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "boot_server": "78.46.194.186", +# "broadcast_client": true, +# "broadcasts": [ +# { +# "address": "172.16.255.255", +# "key": "50", +# "routing_instance_name": "rt1", +# "ttl": 200, +# "version": 3 +# }, +# { +# "address": "192.16.255.255", +# "key": "50", +# "routing_instance_name": "rt2", +# "ttl": 200, +# "version": 3 +# } +# ], +# "interval_range": 2, +# "multicast_client": "224.0.0.1", +# "peers": [ +# { +# "peer": "78.44.194.186" +# }, +# { +# "key_id": 10000, +# "peer": "172.44.194.186", +# "prefer": true, +# "version": 3 +# } +# ], +# "servers": [ +# { +# "key_id": 34, +# "prefer": true, +# "routing_instance": "rt1", +# "server": "48.46.194.186", +# "version": 2 +# }, +# { +# "key_id": 34, +# "prefer": true, +# "server": "48.45.194.186", +# "version": 2 +# } +# ], +# "source_addresses": [ +# { +# "routing_instance": "rt1", +# "source_address": "172.45.194.186" +# }, +# { +# "routing_instance": "rt2", +# "source_address": "171.45.194.186" +# } +# ], +# "threshold": { +# "action": "accept", +# "value": 300 +# }, +# "trusted_keys": [ +# {"key_id": 2000}, +# {"key_id": 3000} +# ] +# }, +# "before": {}, +# "changed": true, +# "commands": [ +# "" +# "78.46.194.186" +# "172.16.255.25550rt1" +# "2003192.16.255.255" +# "50rt2200" +# "32" +# "224.0.0.178.44.194.186" +# "172.44.194.186100003" +# "48.46.194.18634rt1" +# "248.45.194.18634" +# "2172.45.194.186" +# "rt1" +# "171.45.194.186rt2" +# "300accept" +# "30002000" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show system ntp +# boot-server 78.46.194.186; +# interval-range 2; +# peer 78.44.194.186; +# peer 172.44.194.186 key 10000 version 3 prefer; ## SECRET-DATA +# server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA +# server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA +# broadcast 172.16.255.255 routing-instance-name rt1 key 50 version 3 ttl 200; +# broadcast 192.16.255.255 routing-instance-name rt2 key 50 version 3 ttl 200; +# broadcast-client; +# multicast-client 224.0.0.1; +# trusted-key [ 3000 2000 ]; +# threshold 300 action accept; +# source-address 172.45.194.186 routing-instance rt1; +# source-address 171.45.194.186 routing-instance rt2; +# +# +# Using Replaced +# Before state +# ------------ +# +# vagrant@vsrx# show system ntp +# boot-server 78.46.194.186; +# interval-range 2; +# peer 78.44.194.186; +# peer 172.44.194.186 key 10000 version 3 prefer; ## SECRET-DATA +# server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA +# server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA +# broadcast 172.16.255.255 routing-instance-name rt1 key 50 version 3 ttl 200; +# broadcast 192.16.255.255 routing-instance-name rt2 key 50 version 3 ttl 200; +# broadcast-client; +# multicast-client 224.0.0.1; +# trusted-key [ 3000 2000 ]; +# threshold 300 action accept; +# source-address 172.45.194.186 routing-instance rt1; +# source-address 171.45.194.186 routing-instance rt2; + +- name: Replaced running ntp global configuration with provided configuration + junipernetworks.junos.junos_ntp_global: + config: + authentication_keys: + - id: 2 + algorithm: 'md5' + key: 'asdfghd' + - id: 5 + algorithm: 'sha1' + key: 'aasdad' + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: 'rt1' + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + state: replaced +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "authentication_keys": [ +# { +# "algorithm": "md5", +# "id": 2, +# "key": "$9$03aAB1hreW7NbO1rvMLVbgoJ" +# }, +# { +# "algorithm": "sha1", +# "id": 5, +# "key": "$9$DXiHmf5F/A0ZUjq.P3n" +# } +# ], +# "servers": [ +# { +# "key_id": 34, +# "prefer": true, +# "routing_instance": "rt1", +# "server": "48.46.194.186", +# "version": 2 +# }, +# { +# "key_id": 34, +# "prefer": true, +# "server": "48.45.194.186", +# "version": 2 +# } +# ] +# }, +# "before": { +# "boot_server": "78.46.194.186", +# "broadcast_client": true, +# "broadcasts": [ +# { +# "address": "172.16.255.255", +# "key": "50", +# "routing_instance_name": "rt1", +# "ttl": 200, +# "version": 3 +# }, +# { +# "address": "192.16.255.255", +# "key": "50", +# "routing_instance_name": "rt2", +# "ttl": 200, +# "version": 3 +# } +# ], +# "interval_range": 2, +# "multicast_client": "224.0.0.1", +# "peers": [ +# { +# "peer": "78.44.194.186" +# }, +# { +# "key_id": 10000, +# "peer": "172.44.194.186", +# "prefer": true, +# "version": 3 +# } +# ], +# "servers": [ +# { +# "key_id": 34, +# "prefer": true, +# "routing_instance": "rt1", +# "server": "48.46.194.186", +# "version": 2 +# }, +# { +# "key_id": 34, +# "prefer": true, +# "server": "48.45.194.186", +# "version": 2 +# } +# ], +# "source_addresses": [ +# { +# "routing_instance": "rt1", +# "source_address": "172.45.194.186" +# }, +# { +# "routing_instance": "rt2", +# "source_address": "171.45.194.186" +# } +# ], +# "threshold": { +# "action": "accept", +# "value": 300 +# }, +# "trusted_keys": [ +# {"key_id": 2000}, +# {"key_id": 3000} +# ] +# }, +# "changed": true, +# "commands": [ +# " +# "2md5 +# "asdfghd5 +# "sha1aasdad +# "48.46.194.18634rt1 +# "248.45.194.186 +# "342" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show system ntp +# authentication-key 2 type md5 value "$9$03aAB1hreW7NbO1rvMLVbgoJ"; ## SECRET-DATA +# authentication-key 5 type sha1 value "$9$DXiHmf5F/A0ZUjq.P3n"; ## SECRET-DATA +# server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA +# server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA + +# Using overridden +# +# Before state +# ------------ +# +# vagrant@vsrx# show system ntp +# boot-server 78.46.194.186; +# interval-range 2; +# peer 78.44.194.186; +# peer 172.44.194.186 key 10000 version 3 prefer; ## SECRET-DATA +# server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA +# server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA +# broadcast 172.16.255.255 routing-instance-name rt1 key 50 version 3 ttl 200; +# broadcast 192.16.255.255 routing-instance-name rt2 key 50 version 3 ttl 200; +# broadcast-client; +# multicast-client 224.0.0.1; +# trusted-key [ 3000 2000 ]; +# threshold 300 action accept; +# source-address 172.45.194.186 routing-instance rt1; +# source-address 171.45.194.186 routing-instance rt2; + +- name: Override running ntp global configuration with provided configuration + junipernetworks.junos.junos_ntp_global: + config: + authentication_keys: + - id: 2 + algorithm: 'md5' + key: 'asdfghd' + - id: 5 + algorithm: 'sha1' + key: 'aasdad' + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: 'rt1' + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + state: overridden +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "authentication_keys": [ +# { +# "algorithm": "md5", +# "id": 2, +# "key": "$9$03aAB1hreW7NbO1rvMLVbgoJ" +# }, +# { +# "algorithm": "sha1", +# "id": 5, +# "key": "$9$DXiHmf5F/A0ZUjq.P3n" +# } +# ], +# "servers": [ +# { +# "key_id": 34, +# "prefer": true, +# "routing_instance": "rt1", +# "server": "48.46.194.186", +# "version": 2 +# }, +# { +# "key_id": 34, +# "prefer": true, +# "server": "48.45.194.186", +# "version": 2 +# } +# ] +# }, +# "before": { +# "boot_server": "78.46.194.186", +# "broadcast_client": true, +# "broadcasts": [ +# { +# "address": "172.16.255.255", +# "key": "50", +# "routing_instance_name": "rt1", +# "ttl": 200, +# "version": 3 +# }, +# { +# "address": "192.16.255.255", +# "key": "50", +# "routing_instance_name": "rt2", +# "ttl": 200, +# "version": 3 +# } +# ], +# "interval_range": 2, +# "multicast_client": "224.0.0.1", +# "peers": [ +# { +# "peer": "78.44.194.186" +# }, +# { +# "key_id": 10000, +# "peer": "172.44.194.186", +# "prefer": true, +# "version": 3 +# } +# ], +# "servers": [ +# { +# "key_id": 34, +# "prefer": true, +# "routing_instance": "rt1", +# "server": "48.46.194.186", +# "version": 2 +# }, +# { +# "key_id": 34, +# "prefer": true, +# "server": "48.45.194.186", +# "version": 2 +# } +# ], +# "source_addresses": [ +# { +# "routing_instance": "rt1", +# "source_address": "172.45.194.186" +# }, +# { +# "routing_instance": "rt2", +# "source_address": "171.45.194.186" +# } +# ], +# "threshold": { +# "action": "accept", +# "value": 300 +# }, +# "trusted_keys": [ +# {"key_id": 2000}, +# {"key_id": 3000} +# ] +# }, +# "changed": true, +# "commands": [ +# " +# "2md5 +# "asdfghd5 +# "sha1aasdad +# "48.46.194.18634rt1 +# "248.45.194.186 +# "342" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show system ntp +# authentication-key 2 type md5 value "$9$03aAB1hreW7NbO1rvMLVbgoJ"; ## SECRET-DATA +# authentication-key 5 type sha1 value "$9$DXiHmf5F/A0ZUjq.P3n"; ## SECRET-DATA +# server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA +# server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA +# +# Using deleted +# +# Before state +# ------------ +# +# vagrant@vsrx# show system ntp +# authentication-key 2 type md5 value "$9$03aAB1hreW7NbO1rvMLVbgoJ"; ## SECRET-DATA +# authentication-key 5 type sha1 value "$9$DXiHmf5F/A0ZUjq.P3n"; ## SECRET-DATA +# server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA +# server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA +# +- name: Delete running NTP global configuration + junipernetworks.junos.junos_ntp_global: + config: + state: deleted +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": {}, +# "before": { +# "authentication_keys": [ +# { +# "algorithm": "md5", +# "id": 2, +# "key": "$9$03aAB1hreW7NbO1rvMLVbgoJ" +# }, +# { +# "algorithm": "sha1", +# "id": 5, +# "key": "$9$DXiHmf5F/A0ZUjq.P3n" +# } +# ], +# "servers": [ +# { +# "key_id": 34, +# "prefer": true, +# "routing_instance": "rt1", +# "server": "48.46.194.186", +# "version": 2 +# }, +# { +# "key_id": 34, +# "prefer": true, +# "server": "48.45.194.186", +# "version": 2 +# } +# ] +# }, +# "changed": true, +# "commands": [ +# "" +# "" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show system ntp +# +# [edit] +# Using gathered +# +# Before state +# ------------ +# +# vagrant@vsrx# show system ntp +# boot-server 78.46.194.186; +# interval-range 2; +# peer 78.44.194.186; +# peer 172.44.194.186 key 10000 version 3 prefer; ## SECRET-DATA +# server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA +# server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA +# broadcast 172.16.255.255 routing-instance-name rt1 key 50 version 3 ttl 200; +# broadcast 192.16.255.255 routing-instance-name rt2 key 50 version 3 ttl 200; +# broadcast-client; +# multicast-client 224.0.0.1; +# trusted-key [ 3000 2000 ]; +# threshold 300 action accept; +# source-address 172.45.194.186 routing-instance rt1; +# source-address 171.45.194.186 routing-instance rt2; +- name: Gather running NTP global configuration + junipernetworks.junos.junos_ntp_global: + state: gathered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "gathered": { +# "boot_server": "78.46.194.186", +# "broadcast_client": true, +# "broadcasts": [ +# { +# "address": "172.16.255.255", +# "key": "50", +# "routing_instance_name": "rt1", +# "ttl": 200, +# "version": 3 +# }, +# { +# "address": "192.16.255.255", +# "key": "50", +# "routing_instance_name": "rt2", +# "ttl": 200, +# "version": 3 +# } +# ], +# "interval_range": 2, +# "multicast_client": "224.0.0.1", +# "peers": [ +# { +# "peer": "78.44.194.186" +# }, +# { +# "key_id": 10000, +# "peer": "172.44.194.186", +# "prefer": true, +# "version": 3 +# } +# ], +# "servers": [ +# { +# "key_id": 34, +# "prefer": true, +# "routing_instance": "rt1", +# "server": "48.46.194.186", +# "version": 2 +# }, +# { +# "key_id": 34, +# "prefer": true, +# "server": "48.45.194.186", +# "version": 2 +# } +# ], +# "source_addresses": [ +# { +# "routing_instance": "rt1", +# "source_address": "172.45.194.186" +# }, +# { +# "routing_instance": "rt2", +# "source_address": "171.45.194.186" +# } +# ], +# "threshold": { +# "action": "accept", +# "value": 300 +# }, +# "trusted_keys": [ +# {"key_id": 2000}, +# {"key_id": 3000} +# ] +# }, +# "changed": false, +# Using rendered +# +# Before state +# ------------ +# +- name: Render xml for provided facts. + junipernetworks.junos.junos_ntp_global: + config: + boot_server: '78.46.194.186' + broadcasts: + - address: '172.16.255.255' + key: '50' + ttl: 200 + version: 3 + routing_instance_name: 'rt1' + - address: '192.16.255.255' + key: '50' + ttl: 200 + version: 3 + routing_instance_name: 'rt2' + broadcast_client: true + interval_range: 2 + multicast_client: "224.0.0.1" + peers: + - peer: "78.44.194.186" + - peer: "172.44.194.186" + key_id: 10000 + prefer: true + version: 3 + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: 'rt1' + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + source_addresses: + - source_address: "172.45.194.186" + routing_instance: 'rt1' + - source_address: "171.45.194.186" + routing_instance: 'rt2' + threshold: + value: 300 + action: "accept" + trusted_keys: + - 3000 + - 2000 + state: rendered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "rendered": [ +# "" +# "78.46.194.186172.16.255.255" +# "50rt1200" +# "3192.16.255.255" +# "50rt2" +# "2003" +# "2224.0.0.1" +# "78.44.194.186172.44.194.186" +# "100003" +# "48.46.194.18634rt1" +# "248.45.194.186" +# "342" +# "172.45.194.186rt1" +# "171.45.194.186rt2" +# "300accept" +# "30002000" +# ] +# +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# +# +# 2 +# md5 +# $9$GxDjqfT3CA0UjfzF6u0RhS +# +# +# 5 +# sha1 +# $9$ZsUDk.mT3/toJGiHqQz +# +# +# +# +# +# +- name: Parse NTP global running config + junipernetworks.junos.junos_ntp_global: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "parsed": { +# "authentication_keys": [ +# { +# "algorithm": "md5", +# "id": 2, +# "key": "$9$GxDjqfT3CA0UjfzF6u0RhS" +# }, +# { +# "algorithm": "sha1", +# "id": 5, +# "key": "$9$ZsUDk.mT3/toJGiHqQz" +# } +# ] +# } +# +# +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: dict +after: + description: The resulting configuration model invocation. + returned: when changed + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: dict +commands: + description: The set of commands pushed to the remote device. + returned: always + type: list + sample: ["78.44.194.186172.44.194.186", + 'xml 2', 'xml 3'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.ntp_global.ntp_global import ( + Ntp_globalArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.ntp_global.ntp_global import ( + Ntp_global, +) + + +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",)), + ] + module = AnsibleModule( + argument_spec=Ntp_globalArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + + result = Ntp_global(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_ospf_interfaces.py b/ansible_collections/juniper/device/plugins/modules/junos_ospf_interfaces.py new file mode 100644 index 00000000..eb4500cb --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_ospf_interfaces.py @@ -0,0 +1,612 @@ +#!/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 junos_ospf_interfaces +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +ANSIBLE_METADATA = { + "metadata_version": "1.1", + "status": ["preview"], + "supported_by": "network", +} + +DOCUMENTATION = """ +--- +module: junos_ospf_interfaces +version_added: 1.3.0 +short_description: OSPF Interfaces Resource Module. +description: + - This module manages OSPF(v2/v3) configuration of interfaces on devices running Juniper JUNOS. +author: Rohit Thakur (@rohitthakur2590) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). + - Tested against JunOS v18.4R1 +options: + config: + description: A list of OSPF configuration for interfaces. + type: list + elements: dict + suboptions: + router_id: + description: + - The OSPF router id. + type: str + name: + description: + - Name/Identifier of the interface. + type: str + required: True + address_family: + description: + - OSPF settings on the interfaces in address-family context. + type: list + elements: dict + suboptions: + afi: + description: + - Address Family Identifier (AFI) for OSPF settings on the interfaces. + type: str + choices: ['ipv4', 'ipv6'] + required: True + processes: + description: + - Interfaces configuration for an OSPF process. + type: dict + suboptions: + area: + description: Specify the area-id + type: dict + suboptions: + area_id: + description: Specify area id. + type: str + authentication: + description: Specify authentication type + type: dict + suboptions: + simple_password: + description: + - Specify password for authentication. + type: str + md5: + description: + - Specify md5 based authentication. + type: list + elements: dict + suboptions: + key_id: + description: Specify md5 key-id + type: int + key_value: + description: Specify key value + type: str + start_time: + description: Specify start time for key transmission + type: str + interface_type: + description: Specify type of interface + type: str + choices: ["nbma", "p2mp", "p2p"] + bandwidth_based_metrics: + description: Specify list of bandwidth based metrics + type: list + elements: dict + suboptions: + bandwidth: + description: + - BW to apply metric to. + type: str + choices: [1g, 10g] + metric: + description: Specify metric + type: int + priority: + description: + - Priority for the interface. + type: int + passive: + description: + - Do not run OSPF, but advertise it. + type: bool + metric: + description: + - Metric applied to the interface. + type: int + te_metric: + description: + - Traffic engineering metric applied to the interface. + type: int + mtu: + description: + - Maximum OSPF packet size + type: int + ipsec_sa: + description: + - IPSec security association name + type: str + secondary: + description: + - Treat interface as secondary + type: bool + flood_reduction: + description: + - Enable flood reduction. + type: bool + demand_circuit: + description: + - Interface functions as a demand circuit. + type: bool + no_advertise_adjacency_segment: + description: + - Do not advertise an adjacency segment for this interface. + type: bool + no_eligible_backup: + description: + - Not eligible to backup traffic from protected interfaces. + type: bool + no_eligible_remote_backup: + description: + - Not eligible for Remote-LFA backup traffic from protected interfaces. + type: bool + no_interface_state_traps: + description: + - Do not send interface state change traps. + type: bool + no_neighbor_down_notification: + description: + - Don't inform other protocols about neighbor down events. + type: bool + node_link_protection: + description: + - Protect interface from both link and node faults. + type: bool + dead_interval: + description: + - Dead interval (seconds). + type: int + hello_interval: + description: + - Hello interval (seconds). + type: int + poll_interval: + description: + - Poll interval (seconds). + type: int + retransmit_interval: + description: + - Retransmit interval (seconds). + type: int + transit_delay: + description: + - Transit delay (seconds). + type: int + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show protocols ospf). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + description: + - The state the configuration should be left in. + type: str + choices: + - merged + - replaced + - overridden + - deleted + - parsed + - gathered + - rendered + default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# admin# show protocols ospf + +- name: Merge Junos OSPF interfaces config + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: 'ge-0/0/2.0' + address_family: + - afi: 'ipv4' + processes: + area: + area_id: '0.0.0.2' + priority: 3 + metric: 5 + state: merged + +# After state +# ----------- +# +# admin# show protocols ospf +# area 0.0.0.2 { +# interface ge-0/0/2.0 { +# metric 5; +# priority 3; +# } +# } + +# Using replaced +# +# Before state +# ------------ +# +# admin# show protocols ospf +# area 0.0.0.2 { +# interface ge-0/0/2.0 { +# metric 5; +# priority 3; +# } +# } +- name: Replace Junos OSPF interfaces config + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: 'ge-0/0/2.0' + address_family: + - afi: 'ipv4' + processes: + area: + area_id: '0.0.0.1' + priority: 6 + metric: 6 + state: replaced + +# After state +# ----------- +# +# admin# show protocols ospf +# area 0.0.0.1 { +# interface ge-0/0/2.0 { +# metric 6; +# priority 6; +# } +# } + +# Using overridden +# +# Before state +# ------------ +# +# admin# show protocols ospf +# area 0.0.0.3 { +# interface ge-0/0/3.0 { +# metric 5; +# priority 3; +# } +# } +# area 0.0.0.2 { +# interface ge-0/0/2.0 { +# metric 5; +# priority 3; +# } +# } + +- name: Override Junos OSPF interfaces config + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: 'ge-0/0/1.0' + address_family: + - afi: 'ipv4' + processes: + area: + area_id: '0.0.0.1' + priority: 3 + metric: 5 + state: overridden + +# After state +# ----------- +# +# admin# show protocols ospf +# area 0.0.0.1 { +# interface ge-0/0/1.0 { +# metric 5; +# priority 3; +# } +# } + +# +# Using deleted +# +# Before state +# ------------ +# +# admin# show protocols ospf +# area 0.0.0.1 { +# interface ge-0/0/1.0 { +# metric 5; +# priority 3; +# } +# } + +- name: Delete Junos OSPF interfaces config + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: 'ge-0/0/1.0' + state: deleted + +# After state +# ----------- +# +# admin# show protocols ospf +# Using gathered +# +# Before state +# ------------ +# +# admin# show protocols ospf +# area 0.0.0.3 { +# interface ge-0/0/3.0 { +# metric 5; +# priority 3; +# } +# } +# area 0.0.0.2 { +# interface ge-0/0/2.0 { +# metric 5; +# priority 3; +# } +# } + +- name: Gather Junos OSPF interfaces config + junipernetworks.junos.junos_ospf_interfaces: + config: + state: gathered +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# "gathered": [ +# { +# "address_family": [ +# { +# "afi": "ipv4", +# "processes": { +# "area": { +# "area_id": "0.0.0.3" +# }, +# "metric": 5, +# "priority": 3 +# } +# } +# ], +# "name": "ge-0/0/3.0", +# }, +# { +# "address_family": [ +# { +# "afi": "ipv4", +# "processes": { +# "area": { +# "area_id": "0.0.0.2" +# }, +# "metric": 5, +# "priority": 3 +# } +# } +# ], +# "name": "ge-0/0/2.0", +# } +# ] +# +# Using rendered +# +# +- name: Render the commands for provided configuration + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: 'ge-0/0/2.0' + address_family: + - afi: 'ipv4' + processes: + area: + area_id: '0.0.0.2' + priority: 3 + metric: 5 + state: rendered + +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "rendered": " +# +# +# +# 0.0.0.2 +# +# ge-0/0/2.0 +# 3 +# 5 +# +# +# +# " +# +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# +# +# +# 0.0.0.2 +# +# 200 +# +# +# ge-0/0/2.0 +# 5 +# 3 +# +# +# +# +# +# 10.200.16.75 +# +# +# + + +- name: Parsed the device configuration to get output commands + junipernetworks.junos.junos_ospf_interfaces: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "parsed": [ +# { +# "address_family": [ +# { +# "afi": "ipv4", +# "processes": { +# "area": { +# "area_id": "0.0.0.2" +# }, +# "metric": 5, +# "priority": 3 +# } +# } +# ], +# "name": "ge-0/0/2.0", +# } +# ] +# +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + type: dict + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration model invocation. + 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: [' + + + 0.0.0.3 + + ge-0/0/3.0 + 3 + 5 + + + + 0.0.0.2 + + ge-0/0/2.0 + 3 + 5 + + + +", + " + + 10.200.16.75 + 10.200.16.75 +', 'xml 2', 'xml 3'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.ospf_interfaces.ospf_interfaces import ( + Ospf_interfacesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.ospf_interfaces.ospf_interfaces import ( + Ospf_interfaces, +) + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + required_if = [ + ("state", "merged", ("config",)), + ("state", "replaced", ("config",)), + ("state", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_config",)), + ] + module = AnsibleModule( + argument_spec=Ospf_interfacesArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + result = Ospf_interfaces(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_ospfv2.py b/ansible_collections/juniper/device/plugins/modules/junos_ospfv2.py new file mode 100644 index 00000000..e8903786 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_ospfv2.py @@ -0,0 +1,1173 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2020 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 junos_ospfv2 +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_ospfv2 +short_description: OSPFv2 resource module +description: +- This module manages OSPFv2 configuration on devices running Juniper JUNOS. +version_added: 1.0.0 +author: +- Daniel Mellado (@dmellado) +- Rohit Thakur (@rohitthakur2590) +requirements: +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) +notes: +- This module requires the netconf system service be enabled on the device being managed. +- This module works with connection C(netconf). +- See L(the Junos OS Platform Options,https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html). +- Tested against JunOS v18.4R1 +options: + config: + description: A list of OSPFv2 process configuration. + type: list + elements: dict + suboptions: + router_id: + description: + - The OSPFv2 router id. + type: str + areas: + description: + - A list of OSPFv2 areas' configuration. + type: list + elements: dict + suboptions: + area_id: + description: + - The Area ID as an integer or IP Address. + type: str + required: true + area_range: + description: + - Configure an address range for the area. + - Included for compatibility, remove/deprecate after 2025-07-01. + - Alternate for this would be area_ranges which is a list. + type: str + area_ranges: + description: + - Configure IP address ranges for the area. + type: list + elements: dict + suboptions: + address: + description: + - Specify ip address. + type: str + exact: + description: + - Enforce exact match for advertisement of this area range. + type: bool + restrict: + description: + - Restrict advertisement of this area range. + type: bool + override_metric: + description: + - Override the dynamic metric for this area-range. + type: int + stub: + description: + - Settings for configuring the area as a stub. + type: dict + suboptions: + default_metric: + description: + - Metric for the default route in this area. + type: int + set: + description: + - Configure the area as a stub. + type: bool + interfaces: + description: + - List of interfaces in this area. + type: list + elements: dict + suboptions: + authentication: + description: Specify authentication type + type: dict + suboptions: + type: + description: + - Type of authentication to use. + - Included for compatibility, remove/deprecate after 2025-07-01. + type: dict + password: + description: Specify authentication key. + type: str + md5: + description: MD5 authentication keys + type: list + elements: dict + suboptions: + key_id: + description: Specify the key identity + type: int + key: + description: Specify key value + type: str + start_time: + description: Specify Start time for key transmission (YYYY-MM-DD.HH:MM) + type: str + + bandwidth_based_metrics: + description: Specify list of bandwidth based metrics + type: list + elements: dict + suboptions: + bandwidth: + description: + - BW to apply metric to. + type: str + choices: [1g, 10g] + metric: + description: Specify metric + type: int + name: + description: + - Name of the interface. + type: str + required: true + priority: + description: + - Priority for the interface. + type: int + metric: + description: + - Metric applied to the interface. + type: int + flood_reduction: + description: + - Enable flood reduction. + type: bool + passive: + description: Specify passive + type: bool + timers: + description: Specify timers + type: dict + suboptions: + dead_interval: + description: + - Dead interval (seconds). + type: int + hello_interval: + description: + - Hello interval (seconds). + type: int + poll_interval: + description: + - Poll interval (seconds). + type: int + retransmit_interval: + description: + - Retransmit interval (seconds). + type: int + transit_delay: + description: + - Transit delay (seconds). + type: int + external_preference: + description: + - Preference of external routes. + type: int + overload: + description: Specify time for overload mode reset + type: dict + suboptions: + allow_route_leaking: + description: Allow routes to be leaked when overload is configured. + type: bool + as_external: + description: Advertise As External with maximum usable metric. + type: bool + stub_network: + description: Advertise Stub Network with maximum metric. + type: bool + timeout: + description: + - Time after which overload mode is reset (seconds). + type: int + preference: + description: + - Preference of internal routes. + type: int + prefix_export_limit: + description: + - Maximum number of external prefixes that can be exported. + type: int + reference_bandwidth: + description: + - Bandwidth for calculating metric defaults. + type: str + choices: [1g, 10g] + rfc1583compatibility: + description: + - Set RFC1583 compatibility + type: bool + spf_options: + description: + - Configure options for SPF. + type: dict + suboptions: + delay: + description: + - Time to wait before running an SPF (seconds). + type: int + holddown: + description: + - Time to hold down before running an SPF (seconds). + type: int + rapid_runs: + description: + - Number of maximum rapid SPF runs before holddown (seconds). + type: int + no_ignore_our_externals: + description: Do not ignore self-generated external and NSSA LSAs. + type: bool + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show protocols ospf). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + description: + - The state the configuration should be left in. + type: str + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - rendered + - parsed + default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# admin# show protocols ospf + +- name: Merge provided OSPFv2 configuration into running config. + junipernetworks.junos.junos_ospfv2: + config: + - reference_bandwidth: 10g + areas: + - area_id: 0.0.0.100 + area_ranges: + - address: 10.200.17.0/24 + exact: true + restrict: true + override_metric: 2000 + - address: 10.200.15.0/24 + exact: true + restrict: true + override_metric: 2000 + stub: + default_metric: 100 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: false + passive: true + bandwidth_based_metrics: + - bandwidth: 1g + metric: 5 + - bandwidth: 10g + metric: 40 + timers: + dead_interval: 4 + hello_interval: 2 + poll_interval: 2 + retransmit_interval: 2 + rfc1583compatibility: false + state: merged + +# Task Output: +# ------------ +# +# before: [] +# +# commands: +# - +# 10g +# 0.0.0.10010.200.17.0/24 +# 2000 +# 10.200.15.0/242000 +# so-0/0/0.03 +# 51g +# 510g40 +# 4 +# 22 +# 2 +# 100 +# +# after: +# - areas: +# - area_id: 0.0.0.100 +# area_range: '[''10.200.17.0/24'', ''10.200.15.0/24'']' +# area_ranges: +# - address: 10.200.17.0/24 +# exact: true +# override_metric: 2000 +# restrict: true +# - address: 10.200.15.0/24 +# exact: true +# override_metric: 2000 +# restrict: true +# interfaces: +# - bandwidth_based_metrics: +# - bandwidth: 1g +# metric: 5 +# - bandwidth: 10g +# metric: 40 +# metric: 5 +# name: so-0/0/0.0 +# passive: true +# priority: 3 +# timers: +# dead_interval: 4 +# hello_interval: 2 +# poll_interval: 2 +# retransmit_interval: 2 +# stub: +# default_metric: 100 +# set: true +# reference_bandwidth: 10g +# rfc1583compatibility: false + +# After state +# ----------- +# +# admin# show protocols ospf +# reference-bandwidth 10g; +# no-rfc-1583; +# area 0.0.0.100 { +# stub default-metric 100; +# area-range 10.200.17.0/24 { +# restrict; +# exact; +# override-metric 2000; +# } +# area-range 10.200.15.0/24 { +# restrict; +# exact; +# override-metric 2000; +# } +# interface so-0/0/0.0 { +# passive; +# bandwidth-based-metrics { +# bandwidth 1g metric 5; +# bandwidth 10g metric 40; +# } +# metric 5; +# priority 3; +# retransmit-interval 2; +# hello-interval 2; +# dead-interval 4; +# poll-interval 2; +# } +# } +# +# Using replaced +# +# Before state +# ------------ +# +# admin# show protocols ospf +# reference-bandwidth 10g; +# no-rfc-1583; +# area 0.0.0.100 { +# stub default-metric 100; +# area-range 10.200.17.0/24 { +# restrict; +# exact; +# override-metric 2000; +# } +# area-range 10.200.15.0/24 { +# restrict; +# exact; +# override-metric 2000; +# } +# interface so-0/0/0.0 { +# passive; +# bandwidth-based-metrics { +# bandwidth 1g metric 5; +# bandwidth 10g metric 40; +# } +# metric 5; +# priority 3; +# retransmit-interval 2; +# hello-interval 2; +# dead-interval 4; +# poll-interval 2; +# } +# } + +- name: Replace existing Junos OSPFv2 config with provided config + junipernetworks.junos.junos_ospfv2: + config: + - reference_bandwidth: 10g + areas: + - area_id: 0.0.0.100 + area_ranges: + - address: 10.200.17.0/24 + exact: true + restrict: true + - address: 10.200.16.0/24 + exact: true + restrict: true + override_metric: 1000 + stub: + default_metric: 100 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: false + passive: true + bandwidth_based_metrics: + - bandwidth: 1g + metric: 5 + - bandwidth: 10g + metric: 40 + timers: + dead_interval: 4 + hello_interval: 2 + poll_interval: 2 + retransmit_interval: 2 + rfc1583compatibility: false + state: replacedd + +# Task Output: +# ------------ +# +# before: +# - areas: +# - area_id: 0.0.0.100 +# area_range: '[''10.200.17.0/24'', ''10.200.15.0/24'']' +# area_ranges: +# - address: 10.200.17.0/24 +# exact: true +# override_metric: 2000 +# restrict: true +# - address: 10.200.15.0/24 +# exact: true +# override_metric: 2000 +# restrict: true +# interfaces: +# - bandwidth_based_metrics: +# - bandwidth: 1g +# metric: 5 +# - bandwidth: 10g +# metric: 40 +# metric: 5 +# name: so-0/0/0.0 +# passive: true +# priority: 3 +# timers: +# dead_interval: 4 +# hello_interval: 2 +# poll_interval: 2 +# retransmit_interval: 2 +# stub: +# default_metric: 100 +# set: true +# reference_bandwidth: 10g +# rfc1583compatibility: false +# +# commands: +# - +# 0.0.0.100 +# 10g +# 0.0.0.10010.200.17.0/24 +# 10.200.16.0/24 +# 1000 +# so-0/0/0.035 +# 1g5 +# 10g40 +# 42 +# 22 +# 100 +# +# after: +# - areas: +# - area_id: 0.0.0.100 +# area_range: '[''10.200.17.0/24'', ''10.200.16.0/24'']' +# area_ranges: +# - address: 10.200.17.0/24 +# exact: true +# restrict: true +# - address: 10.200.16.0/24 +# exact: true +# override_metric: 1000 +# restrict: true +# interfaces: +# - bandwidth_based_metrics: +# - bandwidth: 1g +# metric: 5 +# - bandwidth: 10g +# metric: 40 +# metric: 5 +# name: so-0/0/0.0 +# passive: true +# priority: 3 +# timers: +# dead_interval: 4 +# hello_interval: 2 +# poll_interval: 2 +# retransmit_interval: 2 +# stub: +# default_metric: 100 +# set: true +# reference_bandwidth: 10g +# rfc1583compatibility: false +# +# After state +# ----------- +# +# admin# show protocols ospf +# reference-bandwidth 10g; +# no-rfc-1583; +# area 0.0.0.100 { +# stub default-metric 100; +# area-range 10.200.17.0/24 { +# restrict; +# exact; +# } +# area-range 10.200.16.0/24 { +# restrict; +# exact; +# override-metric 1000; +# } +# interface so-0/0/0.0 { +# passive; +# bandwidth-based-metrics { +# bandwidth 1g metric 5; +# bandwidth 10g metric 40; +# } +# metric 5; +# priority 3; +# retransmit-interval 2; +# hello-interval 2; +# dead-interval 4; +# poll-interval 2; +# } +# } +# +# Using overridden +# +# Before state +# ------------ +# +# admin# show protocols ospf +# reference-bandwidth 10g; +# no-rfc-1583; +# area 0.0.0.100 { +# stub default-metric 100; +# area-range 10.200.17.0/24 { +# restrict; +# exact; +# } +# area-range 10.200.16.0/24 { +# restrict; +# exact; +# override-metric 1000; +# } +# interface so-0/0/0.0 { +# passive; +# bandwidth-based-metrics { +# bandwidth 1g metric 5; +# bandwidth 10g metric 40; +# } +# metric 5; +# priority 3; +# retransmit-interval 2; +# hello-interval 2; +# dead-interval 4; +# poll-interval 2; +# } +# } + +- name: Override runnig OSPFv2 config with provided config + junipernetworks.junos.junos_ospfv2: + config: + - reference_bandwidth: 10g + areas: + - area_id: 0.0.0.110 + area_ranges: + - address: 20.200.17.0/24 + exact: true + restrict: true + override_metric: 2000 + - address: 20.200.15.0/24 + exact: true + restrict: true + override_metric: 2000 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: false + passive: true + bandwidth_based_metrics: + - bandwidth: 1g + metric: 5 + - bandwidth: 10g + metric: 40 + state: overridden + +# Task Output: +# ------------ +# +# before: +# - areas: +# - area_id: 0.0.0.100 +# area_range: '[''10.200.17.0/24'', ''10.200.16.0/24'']' +# area_ranges: +# - address: 10.200.17.0/24 +# exact: true +# restrict: true +# - address: 10.200.16.0/24 +# exact: true +# override_metric: 1000 +# restrict: true +# interfaces: +# - bandwidth_based_metrics: +# - bandwidth: 1g +# metric: 5 +# - bandwidth: 10g +# metric: 40 +# metric: 5 +# name: so-0/0/0.0 +# passive: true +# priority: 3 +# timers: +# dead_interval: 4 +# hello_interval: 2 +# poll_interval: 2 +# retransmit_interval: 2 +# stub: +# default_metric: 100 +# set: true +# reference_bandwidth: 10g +# rfc1583compatibility: false +# +# commands: +# - +# 0.0.0.100 +# 10g0.0.0.110 +# 20.200.17.0/24 +# 2000 +# 20.200.15.0/242000 +# so-0/0/0.03 +# 51g +# 510g40 +# +# 200 +# +# after: +# - areas: +# - area_id: 0.0.0.110 +# area_range: '[''20.200.17.0/24'', ''20.200.15.0/24'']' +# area_ranges: +# - address: 20.200.17.0/24 +# exact: true +# override_metric: 2000 +# restrict: true +# - address: 20.200.15.0/24 +# exact: true +# override_metric: 2000 +# restrict: true +# interfaces: +# - bandwidth_based_metrics: +# - bandwidth: 1g +# metric: 5 +# - bandwidth: 10g +# metric: 40 +# metric: 5 +# name: so-0/0/0.0 +# passive: true +# priority: 3 +# stub: +# default_metric: 200 +# set: true +# reference_bandwidth: 10g +# rfc1583compatibility: false + +# After state +# ----------- +# +# admin# show protocols ospf +# reference-bandwidth 10g; +# no-rfc-1583; +# area 0.0.0.110 { +# stub default-metric 200; +# area-range 20.200.17.0/24 { +# restrict; +# exact; +# override-metric 2000; +# } +# area-range 20.200.15.0/24 { +# restrict; +# exact; +# override-metric 2000; +# } +# interface so-0/0/0.0 { +# passive; +# bandwidth-based-metrics { +# bandwidth 1g metric 5; +# bandwidth 10g metric 40; +# } +# metric 5; +# priority 3; +# } +# } +# Using deleted +# +# Before state +# ------------ +# +# admin# show protocols ospf +# reference-bandwidth 10g; +# no-rfc-1583; +# area 0.0.0.110 { +# stub default-metric 200; +# area-range 20.200.17.0/24 { +# restrict; +# exact; +# override-metric 2000; +# } +# area-range 20.200.15.0/24 { +# restrict; +# exact; +# override-metric 2000; +# } +# interface so-0/0/0.0 { +# passive; +# bandwidth-based-metrics { +# bandwidth 1g metric 5; +# bandwidth 10g metric 40; +# } +# metric 5; +# priority 3; +# } +# } + +- name: Delete OSPFv2 running config. + junipernetworks.junos.junos_ospfv2: + config: + state: deleted + +# Task Output: +# ------------ +# +# before: +# - areas: +# - area_id: 0.0.0.110 +# area_range: '[''20.200.17.0/24'', ''20.200.15.0/24'']' +# area_ranges: +# - address: 20.200.17.0/24 +# exact: true +# override_metric: 2000 +# restrict: true +# - address: 20.200.15.0/24 +# exact: true +# override_metric: 2000 +# restrict: true +# interfaces: +# - bandwidth_based_metrics: +# - bandwidth: 1g +# metric: 5 +# - bandwidth: 10g +# metric: 40 +# metric: 5 +# name: so-0/0/0.0 +# passive: true +# priority: 3 +# stub: +# default_metric: 200 +# set: true +# reference_bandwidth: 10g +# rfc1583compatibility: false +# +# commands: +# - +# 0.0.0.100 +# +# +# after: [] +# +# +# After state +# ----------- +# +# admin# show protocols ospf + +# Using gathered +# +# Before state +# ------------ +# +# admin# show protocols ospf +# reference-bandwidth 10g; +# no-rfc-1583; +# area 0.0.0.100 { +# stub default-metric 100; +# area-range 10.200.17.0/24 { +# restrict; +# exact; +# override-metric 2000; +# } +# area-range 10.200.15.0/24 { +# restrict; +# exact; +# override-metric 2000; +# } +# interface so-0/0/0.0 { +# passive; +# bandwidth-based-metrics { +# bandwidth 1g metric 5; +# bandwidth 10g metric 40; +# } +# metric 5; +# priority 3; +# retransmit-interval 2; +# hello-interval 2; +# dead-interval 4; +# poll-interval 2; +# } +# } + +- name: Gather Junos OSPFv2 running-configuration + junipernetworks.junos.junos_ospfv2: + config: + state: gathered +# +# +# Task Output: +# ------------ +# +# gathered: +# +# - areas: +# - area_id: 0.0.0.100 +# area_range: '[''10.200.17.0/24'', ''10.200.15.0/24'']' +# area_ranges: +# - address: 10.200.17.0/24 +# exact: true +# override_metric: 2000 +# restrict: true +# - address: 10.200.15.0/24 +# exact: true +# override_metric: 2000 +# restrict: true +# interfaces: +# - bandwidth_based_metrics: +# - bandwidth: 1g +# metric: 5 +# - bandwidth: 10g +# metric: 40 +# metric: 5 +# name: so-0/0/0.0 +# passive: true +# priority: 3 +# timers: +# dead_interval: 4 +# hello_interval: 2 +# poll_interval: 2 +# retransmit_interval: 2 +# stub: +# default_metric: 100 +# set: true +# reference_bandwidth: 10g +# rfc1583compatibility: false + +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# +# 10g +# +# +# 0.0.0.100 +# +# 100 +# +# +# 10.200.16.0/24 +# +# 10000 +# +# +# 10.200.11.0/24 +# +# +# +# +# so-0/0/0.0 +# +# +# +# +# 1g +# 5 +# +# +# 10g +# 40 +# +# +# 5 +# 3 +# 2 +# 2 +# 4 +# 2 +# +# +# +# +# +# +# +# 172.16.17.0/24 +# +# +# +# 10.200.16.75 +# +# 65432 +# +# +# +# + + +- name: Parsed the ospfv2 config into structured ansible resource facts. + junipernetworks.junos.junos_ospfv2: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# Task Output: +# ------------ +# +# parsed: +# - areas: +# - area_id: 0.0.0.100 +# area_range: '[''10.200.16.0/24'', ''10.200.11.0/24'']' +# area_ranges: +# - address: 10.200.16.0/24 +# exact: true +# override_metric: 10000 +# - address: 10.200.11.0/24 +# exact: true +# restrict: true +# interfaces: +# - bandwidth_based_metrics: +# - bandwidth: 1g +# metric: 5 +# - bandwidth: 10g +# metric: 40 +# metric: 5 +# name: so-0/0/0.0 +# passive: true +# priority: 3 +# timers: +# dead_interval: 4 +# hello_interval: 2 +# poll_interval: 2 +# retransmit_interval: 2 +# stub: +# default_metric: 100 +# set: true +# reference_bandwidth: 10g +# rfc1583compatibility: false +# router_id: 10.200.16.75 + +# Using rendered +# +- name: Render the commands for provided configuration + junipernetworks.junos.junos_ospfv2: + config: + - reference_bandwidth: 10g + areas: + - area_id: 0.0.0.100 + area_ranges: + - address: 10.200.17.0/24 + exact: true + restrict: true + override_metric: 2000 + - address: 10.200.15.0/24 + exact: true + restrict: true + override_metric: 2000 + stub: + default_metric: 100 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: false + passive: true + bandwidth_based_metrics: + - bandwidth: 1g + metric: 5 + - bandwidth: 10g + metric: 40 + timers: + dead_interval: 4 + hello_interval: 2 + poll_interval: 2 + retransmit_interval: 2 + rfc1583compatibility: false + state: rendered + +# Task Output: +# ------------ +# +# rendered: " +# 10g0.0.0.100 +# 10.200.17.0/242000 +# 10.200.15.0/24 +# 2000so-0/0/0.0 +# 35 +# 1g510g +# 404 +# 22 +# 2 +# 100" +""" +RETURN = """ +before: + description: The configuration prior to the module invocation. + returned: always + type: dict + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration module invocation. + 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: ['< + nc:ospf>0.0.0.100 + ', 'xml 2', 'xml 3'] +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - +gathered: + description: Facts about the network resource gathered from the remote device as structured data. + returned: when I(state) is C(gathered) + type: list + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. + returned: when I(state) is C(parsed) + type: list + sample: > + This output will always be in the same format as the + module argspec. +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.ospfv2.ospfv2 import ( + Ospfv2Args, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.ospfv2.ospfv2 import ( + Ospfv2, +) + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + required_if = [ + ("state", "merged", ("config",)), + ("state", "replaced", ("config",)), + ("state", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_config",)), + ] + module = AnsibleModule( + argument_spec=Ospfv2Args.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + result = Ospfv2(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_ospfv3.py b/ansible_collections/juniper/device/plugins/modules/junos_ospfv3.py new file mode 100644 index 00000000..6ad2bd46 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_ospfv3.py @@ -0,0 +1,753 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2020 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 junos_ospfv3 +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_ospfv3 +short_description: OSPFv3 resource module +description: +- This module manages global OSPFv3 configuration on devices running Juniper JUNOS. +version_added: 1.2.0 +author: Rohit Thakur (@rohitthakur2590) +requirements: +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) +notes: +- This module requires the netconf system service be enabled on the device being managed. +- This module works with connection C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +- Tested against JunOS v18.4R1 +options: + config: + description: A list of OSPFv3 process configuration. + type: list + elements: dict + suboptions: + router_id: + description: + - The OSPFv3 router id. + type: str + areas: + description: + - A list of OSPFv3 areas' configuration. + type: list + elements: dict + suboptions: + area_id: + description: + - The Area ID as an integer or IP Address. + type: str + required: true + area_range: + description: + - Configure an address range for the area. + type: str + stub: + description: + - Settings for configuring the area as a stub. + type: dict + suboptions: + default_metric: + description: + - Metric for the default route in this area. + type: int + set: + description: + - Configure the area as a stub. + type: bool + interfaces: + description: + - List of interfaces in this area. + type: list + elements: dict + suboptions: + authentication: + description: Specify authentication type + type: dict + suboptions: + type: + description: + - Type of authentication to use. + type: dict + bandwidth_based_metrics: + description: Specify list of bandwidth based metrics + type: list + elements: dict + suboptions: + bandwidth: + description: + - BW to apply metric to. + type: str + choices: [1g, 10g] + metric: + description: Specify metric + type: int + name: + description: + - Name of the interface. + type: str + required: true + priority: + description: + - Priority for the interface. + type: int + metric: + description: + - Metric applied to the interface. + type: int + flood_reduction: + description: + - Enable flood reduction. + type: bool + passive: + description: Specify passive + type: bool + timers: + description: Specify timers + type: dict + suboptions: + dead_interval: + description: + - Dead interval (seconds). + type: int + hello_interval: + description: + - Hello interval (seconds). + type: int + poll_interval: + description: + - Poll interval (seconds). + type: int + retransmit_interval: + description: + - Retransmit interval (seconds). + type: int + transit_delay: + description: + - Transit delay (seconds). + type: int + external_preference: + description: + - Preference of external routes. + type: int + overload: + description: Specify time for overload mode reset + type: dict + suboptions: + timeout: + description: + - Time after which overload mode is reset (seconds). + type: int + preference: + description: + - Preference of internal routes. + type: int + prefix_export_limit: + description: + - Maximum number of external prefixes that can be exported. + type: int + reference_bandwidth: + description: + - Bandwidth for calculating metric defaults. + type: str + choices: [1g, 10g] + rfc1583compatibility: + description: + - Set RFC1583 compatibility + type: bool + spf_options: + description: + - Configure options for SPF. + type: dict + suboptions: + delay: + description: + - Time to wait before running an SPF (seconds). + type: int + holddown: + description: + - Time to hold down before running an SPF (seconds). + type: int + rapid_runs: + description: + - Number of maximum rapid SPF runs before holddown (seconds). + type: int + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show protocols ospf). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + description: + - The state the configuration should be left in. + type: str + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - rendered + - parsed + default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# admin# show protocols ospf3 + +- name: Merge Junos OSPFv3 config + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - metric: 5 + name: so-0/0/0.0 + priority: 3 + - metric: 6 + name: so-0/0/1.0 + priority: 2 + stub: + default_metric: 200 + set: true + state: merged + +# Task Output: +# ------------ +# +# before: [] +# +# commands: +# - +# 0.0.0.100so-0/0/0.0 +# 35 +# so-0/0/1.026 +# 200 +# - +# 10.200.16.75 +# +# after: +# - areas: +# - area_id: 0.0.0.100 +# interfaces: +# - metric: 5 +# name: so-0/0/0.0 +# priority: 3 +# - metric: 6 +# name: so-0/0/1.0 +# priority: 2 +# stub: +# default_metric: 200 +# set: true +# router_id: 10.200.16.75 + +# After state +# ----------- +# +# admin# show protocols ospf3 +# area 0.0.0.100 { +# stub default-metric 200; +# interface so-0/0/0.0 { +# metric 5; +# priority 3; +# } +# interface so-0/0/1.0 { +# metric 6; +# priority 2; +# } +# } +# +# Using replaced +# +# Before state +# ------------ +# +# admin# show protocols ospf3 +# admin# show protocols ospf3 +# area 0.0.0.100 { +# stub default-metric 200; +# interface so-0/0/0.0 { +# metric 5; +# priority 3; +# } +# interface so-0/0/1.0 { +# metric 6; +# priority 2; +# } +# } + +- name: Replace existing Junos OSPFv3 config with provided config + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + state: replaced + +# Task Output: +# ------------ +# +# before: +# - areas: +# - area_id: 0.0.0.100 +# interfaces: +# - metric: 5 +# name: so-0/0/0.0 +# priority: 3 +# - metric: 6 +# name: so-0/0/1.0 +# priority: 2 +# stub: +# default_metric: 200 +# set: true +# router_id: 10.200.16.75 +# +# commands: +# - +# 0.0.0.100 +# so-0/0/0.0 +# 0.0.0.100so-0/0/0.0 +# +# - +# 10.200.16.7510.200.16.75 +# +# after: +# - areas: +# - area_id: 0.0.0.100 +# interfaces: +# - metric: 6 +# name: so-0/0/1.0 +# priority: 2 +# - name: so-0/0/0.0 +# stub: +# default_metric: 200 +# set: true +# router_id: 10.200.16.75 +# +# After state +# ----------- +# +# admin# show protocols ospf3 +# area 0.0.0.100 { +# stub default-metric 200; +# interface so-0/0/1.0 { +# metric 6; +# priority 2; +# } +# interface so-0/0/0.0; +# } +# +# Using overridden +# +# Before state +# ------------ +# +# admin# show protocols ospf3 +# area 0.0.0.100 { +# stub default-metric 200; +# interface so-0/0/1.0 { +# metric 6; +# priority 2; +# } +# interface so-0/0/0.0; +# } + +- name: Override runnig OSPFv3 config with provided config + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: true + passive: true + - area_id: 0.0.0.200 + interfaces: + - name: ge-1/1/0.0 + - name: ge-2/2/0.0 + state: overridden + +# Task Output: +# ------------ +# +# before: +# - areas: +# - area_id: 0.0.0.100 +# interfaces: +# - metric: 6 +# name: so-0/0/1.0 +# priority: 2 +# - name: so-0/0/0.0 +# stub: +# default_metric: 200 +# set: true +# router_id: 10.200.16.75 +# +# commands: +# - +# 0.0.0.100 +# so-0/0/0.03 +# 5 +# 200 +# 0.0.0.200ge-1/1/0.0 +# ge-2/2/0.0 +# +# - +# 10.200.16.75 +# +# after: +# - areas: +# - area_id: 0.0.0.100 +# interfaces: +# - flood_reduction: true +# metric: 5 +# name: so-0/0/0.0 +# passive: true +# priority: 3 +# stub: +# default_metric: 200 +# set: true +# - area_id: 0.0.0.200 +# interfaces: +# - name: ge-1/1/0.0 +# - name: ge-2/2/0.0 +# router_id: 10.200.16.75 + +# After state +# ----------- +# +# admin# show protocols ospf3 +# area 0.0.0.100 { +# stub default-metric 200; +# interface so-0/0/0.0 { +# passive; +# metric 5; +# priority 3; +# flood-reduction; +# } +# } +# area 0.0.0.200 { +# interface ge-1/1/0.0; +# interface ge-2/2/0.0; +# } +# Using deleted +# +# Before state +# ------------ +# +# admin# show protocols ospf3 +# area 0.0.0.100 { +# stub default-metric 200; +# interface so-0/0/0.0 { +# passive; +# metric 5; +# priority 3; +# flood-reduction; +# } +# } +# area 0.0.0.200 { +# interface ge-1/1/0.0; +# interface ge-2/2/0.0; +# } + +- name: Delete OSPFv3 running config. + junipernetworks.junos.junos_ospfv3: + config: + state: deleted + +# Task Output: +# ------------ +# +# before: +# - areas: +# - area_id: 0.0.0.100 +# interfaces: +# - flood_reduction: true +# metric: 5 +# name: so-0/0/0.0 +# passive: true +# priority: 3 +# stub: +# default_metric: 200 +# set: true +# - area_id: 0.0.0.200 +# interfaces: +# - name: ge-1/1/0.0 +# - name: ge-2/2/0.0 +# router_id: 10.200.16.75 +# +# commands: +# - +# +# - +# +# +# after: [] +# +# +# After state +# ----------- +# +# admin# show protocols ospf3 + +# Using gathered +# +# Before state +# ------------ +# +# admin# show protocols ospf3 +# area 0.0.0.100 { +# stub default-metric 200; +# interface so-0/0/0.0 { +# metric 5; +# priority 3; +# } +# interface so-0/0/1.0 { +# metric 6; +# priority 2; +# } + +- name: Gather Junos OSPFv3 running-configuration + junipernetworks.junos.junos_ospfv3: + config: + state: gathered +# +# +# Task Output: +# ------------ +# +# gathered: +# +# - areas: +# - area_id: 0.0.0.100 +# interfaces: +# - metric: 5 +# name: so-0/0/0.0 +# priority: 3 +# - metric: 6 +# name: so-0/0/1.0 +# priority: 2 +# stub: +# default_metric: 200 +# set: true +# router_id: 10.200.16.75 + +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# +# +# +# 0.0.0.100 +# +# 200 +# +# +# so-0/0/0.0 +# +# 5 +# 3 +# +# +# +# +# 0.0.0.200 +# +# ge-1/1/0.0 +# +# +# ge-2/2/0.0 +# +# +# +# +# +# 10.200.16.75 +# +# +# + + +- name: Parsed the ospfv3 config into structured ansible resource facts. + junipernetworks.junos.junos_ospfv3: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# Task Output: +# ------------ +# +# parsed: +# - router_id: 10.200.16.75 +# areas: +# - area_id: 0.0.0.100 +# stub: +# default_metric: 200 +# set: true +# interfaces: +# - name: so-0/0/0.0 +# priority: 3 +# metric: 5 +# flood_reduction: true +# passive: true +# - area_id: 0.0.0.200 +# interfaces: +# - name: ge-1/1/0.0 +# - name: ge-2/2/0.0 + +# Using rendered +# +- name: Render the commands for provided configuration + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - metric: 5 + name: so-0/0/0.0 + priority: 3 + - metric: 6 + name: so-0/0/1.0 + priority: 2 + stub: + default_metric: 200 + set: true + state: rendered + +# Task Output: +# ------------ +# +# rendered: " +# 0.0.0.100 +# so-0/0/0.03 +# 5so-0/0/1.0 +# 26 +# 200" +""" +RETURN = """ +before: + description: The configuration prior to the module invocation. + returned: always + type: dict + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration module invocation. + 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: ['< + nc:ospf3>0.0.0.100', 'xml 2', 'xml 3'] +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - +gathered: + description: Facts about the network resource gathered from the remote device as structured data. + returned: when I(state) is C(gathered) + type: list + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. + returned: when I(state) is C(parsed) + type: list + sample: > + This output will always be in the same format as the + module argspec. +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.ospfv3.ospfv3 import ( + Ospfv3Args, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.ospfv3.ospfv3 import ( + Ospfv3, +) + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + required_if = [ + ("state", "merged", ("config",)), + ("state", "replaced", ("config",)), + ("state", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_config",)), + ] + module = AnsibleModule( + argument_spec=Ospfv3Args.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + result = Ospfv3(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_package.py b/ansible_collections/juniper/device/plugins/modules/junos_package.py new file mode 100644 index 00000000..b7f978c9 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_package.py @@ -0,0 +1,291 @@ +#!/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 + + +DOCUMENTATION = """ +module: junos_package +author: Peter Sprygada (@privateip) +short_description: Installs packages on remote devices running Junos +description: +- This module can install new and updated packages on remote devices running Junos. The + module will compare the specified package with the one running on the remote device + and install the specified version if there is a mismatch +version_added: 1.0.0 +extends_documentation_fragment: +- junipernetworks.junos.junos +options: + src: + description: + - The I(src) argument specifies the path to the source package to be installed + on the remote device in the advent of a version mismatch. The I(src) argument + can be either a localized path or a full path to the package file to install. + required: true + type: path + aliases: + - package + version: + description: + - The I(version) argument can be used to explicitly specify the version of the + package that should be installed on the remote device. If the I(version) argument + is not specified, then the version is extracts from the I(src) filename. + type: str + reboot: + description: + - In order for a package to take effect, the remote device must be restarted. When + enabled, this argument will instruct the module to reboot the device once the + updated package has been installed. If disabled or the remote package does not + need to be changed, the device will not be started. + type: bool + default: true + no_copy: + description: + - The I(no_copy) argument is responsible for instructing the remote device on + where to install the package from. When enabled, the package is transferred + to the remote device prior to installing. + type: bool + default: false + unlink: + description: + - The I(unlink) argument is responsible for instructing the remote device to + remove the installation packages after installation. + type: bool + default: false + validate: + description: + - The I(validate) argument is responsible for instructing the remote device to + skip checking the current device configuration compatibility with the package + being installed. When set to false validation is not performed. + type: bool + default: true + force: + description: + - The I(force) argument instructs the module to bypass the package version check + and install the packaged identified in I(src) on the remote device. + type: bool + default: false + force_host: + description: + - The I(force_host) argument controls the way software package or bundle is added + on remote JUNOS host and is applicable for JUNOS QFX5100 device. If the value + is set to C(True) it will ignore any warnings while adding the host software + package or bundle. + type: bool + default: false + issu: + description: + - The I(issu) argument is a boolean flag when set to C(True) allows unified in-service + software upgrade (ISSU) feature which enables you to upgrade between two different + Junos OS releases with no disruption on the control plane and with minimal disruption + of traffic. + type: bool + default: false + ssh_private_key_file: + description: + - The C(ssh_private_key_file) argument is path to the SSH private key file. This + can be used if you need to provide a private key rather than loading the key + into the ssh-key-ring/environment + type: path + ssh_config: + description: + - The C(ssh_config) argument is path to the SSH configuration file. This can be + used to load SSH information from a configuration file. If this option is not + given by default ~/.ssh/config is queried. + type: path + provider: + description: + - B(Deprecated) + - 'Starting with Ansible 2.5 we recommend using C(connection: network_cli) or + C(connection: netconf).' + - For more information please see the L(Junos OS Platform Options guide, ../network/user_guide/platform_junos.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 + port: + description: + - Specifies the port to use when building the connection to the remote device. The + port value will default to the well known SSH port of 22 (for C(transport=cli)) + or port 830 (for C(transport=netconf)) device. + type: int + 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 + 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 + transport: + description: + - Configures the transport connection to use when connecting to the remote + device. + type: str + default: netconf + choices: + - cli + - netconf +requirements: +- junos-eznc +- ncclient (>=v0.5.2) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. +- Works with C(local) connections only. +- Since this module uses junos-eznc to establish connection with junos device the + netconf configuration parameters needs to be passed using module options for example + C(ssh_config) unlike other junos modules that uses C(netconf) connection type. +""" + +EXAMPLES = """ +# the required set of connection arguments have been purposely left off +# the examples for brevity + +- name: install local package on remote device + junipernetworks.junos.junos_package: + src: junos-vsrx-12.1X46-D10.2-domestic.tgz + +- name: install local package on remote device without rebooting + junipernetworks.junos.junos_package: + src: junos-vsrx-12.1X46-D10.2-domestic.tgz + reboot: false + +- name: install local package on remote device with jumpost + junipernetworks.junos.junos_package: + src: junos-vsrx-12.1X46-D10.2-domestic.tgz + ssh_config: /home/user/customsshconfig +""" +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + get_device, + junos_argument_spec, +) + + +try: + from jnpr.junos.utils.sw import SW + + HAS_PYEZ = True +except ImportError: + HAS_PYEZ = False + + +def install_package(module, device): + junos = SW(device) + package = module.params["src"] + no_copy = module.params["no_copy"] + unlink = module.params["unlink"] + validate = module.params["validate"] + force_host = module.params["force_host"] + issu = module.params["issu"] + + def progress_log(dev, report): + module.log(report) + + module.log("installing package") + result = junos.install( + package, + progress=progress_log, + no_copy=no_copy, + unlink=unlink, + validate=validate, + force_host=force_host, + issu=issu, + ) + + if not result: + module.fail_json(msg="Unable to install package on device") + + if module.params["reboot"]: + module.log("rebooting system") + junos.reboot() + + +def main(): + """Main entry point for Ansible module execution""" + argument_spec = dict( + src=dict(type="path", required=True, aliases=["package"]), + version=dict(), + reboot=dict(type="bool", default=True), + no_copy=dict(default=False, type="bool"), + unlink=dict(default=False, type="bool"), + validate=dict(default=True, type="bool"), + force=dict(type="bool", default=False), + force_host=dict(type="bool", default=False), + issu=dict(type="bool", default=False), + ssh_private_key_file=dict(type="path"), + ssh_config=dict(type="path"), + ) + + argument_spec.update(junos_argument_spec) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + if module.params["provider"] is None: + module.params["provider"] = {} + + if not HAS_PYEZ: + module.fail_json( + msg="junos-eznc is required but does not appear to be installed. " + "It can be installed using `pip install junos-eznc`", + ) + + result = dict(changed=False) + + do_upgrade = module.params["force"] or False + + device = get_device(module) + + if not module.params["force"]: + device.facts_refresh() + has_ver = device.facts.get("version") + wants_ver = module.params["version"] + do_upgrade = has_ver != wants_ver + + if do_upgrade: + if not module.check_mode: + install_package(module, device) + result["changed"] = True + + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_ping.py b/ansible_collections/juniper/device/plugins/modules/junos_ping.py new file mode 100644 index 00000000..3045bf1d --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_ping.py @@ -0,0 +1,290 @@ +#!/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 + + +DOCUMENTATION = """ +module: junos_ping +short_description: Tests reachability using ping from devices running Juniper JUNOS +description: +- Tests reachability using ping from devices running Juniper JUNOS to a remote destination. +- Tested against Junos (17.3R1.10) +- For a general purpose network module, see the M(ansible.netcommon.net_ping) module. +- For Windows targets, use the M(ansible.windows.win_ping) module instead. +- For targets running Python, use the M(ansible.builtin.ping) module instead. +version_added: 1.0.0 +extends_documentation_fragment: +- junipernetworks.junos.junos +author: +- Nilashish Chakraborty (@NilashishC) +options: + dest: + description: + - The IP Address or hostname (resolvable by the device) of the remote node. + type: str + required: true + df_bit: + description: + - Determines whether to set the DF bit. + type: bool + default: false + rapid: + description: + - Determines whether to send the packets rapidly. + type: bool + default: false + count: + description: + - Number of packets to send to check reachability. + type: int + default: 5 + source: + description: + - The IP Address to use while sending the ping packet(s). + type: str + interface: + description: + - The source interface to use while sending the ping packet(s). + type: str + ttl: + description: + - The time-to-live value for the ICMP packet(s). + type: int + size: + description: + - Determines the size (in bytes) of the ping packet(s). + type: int + interval: + description: + - Determines the interval (in seconds) between consecutive pings. + type: int + state: + description: + - Determines if the expected result is success or fail. + type: str + choices: + - absent + - present + default: present +notes: +- For a general purpose network module, see the M(ansible.netcommon.net_ping) module. +- For Windows targets, use the M(ansible.windows.win_ping) module instead. +- For targets running Python, use the M(ansible.builtin.ping) module instead. +- This module works only with connection C(network_cli). +""" + +EXAMPLES = """ +- name: Test reachability to 10.10.10.10 + junipernetworks.junos.junos_ping: + dest: 10.10.10.10 + +- name: Test reachability to 10.20.20.20 using source and size set + junipernetworks.junos.junos_ping: + dest: 10.20.20.20 + size: 1024 + ttl: 128 + +- name: Test unreachability to 10.30.30.30 using interval + junipernetworks.junos.junos_ping: + dest: 10.30.30.30 + interval: 3 + state: absent + +- name: Test reachability to 10.40.40.40 setting count and interface + junipernetworks.junos.junos_ping: + dest: 10.40.40.40 + interface: fxp0 + count: 20 + size: 512 + +- name: Test reachability to 10.50.50.50 using do-not-fragment and rapid + junipernetworks.junos.junos_ping: + dest: 10.50.50.50 + df_bit: true + rapid: true +""" + +RETURN = """ +commands: + description: List of commands sent. + returned: always + type: list + sample: ["ping 10.8.38.44 count 10 source 10.8.38.38 ttl 128"] +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: The round trip time (RTT) stats. + returned: when ping succeeds + type: dict + sample: {"avg": 2, "max": 8, "min": 1, "stddev": 24} +""" + +import re + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + get_connection, +) + + +def main(): + """main entry point for module execution""" + argument_spec = dict( + count=dict(type="int", default=5), + dest=dict(type="str", required=True), + df_bit=dict(type="bool", default=False), + rapid=dict(type="bool", default=False), + source=dict(), + interface=dict(), + ttl=dict(type="int"), + size=dict(type="int"), + interval=dict(type="int"), + state=dict( + type="str", + choices=["absent", "present"], + default="present", + ), + ) + + module = AnsibleModule(argument_spec=argument_spec) + + count = module.params["count"] + dest = module.params["dest"] + df_bit = module.params["df_bit"] + rapid = module.params["rapid"] + source = module.params["source"] + size = module.params["size"] + ttl = module.params["ttl"] + interval = module.params["interval"] + interface = module.params["interface"] + warnings = list() + + results = {"changed": False} + if warnings: + results["warnings"] = warnings + + results["commands"] = build_ping( + dest, + count, + size, + interval, + source, + ttl, + interface, + df_bit, + rapid, + ) + conn = get_connection(module) + + ping_results = conn.get(results["commands"]) + + rtt_info, rate_info = None, None + for line in ping_results.split("\n"): + if line.startswith("round-trip"): + rtt_info = line + if line.startswith("%s packets transmitted" % count): + rate_info = line + + if rtt_info: + rtt = parse_rtt(rtt_info) + for k, v in rtt.items(): + if rtt[k] is not None: + rtt[k] = float(v) + results["rtt"] = rtt + + pkt_loss, rx, tx = parse_rate(rate_info) + results["packet_loss"] = str(pkt_loss) + "%" + results["packets_rx"] = int(rx) + results["packets_tx"] = int(tx) + + validate_results(module, pkt_loss, results) + + module.exit_json(**results) + + +def build_ping( + dest, + count, + size=None, + interval=None, + source=None, + ttl=None, + interface=None, + df_bit=False, + rapid=False, +): + cmd = "ping {0} count {1}".format(dest, str(count)) + + if source: + cmd += " source {0}".format(source) + + if interface: + cmd += " interface {0}".format(interface) + + if ttl: + cmd += " ttl {0}".format(str(ttl)) + + if size: + cmd += " size {0}".format(str(size)) + + if interval: + cmd += " interval {0}".format(str(interval)) + + if df_bit: + cmd += " do-not-fragment" + + if rapid: + cmd += " rapid" + + return cmd + + +def parse_rate(rate_info): + rate_re = re.compile( + r"(?P\d*) packets transmitted,(?:\s*)(?P\d*) packets received,(?:\s*)(?P\d*)% packet loss", + ) + rate = rate_re.match(rate_info) + + return rate.group("pkt_loss"), rate.group("rx"), rate.group("tx") + + +def parse_rtt(rtt_info): + rtt_re = re.compile( + r"round-trip (?:.*)=(?:\s*)(?P\d+\.\d+).(?:\d*)/(?P\d+\.\d+).(?:\d*)/(?P\d*\.\d*).(?:\d*)/(?P\d*\.\d*)", + ) + rtt = rtt_re.match(rtt_info) + + return rtt.groupdict() + + +def validate_results(module, loss, results): + state = module.params["state"] + if state == "present" and int(loss) == 100: + module.fail_json(msg="Ping failed unexpectedly", **results) + elif state == "absent" and int(loss) < 100: + module.fail_json(msg="Ping succeeded unexpectedly", **results) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_prefix_lists.py b/ansible_collections/juniper/device/plugins/modules/junos_prefix_lists.py new file mode 100644 index 00000000..938b66a9 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_prefix_lists.py @@ -0,0 +1,658 @@ +#!/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 junos_prefix_lists +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +ANSIBLE_METADATA = { + "metadata_version": "1.1", + "status": ["preview"], + "supported_by": "network", +} + +DOCUMENTATION = """ +--- +module: junos_prefix_lists +version_added: 2.1.0 +short_description: Manage prefix-lists attributes of interfaces on Junos devices. +description: Manage prefix-lists attributes of interfaces on Junos network devices. +author: Rohit Thakur (@rohitthakur2590) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection C(netconf). + - See L(the Junos OS Platform Options,https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html). + - Tested against JunOS v18.4R1 +options: + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show policy-options). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + config: + description: The provided link BGP address family dictionary. + type: list + elements: dict + suboptions: + name: + description: Specify the name of the prefix-list. + type: str + required: true + address_prefixes: + description: Specify address prefixes. + type: list + elements: str + dynamic_db: + description: Enable object to exist in dynamic DB. + type: bool + state: + description: + - The state the configuration should be left in. + type: str + choices: + - merged + - replaced + - overridden + - deleted + - parsed + - gathered + - rendered + default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# vagrant@vsrx# show policy-options +# +# [edit] + +- name: Merge Junos prefix lists + junipernetworks.junos.junos_prefix_lists: + config: + - name: Internal + address_prefixes: + - 172.16.1.32 + - 172.16.3.32 + - name: Test1 + dynamic_db: true + - name: Test2 + address_prefixes: + - 172.16.2.32 + - 172.16.7.32 + - 172.16.9.32 + state: merged + +# Task Output +# ------------- +# +# before: [] +# commands: +# - +# - "Internal172.16.1.32" +# - "172.16.3.32" +# - "Test1" +# - "Test2" +# - "172.16.2.32" +# - "172.16.7.32" +# - "172.16.9.32" +# - "" +# after: +# - address_prefixes: +# - 172.16.1.32/32 +# - 172.16.3.32/32 +# name: Internal +# - dynamic_db: true +# name: Test1 +# - address_prefixes: +# - 172.16.2.32/32 +# - 172.16.7.32/32 +# - 172.16.9.32/32 +# name: Test2 + + +# After state +# ----------- +# +# vagrant@vsrx# show policy-options +# prefix-list Internal { +# 172.16.1.32/32; +# 172.16.3.32/32; +# } +# prefix-list Test1 { +# dynamic-db; +# } +# prefix-list Test2 { +# 172.16.2.32/32; +# 172.16.7.32/32; +# 172.16.9.32/32; +# } + + +# Using gathered +# +# Before state +# ------------ +# +# vagrant@vsrx# show policy-options +# prefix-list Internal { +# 172.16.1.32/32; +# 172.16.3.32/32; +# } +# prefix-list Test1 { +# dynamic-db; +# } +# prefix-list Test2 { +# 172.16.2.32/32; +# 172.16.7.32/32; +# 172.16.9.32/32; +# } + +- name: Gather Junos prefix-lists + junipernetworks.junos.junos_prefix_lists: + state: gathered + + +# Task Output +# ------------- +# +# gathered: +# - address_prefixes: +# - 172.16.1.32/32 +# - 172.16.3.32/32 +# name: Internal +# - dynamic_db: true +# name: Test1 +# - address_prefixes: +# - 172.16.2.32/32 +# - 172.16.7.32/32 +# - 172.16.9.32/32 +# name: Test2 + + +# Using replaced + + +# Before state +# ------------ +# +# vagrant@vsrx# show policy-options +# prefix-list Internal { +# 172.16.1.32/32; +# 172.16.3.32/32; +# } +# prefix-list Test1 { +# dynamic-db; +# } +# prefix-list Test2 { +# 172.16.2.32/32; +# 172.16.7.32/32; +# 172.16.9.32/32; +# } + + +- name: Replace existing Junos prefix-lists configuration with provided config + junipernetworks.junos.junos_prefix_lists: + config: + - name: Test2 + address_prefixes: + - 172.16.4.32 + - 172.16.8.32 + - 172.16.9.32" + state: replaced + + +# Task Output +# ------------- +# +# before: +# - address_prefixes: +# - 172.16.1.32/32 +# - 172.16.3.32/32 +# name: Internal +# - dynamic_db: true +# name: Test1 +# - address_prefixes: +# - 172.16.2.32/32 +# - 172.16.7.32/32 +# - 172.16.9.32/32 +# name: Test2 +# commands: +# - +# - Test2 +# - "Test2172.16.4.32" +# - "172.16.8.32" +# - "172.16.9.32" +# - "" +# after: +# - address_prefixes: +# - 172.16.1.32/32 +# - 172.16.3.32/32 +# name: Internal +# - dynamic_db: true +# name: Test1 +# - address_prefixes: +# - 172.16.4.32/32 +# - 172.16.8.32/32 +# - 172.16.9.32/32 +# name: Test2 + +# After state +# ----------- +# +# vagrant@vsrx# show policy-options +# prefix-list Internal { +# 172.16.1.32/32; +# 172.16.3.32/32; +# } +# prefix-list Test1 { +# dynamic-db; +# } +# prefix-list Test2 { +# 172.16.4.32/32; +# 172.16.8.32/32; +# 172.16.9.32/32; +# } + + +# Using overridden + +# Before state +# ------------ +# +# vagrant@vsrx# show policy-options +# prefix-list Internal { +# 172.16.1.32/32; +# 172.16.3.32/32; +# } +# prefix-list Test1 { +# dynamic-db; +# } +# prefix-list Test2 { +# 172.16.4.32/32; +# 172.16.8.32/32; +# 172.16.9.32/32; +# } + + +- name: Override Junos prefix-lists configuration with provided configuration + junipernetworks.junos.junos_prefix_lists: + config: + - name: Test2 + address_prefixes: + - 172.16.4.32/28 + - 172.16.8.32/28 + - 172.16.9.32/28 + state: overridden + + +# Task Output +# ------------- +# +# before: +# - address_prefixes: +# - 172.16.1.32/32 +# - 172.16.3.32/32 +# name: Internal +# - dynamic_db: true +# name: Test1 +# - address_prefixes: +# - 172.16.4.32/32 +# - 172.16.8.32/32 +# - 172.16.9.32/32 +# name: Test2 +# commands: +# - +# - Internal +# - Test1 +# - Test2 +# - "Test2" +# - "172.16.4.32/28" +# - "172.16.8.32/28" +# - "172.16.9.32/28" +# after: +# - address_prefixes: +# - 172.16.4.32/28 +# - 172.16.8.32/28 +# - 172.16.9.32/28 +# name: Test2 + +# After state +# ----------- +# +# vagrant@vsrx# show policy-options +# prefix-list Test2 { +# 172.16.4.32/28; +# 172.16.8.32/28; +# 172.16.9.32/28; +# } + + +# Using deleted + + +# Before state +# ------------ +# +# vagrant@vsrx# show policy-options +# prefix-list Internal { +# 172.16.1.32/32; +# 172.16.3.32/32; +# } +# prefix-list Test1 { +# dynamic-db; +# } +# prefix-list Test2 { +# 172.16.2.32/32; +# 172.16.7.32/32; +# 172.16.9.32/32; +# } + + +- name: Delete provided prefix-lists + junipernetworks.junos.junos_prefix_lists: + config: + - name: "Test1" + - name: "Test2" + state: deleted + + +# Task Output +# ------------- +# +# before: +# - address_prefixes: +# - 172.16.1.32/32 +# - 172.16.3.32/32 +# name: Internal +# - dynamic_db: true +# name: Test1 +# - address_prefixes: +# - 172.16.2.32/32 +# - 172.16.7.32/32 +# - 172.16.9.32/32 +# name: Test2 +# commands: +# - +# - Test1 +# - Test2 +# after: +# - address_prefixes: +# - 172.16.1.32/32 +# - 172.16.3.32/32 +# name: Internal + + +# After state +# ----------- +# +# vagrant@vsrx# show policy-options +# prefix-list Internal { +# 172.16.1.32/32; +# 172.16.3.32/32; +# } +# + + +# Using deleted without specifying config + + +# Before state +# ------------ +# +# vagrant@vsrx# show policy-options +# prefix-list Internal { +# 172.16.1.32/32; +# 172.16.3.32/32; +# } +# prefix-list Test1 { +# dynamic-db; +# } +# prefix-list Test2 { +# 172.16.2.32/32; +# 172.16.7.32/32; +# 172.16.9.32/32; +# } + + +- name: Delete complete Junos prefix-lists configuration + junipernetworks.junos.junos_prefix_lists: + state: deleted + + +# Task Output +# ------------- +# +# before: +# - address_prefixes: +# - 172.16.1.32/32 +# - 172.16.3.32/32 +# name: Internal +# - dynamic_db: true +# name: Test1 +# - address_prefixes: +# - 172.16.2.32/32 +# - 172.16.7.32/32 +# - 172.16.9.32/32 +# name: Test2 +# commands: +# - +# - +# after: [] + + +# After state +# ----------- +# +# vagrant@vsrx# show policy-options +# +# [edit] + + +# Using parsed + + +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# +# 64510 +# +# +# 64500 +# +# +# 172.16.1.16/28 +# +# +# 172.16.1.32/28 +# +# +# +# +# + + +- name: Parse running prefix-lists configuration + junipernetworks.junos.junos_prefix_lists: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + + +# Task Output +# ------------- +# parsed: +# - name: '64510' +# - address_prefixes: +# - 172.16.1.16/28 +# - 172.16.1.32/28 +# dynamic_db: true +# name: '64500' + + +# Using rendered + + +- name: Render the xml for provided configuration + junipernetworks.junos.junos_prefix_lists: + config: + - name: Internal + address_prefixes: + - 172.16.1.32 + - 172.16.3.32 + - name: Test1 + dynamic_db: true + - name: Test2 + address_prefixes: + - 172.16.2.32 + - 172.16.7.32 + - 172.16.9.32 + state: rendered + + +# Task Output +# ------------- +# rendered: +# - +# - "Internal172.16.1.32" +# - "172.16.3.32" +# - "Test1" +# - "Test2" +# - "172.16.2.32" +# - "172.16.7.32" +# - "172.16.9.32" +# - "" +""" +RRETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + type: str + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration model invocation. + returned: when changed + type: str + 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: + - + - "Internal172.16.1.32" + - "172.16.3.32" + - "Test1" + - "Test2" + - "172.16.2.32" + - "172.16.7.32" + - "172.16.9.32" + - "" +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - + - "Internal172.16.1.32" + - "172.16.3.32" + - "Test1" + - "Test2" + - "172.16.2.32" + - "172.16.7.32" + - "172.16.9.32" + - "" +gathered: + description: Facts about the network resource gathered from the remote device as structured data. + returned: when I(state) is C(gathered) + type: list + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. + returned: when I(state) is C(parsed) + type: list + sample: > + This output will always be in the same format as the + module argspec. +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.prefix_lists.prefix_lists import ( + Prefix_listsArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.prefix_lists.prefix_lists import ( + Prefix_lists, +) + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + required_if = [ + ("state", "merged", ("config",)), + ("state", "replaced", ("config",)), + ("state", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_config",)), + ] + module = AnsibleModule( + argument_spec=Prefix_listsArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + result = Prefix_lists(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_routing_instances.py b/ansible_collections/juniper/device/plugins/modules/junos_routing_instances.py new file mode 100644 index 00000000..e6265472 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_routing_instances.py @@ -0,0 +1,801 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# 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 junos_routing_instances +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +ANSIBLE_METADATA = { + "metadata_version": "1.1", + "status": ["preview"], + "supported_by": "network", +} + +DOCUMENTATION = """ +--- +module: junos_routing_instances +version_added: 2.1.0 +short_description: Manage routing instances on Junos devices. +description: Manage routing instances on Junos network devices. +author: Rohit Thakur (@rohitthakur2590) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). + - Tested against JunOS v18.4R1 +options: + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show routing-instances). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + config: + description: The provided Routing instance configuration list. + type: list + elements: dict + suboptions: + name: + description: Specify routing instance name. + type: str + connector_id_advertise: + description: Advertise connector-id attribute. + type: bool + description: + description: Specify text description of routing instance. + type: str + egress_protection: + description: Egress instance protection dictionary. + type: dict + suboptions: + context_identifier: + description: Specify context identifier. + type: str + protector: + description: Enable Edge Protector functionality for this VPN. + type: bool + instance_role: + description: Primary role of L2Backhaul-vpn router. + type: str + choices: ['access', 'nni'] + bridge_domains: + description: + - Bridge domain configuration. + - This has been tested for junos MX204. + type: list + elements: dict + suboptions: + name: + description: Specify the name of the bridge domain. + type: str + description: + description: Specify domain description. + type: str + domain_id: + description: Provide the domain ID. + type: int + enable_mac_move_action: + description: Enable blocking action due to mac-move in this Bridge Domain. + type: bool + vlan_id: + description: IEEE 802.1q VLAN identifier for bridging domain (1..4094) + type: int + mcae_mac_flush: + description: Enable IRB MAC synchronization in this bridge domain + type: bool + no_irb_layer_2_copy: + description: Disable transmission of layer-2 copy of packets of irb routing-interface. + type: bool + no_local_switching: + description: Disable local switching within CE-facing interfaces. + type: bool + service_id: + description: Specify service id. + type: int + type: + description: Specify instance type. + type: str + choices: + - evpn + - evpn-vpws + - forwarding + - l2backhaul-vpn + - l2vpn + - layer2-control + - mac-vrf + - mpls-forwarding + - mpls-internet-multicast + - no-forwarding + - virtual-router + - virtual-switch + - vpls + - vrf + interfaces: + description: Interface name for this routing instance. + type: list + elements: dict + suboptions: + name: + description: Specify name of the interface. + type: str + protect_interface: + description: Specify name of the protected interface. + type: str + l2vpn_id: + description: Layer-2 vpn-id for this instance. + type: str + no_irb_layer_2_copy: + description: Disable transmission of layer-2 copy of packets of irb routing-interface. + type: bool + no_normalization: + description: Disable vlan id normalization for interfaces. + type: bool + no_local_switching: + description: Disable vlan id normalization for interfaces. + type: bool + no_vrf_advertise: + description: Disable vlan id normalization for interfaces. + type: bool + no_vrf_propagate_ttl: + description: Disable TTL propagation from IP to MPLS (on push) and MPLS to IP (on pop). + type: bool + qualified_bum_pruning_mode: + description: Enable BUM pruning for VPLS instance. + type: bool + route_distinguisher: + description: Route distinguisher for this instance + type: str + routing_interface: + description: Routing interface name for this routing-instance. + type: list + elements: str + vrf_imports: + description: Import policy for VRF instance RIBs. + type: list + elements: str + vrf_exports: + description: Export policy for VRF instance RIBs. + type: list + elements: str + state: + description: + - The state the configuration should be left in. + type: str + choices: + - merged + - replaced + - overridden + - deleted + - parsed + - gathered + - rendered + default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# admin# show routing-instances +# +# [edit] +# vagrant@vsrx# show policy-options +# policy-statement test-policy { +# term t1 { +# then reject; +# } +# } +# policy-statement test-policy-1 { +# term t1 { +# then reject; +# } +# } + +- name: Merge Junos BGP address family configuration + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + state: merged +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# After state +# ----------- +# +# admin# show routing-instances +# forwardinst { +# description "Configured by Ansible Content Team"; +# instance-type forwarding; +# } +# test { +# instance-type vrf; +# interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined +# interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined +# route-distinguisher 10.58.255.1:37; +# vrf-import test-policy; +# vrf-export [ test-policy test-policy-1 ]; +# connector-id-advertise; +# } +# +# Using gathered +# +# Before state +# ------------ +# +# admin# show routing-instances +# +# [edit] +# admin# show routing-instances +# forwardinst { +# description "Configured by Ansible Content Team"; +# instance-type forwarding; +# } +# test { +# instance-type vrf; +# interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined +# interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined +# route-distinguisher 10.58.255.1:37; +# vrf-import test-policy; +# vrf-export [ test-policy test-policy-1 ]; +# connector-id-advertise; +# } +- name: Gather Junos routing-instances + junipernetworks.junos.junos_routing_instances: + state: gathered +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# "gathered": [ +# { +# "description": "Configured by Ansible Content Team", +# "name": "forwardinst", +# "type": "forwarding" +# }, +# { +# "connector_id_advertise": true, +# "interfaces": [ +# { +# "name": "gr-0/0/0.0" +# }, +# { +# "name": "sp-0/0/0.0" +# } +# ], +# "name": "test", +# "route_distinguisher": "10.58.255.1:37", +# "type": "vrf", +# "vrf_exports": [ +# "test-policy", +# "test-policy-1" +# ], +# "vrf_imports": [ +# "test-policy" +# ] +# } +# ] +# +# Using replaced +# +# Before state +# ------------ +# +# admin# show routing-instances +# forwardinst { +# description "Configured by Ansible Content Team"; +# instance-type forwarding; +# } +# test { +# instance-type vrf; +# interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined +# interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined +# route-distinguisher 10.58.255.1:37; +# vrf-import test-policy; +# vrf-export [ test-policy test-policy-1 ]; +# connector-id-advertise; +# } + +- name: Replace existing Junos routing instance config with provided config + junipernetworks.junos.junos_routing_instances: + config: + address_family: + - name: "test" + type: "vrf" + route_distinguisher: "10.57.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: false + description: "Configured by Ansible Content Team" + state: replaced + +# After state +# ----------- +# +# admin@vsrx# show routing-instances +# forwardinst { +# description "Configured by Ansible Content Team"; +# instance-type forwarding; +# } +# test { +# description "Configured by Ansible Content Team"; +# instance-type vrf; +# interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined +# interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined +# route-distinguisher 10.57.255.1:37; +# vrf-import test-policy; +# vrf-export test-policy; +# } + +# Using overridden +# +# Before state +# ------------ +# +# admin@vsrx# show routing-instances +# forwardinst { +# description "Configured by Ansible Content Team"; +# instance-type forwarding; +# } +# test { +# description "Configured by Ansible Content Team"; +# instance-type vrf; +# interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined +# interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined +# route-distinguisher 10.57.255.1:37; +# vrf-import test-policy; +# vrf-export test-policy; +# } + +- name: Override Junos routing-instances configuration + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + - name: "vtest1" + type: "virtual-router" + state: overridden + +# After state +# ----------- +# +# admin@vsrx# show routing-instances +# forwardinst { +# description "Configured by Ansible Content Team"; +# instance-type forwarding; +# } +# test { +# instance-type vrf; +# interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined +# interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined +# route-distinguisher 10.58.255.1:37; +# vrf-import test-policy; +# vrf-export [ test-policy test-policy-1 ]; +# connector-id-advertise; +# } +# vtest1 { +# instance-type virtual-router; +# } + + +# Using deleted +# +# Before state +# ------------ +# +# admin@vsrx# show routing-instances +# forwardinst { +# description "Configured by Ansible Content Team"; +# instance-type forwarding; +# } +# test { +# instance-type vrf; +# interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined +# interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined +# route-distinguisher 10.58.255.1:37; +# vrf-import test-policy; +# vrf-export [ test-policy test-policy-1 ]; +# connector-id-advertise; +# } + +- name: Delete provided junos routing-instamce + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + state: deleted + +# After state +# ----------- +# +# admin@vsrx# show routing-instances +# forwardinst { +# description "Configured by Ansible Content Team"; +# instance-type forwarding; +# } + +# Using deleted without config +# +# Before state +# ------------ +# +# admin@vsrx# show routing-instances +# forwardinst { +# description "Configured by Ansible Content Team"; +# instance-type forwarding; +# } +# test { +# instance-type vrf; +# interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined +# interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined +# route-distinguisher 10.58.255.1:37; +# vrf-import test-policy; +# vrf-export [ test-policy test-policy-1 ]; +# connector-id-advertise; +# } +# vtest1 { +# instance-type virtual-router; +# } + +- name: Delete complete Junos routing-instances config + junipernetworks.junos.junos_routing_instances: + config: + state: deleted + +# After state +# ----------- +# +# admin@vsrx# show routing-instances +# +# [edit] + +- name: Gather Junos BGP address family config + junipernetworks.junos.junos_routing_instances: + config: + state: gathered +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# "gathered": { +# "address_family": [ +# { +# "af_type": [ +# { +# "accepted_prefix_limit": { +# "idle_timeout_value": 2001, +# "limit_threshold": 98, +# "maximum": 20 +# }, +# "damping": true, +# "defer_initial_multipath_build": { +# "maximum_delay": 2 +# }, +# "type": "signaling" +# } +# ], +# "afi": "evpn" +# }, +# { +# "af_type": [ +# { +# "accepted_prefix_limit": { +# "idle_timeout_value": 2000, +# "limit_threshold": 99, +# "maximum": 20 +# }, +# "damping": true, +# "defer_initial_multipath_build": { +# "maximum_delay": 2 +# }, +# "delay_route_advertisements": { +# "max_delay_route_age": 20, +# "max_delay_routing_uptime": 32000, +# "min_delay_inbound_convergence": 32000, +# "min_delay_routing_uptime": 23000 +# }, +# "graceful_restart_forwarding_state_bit": "from-fib", +# "type": "any" +# }, +# { +# "legacy_redirect_ip_action": { +# "receive": true, +# "send": true +# }, +# "loops": 4, +# "no_install": true, +# "output_queue_priority_expedited": true, +# "secondary_independent_resolution": true, +# "type": "flow" +# }, +# { +# "entropy_label": { +# "no_next_hop_validation": true +# }, +# "explicit_null": { +# "connected_only": true +# }, +# "per_group_label": true, +# "per_prefix_label": true, +# "prefix_limit": { +# "forever": true, +# "limit_threshold": 99, +# "maximum": 20 +# }, +# "resolve_vpn": true, +# "rib": "inet.3", +# "route_refresh_priority_priority": 3, +# "type": "labeled-unicast" +# }, +# { +# "extended_nexthop": true, +# "extended_nexthop_color": true, +# "local_ipv4_address": "9.9.9.9", +# "type": "unicast" +# } +# ], +# "afi": "inet" +# } +# ] +# } +# +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# +# forwardinst +# Configured by Ansible Content Team +# forwarding +# +# +# test +# vrf +# +# gr-0/0/0.0 +# +# +# sp-0/0/0.0 +# +# +# 10.58.255.1:37 +# +# test-policy +# test-policy +# test-policy-1 +# +# +# +# +# + +- name: Parse routing instance running config + junipernetworks.junos.junos_routing_instances: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "parsed": [ +# { +# "description": "Configured by Ansible Content Team", +# "name": "forwardinst", +# "type": "forwarding" +# }, +# { +# "connector_id_advertise": true, +# "interfaces": [ +# { +# "name": "gr-0/0/0.0" +# }, +# { +# "name": "sp-0/0/0.0" +# } +# ], +# "name": "test", +# "route_distinguisher": "10.58.255.1:37", +# "type": "vrf", +# "vrf_exports": [ +# "test-policy", +# "test-policy-1" +# ], +# "vrf_imports": [ +# "test-policy" +# ] +# } +# ] +# +# +# Using rendered +# +# +- name: Render the xml for provided configuration + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + state: rendered + +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "rendered": " +# testvrf +# sp-0/0/0.0gr-0/0/0.0 +# 10.58.255.1:37 +# test-policytest-policy +# test-policy-1 +# forwardinstConfigured by Ansible Content Team +# forwarding" +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: list +after: + description: The resulting configuration model invocation. + returned: when changed + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: list +commands: + description: The set of commands pushed to the remote device. + returned: always + type: list + sample: [' + + test + + vrf + + sp-0/0/0.0 + + + gr-0/0/0.0 + + + 10.58.255.1:37 + + test-policy + test-policy + test-policy-1 + + +
+ ', 'xml2', 'xml 3'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.routing_instances.routing_instances import ( + Routing_instancesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.routing_instances.routing_instances import ( + Routing_instances, +) + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + required_if = [ + ("state", "merged", ("config",)), + ("state", "replaced", ("config",)), + ("state", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_config",)), + ] + module = AnsibleModule( + argument_spec=Routing_instancesArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + result = Routing_instances(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_routing_options.py b/ansible_collections/juniper/device/plugins/modules/junos_routing_options.py new file mode 100644 index 00000000..b5d5f87d --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_routing_options.py @@ -0,0 +1,402 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# 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 junos_routing_options +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +DOCUMENTATION = """ +--- +module: junos_routing_options +version_added: 2.8.0 +short_description: Manage routing-options configuration on Junos devices. +description: This module manages routing-options configuration on devices running Junos. +author: Rohit Thakur (@rohitthakur2590) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection C(netconf). + - See L(the Junos OS Platform Options,https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html). + - Tested against JunOS v18.4R1 +options: + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show system routing-options). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result. + type: str + config: + description: A dictionary of routing-options configuration. + type: dict + suboptions: + autonomous_system: + description: Specify Autonomous system number. + type: dict + suboptions: + as_number: + description: Specify Autonomous system number. + type: str + required: true + loops: + description: Specify maximum number of times this AS can be in an AS path. + type: int + asdot_notation: + description: Enable AS-Dot notation to display true 4 byte AS numbers. + type: bool + router_id: + description: Specify Router identifier. + type: str + state: + description: + - The state the configuration should be left in. + - Refer to examples for more details. + type: str + choices: + - merged + - replaced + - deleted + - overridden + - parsed + - gathered + - rendered + default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# vagrant@vsrx# show system routing-options +# +- name: Merge provided NTP configuration into running configuration. + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + state: merged +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "autonomous_system": { +# "as_number": "2", +# "asdot_notation": true +# } +# }, +# "before": {}, +# "changed": true, +# "commands": [ +# "" +# "2" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show routing-options +# autonomous-system 2 asdot-notation; +# +# +# Using Replaced +# Before state +# ------------ +# +# vagrant@vsrx# show routing-options +# autonomous-system 2 asdot-notation; + +- name: Replaced running routing-options configuration with provided configuration + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + router_id: "1.1.1.1" + state: replaced +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "autonomous_system": { +# "as_number": "2", +# "asdot_notation": true +# }, +# "router_id": "1.1.1.1" +# }, +# "before": { +# "autonomous_system": { +# "as_number": "2", +# "asdot_notation": true +# } +# }, +# "changed": true, +# "commands": [ +# "" +# "2" +# "1.1.1.1" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show routing-options +# router-id 1.1.1.1; +# autonomous-system 2 asdot-notation; + + +# Using overridden +# +# vagrant@vsrx# show routing-options +# autonomous-system 2 asdot-notation; + +- name: Override running routing-options configuration with provided configuration + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + router_id: "1.1.1.1" + state: overridden +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "autonomous_system": { +# "as_number": "2", +# "asdot_notation": true +# }, +# "router_id": "1.1.1.1" +# }, +# "before": { +# "autonomous_system": { +# "as_number": "2", +# "asdot_notation": true +# } +# }, +# "changed": true, +# "commands": [ +# "" +# "2" +# "1.1.1.1" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show routing-options +# router-id 1.1.1.1; +# autonomous-system 2 asdot-notation; +# +# Using deleted +# +# Before state +# ------------ +# +# vagrant@vsrx# show routing-options +# router-id 1.1.1.1; +# autonomous-system 2 asdot-notation; +# +- name: Delete running routing-options configuration + junipernetworks.junos.junos_routing_options: + config: + state: deleted +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": {}, +# "before": { +# "autonomous_system": { +# "as_number": "2", +# "asdot_notation": true +# }, +# "router_id": "1.1.1.1" +# }, +# "changed": true, +# "commands": [ +# "" +# "" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show routing-options +# +# [edit] +# Using gathered +# +# Before state +# ------------ +# +# vagrant@vsrx# show routing-options +# router-id 1.1.1.1; +# autonomous-system 2 asdot-notation; + +- name: Gather running routing-options configuration + junipernetworks.junos.junos_routing_options: + state: gathered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "gathered": { +# "autonomous_system": { +# "as_number": "2", +# "asdot_notation": true +# }, +# "router_id": "1.1.1.1" +# }, +# "changed": false, +# Using rendered +# +# Before state +# ------------ +# +- name: Render xml for provided facts. + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + loops: 4 + router_id: 12.12.12.12 + state: rendered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "rendered": [ +# " +# "24 +# "12.12.12.12" +# ] +# +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# 12.12.12.12 +# +# 2 +# 4 +# +# +# +# +# +# +- name: Parse routing-options running config + junipernetworks.junos.junos_routing_options: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "parsed": { +# "autonomous_system": { +# "as_number": "2", +# "asdot_notation": true, +# "loops": 4 +# }, +# "router_id": "12.12.12.12" +# } +# +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: dict +after: + description: The resulting configuration model invocation. + returned: when changed + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: dict +commands: + description: The set of commands pushed to the remote device. + returned: always + type: list + sample: [''] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.routing_options.routing_options import ( + Routing_optionsArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.routing_options.routing_options import ( + Routing_options, +) + + +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",)), + ] + module = AnsibleModule( + argument_spec=Routing_optionsArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + + result = Routing_options(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_rpc.py b/ansible_collections/juniper/device/plugins/modules/junos_rpc.py new file mode 100644 index 00000000..23da5e95 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_rpc.py @@ -0,0 +1,177 @@ +#!/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 + + +DOCUMENTATION = """ +module: junos_rpc +author: Peter Sprygada (@privateip) +short_description: Runs an arbitrary RPC over NetConf on an Juniper JUNOS device +description: +- Sends a request to the remote device running JUNOS to execute the specified RPC + using the NetConf transport. The reply is then returned to the playbook in the + C(xml) key. If an alternate output format is requested, the reply is transformed + to the requested output. +version_added: 1.0.0 +extends_documentation_fragment: +- junipernetworks.junos.junos +options: + rpc: + description: + - The C(rpc) argument specifies the RPC call to send to the remote devices to + be executed. The RPC Reply message is parsed and the contents are returned + to the playbook. + type: str + required: true + args: + description: + - The C(args) argument provides a set of arguments for the RPC call and are encoded + in the request message. This argument accepts a set of key=value arguments. + type: dict + attrs: + description: + - The C(attrs) arguments defines a list of attributes and their values to set + for the RPC call. This accepts a dictionary of key-values. + type: dict + output: + description: + - The C(output) argument specifies the desired output of the return data. This + argument accepts one of C(xml), C(text), or C(json). For C(json), the JUNOS + device must be running a version of software that supports native JSON output. + default: xml + type: str + choices: ["xml", "json", "text"] +requirements: +- ncclient (>=v0.5.2) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. +- Recommended connection is C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +- This module also works with C(local) connections for legacy playbooks. +""" + +EXAMPLES = """ +- name: collect interface information using rpc + junipernetworks.junos.junos_rpc: + rpc: get-interface-information + args: + interface-name: em0 + media: true + +- name: get system information + junipernetworks.junos.junos_rpc: + rpc: get-system-information + +- name: load configuration + junipernetworks.junos.junos_rpc: + rpc: load-configuration + attrs: + action: override + url: /tmp/config.conf +""" + +RETURN = """ +xml: + description: The xml return string from the rpc request. + returned: always + type: str +output: + description: The rpc rely converted to the output format. + returned: always + type: str +output_lines: + description: The text output split into lines for readability. + returned: always + type: list +""" +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf import ( + exec_rpc, +) + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + tostring, +) + + +USE_PERSISTENT_CONNECTION = True + +try: + from lxml.etree import Element, SubElement +except ImportError: + from xml.etree.ElementTree import Element, SubElement + + +def main(): + """main entry point for Ansible module""" + argument_spec = dict( + rpc=dict(required=True), + args=dict(type="dict"), + attrs=dict(type="dict"), + output=dict(default="xml", choices=["xml", "json", "text"]), + ) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=False, + ) + + warnings = list() + result = {"changed": False, "warnings": warnings} + + rpc = str(module.params["rpc"]).replace("_", "-") + + if all((module.check_mode, not rpc.startswith("get"))): + module.fail_json(msg="invalid rpc for running in check_mode") + + args = module.params["args"] or {} + attrs = module.params["attrs"] or {} + + xattrs = {"format": module.params["output"]} + + for key, value in iteritems(attrs): + xattrs.update({key: value}) + + element = Element(module.params["rpc"], xattrs) + + for key, value in iteritems(args): + key = str(key).replace("_", "-") + if isinstance(value, list): + for item in value: + child = SubElement(element, key) + if item is not True: + child.text = item + else: + child = SubElement(element, key) + if value is not True: + child.text = value + + reply = exec_rpc(module, tostring(element), ignore_warning=False) + + result["xml"] = tostring(reply) + + if module.params["output"] == "text": + data = reply.find(".//output") + result["output"] = data.text.strip() + result["output_lines"] = result["output"].split("\n") + + elif module.params["output"] == "json": + result["output"] = module.from_json(reply.text.strip()) + + else: + result["output"] = tostring(reply).split("\n") + + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_scp.py b/ansible_collections/juniper/device/plugins/modules/junos_scp.py new file mode 100644 index 00000000..0fe11bfc --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_scp.py @@ -0,0 +1,239 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2018, 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 + + +DOCUMENTATION = """ +module: junos_scp +author: Christian Giese (@GIC-de) +short_description: Transfer files from or to remote devices running Junos +description: +- This module transfers files via SCP from or to remote devices running Junos. +version_added: 1.0.0 +extends_documentation_fragment: +- junipernetworks.junos.junos +deprecated: + why: Updated modules released with more functionality + alternative: Use M(ansible.netcommon.net_get), M(ansible.netcommon.net_put) instead. + removed_at_date: '2025-01-01' +options: + src: + description: + - The C(src) argument takes a single path, or a list of paths to be transferred. + The argument C(recursive) must be C(true) to transfer directories. + required: true + type: list + elements: path + dest: + description: + - The C(dest) argument specifies the path in which to receive the files. + type: path + default: . + recursive: + description: + - The C(recursive) argument enables recursive transfer of files and directories. + type: bool + default: no + remote_src: + description: + - The C(remote_src) argument enables the download of files (I(scp get)) from the + remote device. The default behavior is to upload files (I(scp put)) to the remote + device. + type: bool + default: no + ssh_private_key_file: + description: + - The C(ssh_private_key_file) argument is path to the SSH private key file. This + can be used if you need to provide a private key rather than loading the key + into the ssh-key-ring/environment + type: path + ssh_config: + description: + - The C(ssh_config) argument is path to the SSH configuration file. This can be + used to load SSH information from a configuration file. If this option is not + given by default ~/.ssh/config is queried. + type: path + provider: + description: + - B(Deprecated) + - 'Starting with Ansible 2.5 we recommend using C(connection: network_cli) or + C(connection: netconf).' + - For more information please see the L(Junos OS Platform Options guide, ../network/user_guide/platform_junos.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 + port: + description: + - Specifies the port to use when building the connection to the remote device. The + port value will default to the well known SSH port of 22 (for C(transport=cli)) + or port 830 (for C(transport=netconf)) device. + type: int + 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 + 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 + transport: + description: + - Configures the transport connection to use when connecting to the remote + device. + type: str + default: netconf + choices: + - cli + - netconf +requirements: +- junos-eznc +- ncclient (>=v0.5.2) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vMX JUNOS version 17.3R1.10. +- Works with C(local) connections only. +- Since this module uses junos-eznc to establish connection with junos device the + netconf configuration parameters needs to be passed using module options for example + C(ssh_config) unlike other junos modules that uses C(netconf) connection type. +""" + +EXAMPLES = """ +# the required set of connection arguments have been purposely left off +# the examples for brevity +- name: upload local file to home directory on remote device + junipernetworks.junos.junos_scp: + src: test.tgz + +- name: upload local file to tmp directory on remote device + junipernetworks.junos.junos_scp: + src: test.tgz + dest: /tmp/ + +- name: download file from remote device + junipernetworks.junos.junos_scp: + src: test.tgz + remote_src: true + +- name: ssh config file path for jumphost config + junipernetworks.junos.junos_scp: + src: test.tgz + remote_src: true + ssh_config: /home/user/customsshconfig +""" + +RETURN = """ +changed: + description: always true + returned: always + type: bool +""" +from ansible.module_utils._text import to_native +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + get_device, + junos_argument_spec, +) + + +try: + from jnpr.junos.utils.scp import SCP + + HAS_PYEZ = True +except ImportError: + HAS_PYEZ = False + + +def transfer_files(module, device): + dest = module.params["dest"] + recursive = module.params["recursive"] + + with SCP(device) as scp: + for src in module.params["src"]: + if module.params["remote_src"]: + scp.get(src.strip(), local_path=dest, recursive=recursive) + else: + scp.put(src.strip(), remote_path=dest, recursive=recursive) + + +def main(): + """Main entry point for Ansible module execution""" + argument_spec = dict( + src=dict(type="list", required=True, elements="path"), + dest=dict(type="path", required=False, default="."), + recursive=dict(type="bool", default=False), + remote_src=dict(type="bool", default=False), + ssh_private_key_file=dict(type="path"), + ssh_config=dict(type="path"), + ) + + argument_spec.update(junos_argument_spec) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + if module.params["provider"] is None: + module.params["provider"] = {} + + if not HAS_PYEZ: + module.fail_json( + msg="junos-eznc is required but does not appear to be installed. " + "It can be installed using `pip install junos-eznc`", + ) + + result = dict(changed=True) + + if not module.check_mode: + # open pyez connection and transfer files via SCP + try: + device = get_device(module) + transfer_files(module, device) + except Exception as ex: + module.fail_json(msg=to_native(ex)) + finally: + try: + # close pyez connection and ignore exceptions + device.close() + except Exception: + pass + + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_security_policies.py b/ansible_collections/juniper/device/plugins/modules/junos_security_policies.py new file mode 100644 index 00000000..38973ed8 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_security_policies.py @@ -0,0 +1,2705 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2022 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 junos_security_policies +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +ANSIBLE_METADATA = { + "metadata_version": "1.1", + "status": ["preview"], + "supported_by": "network", +} + +DOCUMENTATION = """ +--- +module: junos_security_policies +version_added: 2.9.0 +short_description: Create and manage security policies on Juniper JUNOS devices +description: This module provides declarative creation and management of security policies on Juniper JUNOS devices +author: Pranav Bhatt (@pranav-bhatt) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: + - This module requires the netconf system service be enabled on the device being managed + - This module works with connection C(netconf) + - See L(the Junos OS Platform Options,https://docsansiblecom/ansible/latest/network/user_guide/platform_junoshtml) + - Tested against JunOS v18.4R1 +options: + config: + description: A dictionary of security policies + type: dict + suboptions: + from_zones: + description: + - List of security zones from which the traffic originates from + type: list + elements: dict + suboptions: + name: + description: + - The name of the security zone from which the traffic originates from + type: str + to_zones: + description: + - List of destination security zones of the traffic + type: list + elements: dict + suboptions: + name: + description: + - The name of the destination security zone of the traffic + type: str + policies: &policy_attributes + description: + - List of policies defined for the associated category + type: list + elements: dict + suboptions: + name: + description: + - Name of the policy + type: str + description: + description: + - Description of the security policy + type: str + scheduler_name: + description: + - Name of the scheduler to run this policy + type: str + match: + description: Configure security policy match criteria + type: dict + suboptions: + application: + description: + - Specify the IP or remote procedure call (RPC) application or set of applications to be used as match criteria + type: dict + suboptions: + names: + description: Name of the predefined or custom application or application set used as match criteria + type: list + elements: str + any: + description: Match any predefined or custom applications or application sets + type: bool + dynamic_application: + description: + - Specify the dynamic applications or dynamic application groups used as match criteria within a security policy + type: dict + suboptions: + names: + description: Specify dynamic applications or dynamic application groups + type: list + elements: str + any: + description: + - Configuring the dynamic application as any installs the policy with the application as a wildcard (default) + type: bool + none: + description: + - Configuring the dynamic application as none ignores classification results from AppID and does not use the + dynamic application in security policy lookups + type: bool + destination_address: + description: + - Define the matching criteria You can specify one or more IP addresses, address sets, or wildcard addresses + type: dict + suboptions: + addresses: + description: + - IP address, IP address set, or address book entry, or wildcard address (represented as ABCD/wildcard_mask) + type: list + elements: str + any: + description: Any IPv4 or IPv6 address + type: bool + any_ipv4: + description: Any IPv4 address + type: bool + any_ipv6: + description: Any IPv6 address + type: bool + destination_address_excluded: + description: + - Exclude destination addresses + type: bool + source_address: + description: + - Define the matching criteria You can specify one or more IP addresses, address sets, or wildcard addresses + type: dict + suboptions: + addresses: + description: + - IP address, IP address set, or address book entry, or wildcard address (represented as ABCD/wildcard_mask) + type: list + elements: str + any: + description: Any IPv4 or IPv6 address + type: bool + any_ipv4: + description: Any IPv4 address + type: bool + any_ipv6: + description: Any IPv6 address + type: bool + source_address_excluded: + description: + - Exclude source addresses + type: bool + source_identity: + description: + - Identifies users and roles to be used as match criteria for a policy + type: dict + suboptions: + names: + description: A list of specific users and roles + type: list + elements: str + any: + description: + - Any user or role, as well as the keywords authenticated_user, unauthenticated_user, + and unknown_user + type: bool + authenticated_user: + description: All users and roles that have been authenticated + type: bool + unauthenticated_user: + description: + - Any user or role that does not have an IP_address mapped to authentication sources and the authentication source + is up and running + type: bool + unknown_user: + description: + - Any user or role that does not have an IP address mapped to authentication sources, because the + authentication source is disconnected from the SRX Series device + type: bool + source_end_user_profile: + description: Source end user profile name + type: str + url_category: + description: URL category + type: dict + suboptions: + names: + description: + - Names of url category to match + type: list + elements: str + any: + description: + - Apply to any url category + type: bool + none: + description: + - Do not apply to the url category + type: bool + from_zone: + description: Identify a single source zone or multiple source zones to be used as a match criteria for a policy + type: dict + suboptions: + names: + description: Name of single or multiple source zone + type: list + elements: str + any: + description: Match any zone + type: bool + junos_host: + description: + - junos-host + type: bool + to_zone: + description: Identify a single destination zone or multiple destination zones to be used as a match criteria for a policy + type: dict + suboptions: + names: + description: Name of single or multiple destination zone + type: list + elements: str + any: + description: Match any zone + type: bool + junos_host: + description: + - junos-host + type: bool + then: + description: Specify the policy action to be performed when packets match the defined criteria + type: dict + suboptions: + count: + description: + - Enable a count, in bytes or kilobytes, of all network traffic the policy allows to pass through the device + in both directions; the originating traffic from the client to the server (from the from_zone to the to_zone), + and the return traffic from the server to the originating client + type: bool + deny: + description: Block the service at the firewall The device drops the packets + type: bool + reject: + description: + - Block the service at the firewall The device drops the packet and sends a TCP reset (RST) segment to the + source host for TCP traffic and an ICMP "destination unreachable, port unreachable" + message (type 3, code 3) for UDP traffic + type: dict + suboptions: + enable: + description: + - Enable rejection of packets based on match criteria + type: bool + profile: + description: + - You can chose to provide a notification to the clients or redirect client request to an informative + Web page when a policy blocks HTTP or HTTPS traffic with a deny or reject action + type: str + ssl_proxy: + description: + - You can apply a redirect SSL proxy profile when a policy blocks HTTPS traffic with a reject action + When you apply am SSL proxy profile, SSL proxy decrypts the traffic and application + identification functionality identifies the application + type: dict + suboptions: + enable: + description: + - Enable SSL proxy + type: bool + profile_name: + description: Name of SSL proxy profile + type: str + log: + description: + - Log traffic information for a specific policy Traffic information is logged when a + session begins (session_init) or closes (session_close) + type: dict + suboptions: + session_init: + description: + - Enable logging on session initialization time + type: bool + session_close: + description: + - Enable logging on session close time + type: bool + permit: + description: Block the service at the firewall The device drops the packets + type: dict + suboptions: + application_services: + description: + - Enable application services within a security policy + type: dict + suboptions: + advanced_anti_malware_policy: + description: + - Specify advanced_anti_malware policy name + type: str + application_firewalls: + description: + - Specify the rule sets configured as part of application firewall to be applied to the permitted traffic + type: list + elements: dict + suboptions: + rule_set: + description: + - name of rule set to use + type: str + application_traffic_control_rule_set: + description: + - Specify the rule set configured as part of AppQoS, application_aware quality of service, + to be applied to the permitted traffic + type: str + gprs_gtp_profile: + description: + - Specify GPRS tunneling protocol profile name + type: str + gprs_sctp_profile: + description: + - Specify GPRS stream control protocol profile name + type: str + icap_redirect: + description: + - Specify icap redirect profile name + type: str + idp: + description: + - Intrusion Detection and Prevention (IDP) + type: bool + idp_policy: + description: + - Specify IDP policy name + type: str + packet_capture: + description: + - Option to enable or disable packet capture + type: bool + redirect_wx: + description: + - Specify the WX redirection needed for the packets that arrive from the LAN + type: bool + reverse_redirect_wx: + description: + - Specify the WX redirection needed for the reverse flow of the packets that arrive from the WAN + type: bool + security_intelligence_policy: + description: + - Specify security_intelligence policy name + type: str + security_intelligence: + description: Specify the security intelligence feed post action + type: dict + suboptions: + add_destination_identity_to_feed: + description: Add destination user identity to the security feed + type: str + add_destination_ip_to_feed: + description: Add the destination IP address to the security feed + type: str + add_source_ip_to_feed: + description: Add the source IP address to the security feed + type: str + add_source_identity_to_feed: + description: Add source user identity to the security feed + type: str + ssl_proxy: + description: You can apply a redirect SSL proxy profile when a policy blocks HTTPS traffic with a reject action + type: dict + suboptions: + enable: + description: + - Enable SSL proxy + type: bool + profile_name: + description: Name of SSL proxy profile + type: str + uac_policy: + description: + - Enable Unified Access Control (UAC) for the security policy + type: dict + suboptions: + enable: + description: + - Enable Unified Access Control (UAC) + type: bool + captive_portal: + description: + - Specify the preconfigured security policy for captive portal on the Junos OS Enforcer to enable the + captive portal feature + type: str + utm_policy: + description: + - Specify UTM policy name + type: str + destination_address: + description: + - Specify whether the traffic permitted by the security policy is limited to packets + where the destination IP address has been translated by means of a destination NAT rule + or to packets where the destination IP address has not been translated + choices: + - drop-translated + - drop-untranslated + type: str + firewall_authentication: + description: Configure firewall authentication methods + type: dict + suboptions: + pass_through: + description: + - Configure pass-through firewall user authentication + type: dict + suboptions: + access_profile: + description: + - Specify the name of the access profile + type: str + client_match: + description: + - Specify the name of the users or user groups in a profile who are allowed access by this policy + type: str + ssl_termination_profile: + description: + - Specify the SSL termination profile used for SSL offloading + type: str + web_redirect: + description: + - Enable redirecting an HTTP request to the device and redirecting the client system to a + webpage for authentication + type: bool + web_redirect_to_https: + description: + - Redirect unauthenticated HTTP requests to the internal HTTPS Web server of the device + type: bool + auth_only_browser: + description: + - Configure firewall authentication to ignore non-browser HTTP/HTTPS traffic + type: bool + auth_user_agent: + description: + - Specify a user-agent value to be used to verify that the user's browser traffic is HTTP/HTTPS traffic + type: str + push_to_identity_management: + description: enables pushing to identity management devices + type: bool + user_firewall: + description: + - Configure user role firewall authentication, and map the source IP address to the username and its + associated roles (groups) + type: dict + suboptions: + access_profile: + description: + - Specify the name of the access profile to be used for authentication + type: str + domain: + description: + - Specify the name of the domain where firewall authentication occurs in the event that the + Windows Management Instrumentation client (WMIC) is not available to get + IP_to_user mapping for the integrated user firewall feature + type: str + ssl_termination_profile: + description: + - For HTTPS traffic, specify the name of the SSL termination profile used for SSL offloading + type: str + web_redirect: + description: + - Enable webpage redirection + type: bool + web_redirect_to_https: + description: + - Enable redirection to HTTPS + type: bool + auth_only_browser: + description: + - Configure firewall authentication to ignore non-browser HTTP/HTTPS traffic + type: bool + auth_user_agent: + description: + - Specify a user-agent value to be used to verify that the user's browser traffic is HTTP/HTTPS traffic + type: str + web_authentication: + description: + - Specify that the policy allows access to users or user groups who have previously been authenticated by + Web authentication + type: list + elements: str + tcp_options: + description: + - Specify the TCP options for each policy You can configure sync and sequence checks for each policy + based on your requirements, and, because each policy has two directions, you can configure a + TCP MSS value for both directions or for just one direction + type: dict + suboptions: + initial_tcp_mss: + description: + - Configure the TCP maximum segment size (MSS) for packets that arrive at the + ingress interface (initial direction), match a specific policy, and for which a session is created + type: int + reverse_tcp_mss: + description: + - Configure the TCP maximum segment size (MSS) for packets that match a specific policy and travel in the + reverse direction of a session + type: int + sequence_check_required: + description: + - Enable sequence check per policy The sequence_check_required value overrides the global value no_sequence_check + type: bool + syn_check_required: + description: + - Enable sync check per policy The syn_check_required value overrides the global value no_syn_check + type: bool + window_scale: + description: + - Enable window_scale per policy + type: bool + tunnel: + description: Encapsulate outgoing IP packets and decapsulate incoming IP packets + type: dict + suboptions: + ipsec_vpn: + description: + - name of the ipsec policy + type: str + pair_policy: + description: + - name of the pair policy + type: str + global: + description: + - List of global security policies + type: dict + suboptions: + policies: *policy_attributes + running_config: + description: + - This option is used only with state I(parsed) + - The value of this option should be the output received from the JunOS device + by executing the command B(show configuration security policies) + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + choices: + - merged + - replaced + - overridden + - deleted + - rendered + - gathered + - parsed + default: merged + 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(replaced) will replace the running configuration with the provided + configuration + - The state I(replaced) and state I(overridden) have the same behaviour + - 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 security policies detail) executed on device For state I(parsed) active + connection to remote host is not required + type: str +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# vagrant@vsrx> show security policies +# Default policy: deny-all +# Pre ID default policy: permit-all +# Global policies: +# Policy: test_glob, State: enabled, Index: 4, Scope Policy: 0, Sequence number: 1 +# From zones: any +# To zones: any +# Source addresses: any-ipv4 +# Destination addresses: any-ipv4 +# Applications: any +# Action: deny +# +# vagrant@vsrx> show security zones +# +# Security zone: one +# Send reset for non-SYN session TCP packets: Off +# Policy configurable: Yes +# Interfaces bound: 1 +# Interfaces: +# ge-0/0/0.0 +# +# Security zone: three +# Send reset for non-SYN session TCP packets: Off +# Policy configurable: Yes +# Interfaces bound: 1 +# Interfaces: +# ge-0/0/2.0 +# +# Security zone: two +# Send reset for non-SYN session TCP packets: Off +# Policy configurable: Yes +# Interfaces bound: 1 +# Interfaces: +# ge-0/0/1.0 +# +# Security zone: junos-host +# Send reset for non-SYN session TCP packets: Off +# Policy configurable: Yes +# Interfaces bound: 0 +# Interfaces: +# +- junipernetworks.junos.junos_security_policies: + config: + from_zones: + - name: one + to_zones: + - name: two + policies: + - match: + application: + names: + - junos-dhcp-relay + - junos-finger + destination_address: + addresses: + - a2 + - a4 + destination_address_excluded: true + dynamic_application: + names: + - any + source_address: + addresses: + - a1 + - a3 + source_address_excluded: true + source_end_user_profile: test_end_user_profile + source_identity: + unknown_user: true + url_category: + names: + - Enhanced_Web_Chat + name: test_policy_1 + then: + count: true + deny: true + log: session-close + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + addresses: + - a1 + name: test_policy_2 + then: + reject: + enable: true + profile: test_dyn_app + ssl_proxy: + enable: true + profile_name: SECURITY-SSL-PROXY + - name: three + policies: + - match: + application: + any: true + destination_address: + addresses: + - a2 + source_address: + addresses: + - a1 + name: test_policy_3 + then: + permit: + application_services: + application_traffic_control_rule_set: test_traffic_control + gprs_gtp_profile: gtp1 + icap_redirect: test_icap + reverse_redirect_wx: 'True' + uac_policy: + enable: true + firewall_authentication: + push_to_identity_management: true + web_authentication: + - FWClient1 + tcp_options: + initial_tcp_mss: 64 + window_scale: true + global: + policies: + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any_ipv6: true + name: test_glob_1 + then: + deny: true + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any_ipv6: true + name: test_glob_2 + then: + deny: true + state: merged +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "from_zones": [ +# { +# "name": "one", +# "to_zones": [ +# { +# "name": "two", +# "policies": [ +# { +# "match": { +# "application": { +# "names": [ +# "junos-dhcp-relay", +# "junos-finger" +# ] +# }, +# "destination_address": { +# "addresses": [ +# "a2", +# "a4" +# ] +# }, +# "destination_address_excluded": true, +# "dynamic_application": { +# "names": [ +# "any" +# ] +# }, +# "source_address": { +# "addresses": [ +# "a1", +# "a3" +# ] +# }, +# "source_address_excluded": true, +# "source_end_user_profile": "test_end_user_profile", +# "source_identity": { +# "unknown_user": true +# }, +# "url_category": { +# "names": [ +# "Enhanced_Web_Chat" +# ] +# } +# }, +# "name": "test_policy_1", +# "then": { +# "count": true, +# "deny": true, +# "log": "session-close" +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "addresses": [ +# "a1" +# ] +# } +# }, +# "name": "test_policy_2", +# "then": { +# "reject": { +# "enable": true, +# "profile": "test_dyn_app", +# "ssl_proxy": { +# "enable": true, +# "profile_name": "SECURITY-SSL-PROXY" +# } +# } +# } +# } +# ] +# }, +# { +# "name": "three", +# "policies": [ +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "addresses": [ +# "a2" +# ] +# }, +# "source_address": { +# "addresses": [ +# "a1" +# ] +# } +# }, +# "name": "test_policy_3", +# "then": { +# "permit": { +# "application_services": { +# "application_traffic_control_rule_set": "test_traffic_control", +# "gprs_gtp_profile": "gtp1", +# "icap_redirect": "test_icap", +# "reverse_redirect_wx": "True", +# "uac_policy": { +# "enable": true +# } +# }, +# "firewall_authentication": { +# "push_to_identity_management": true, +# "web_authentication": [ +# "FWClient1" +# ] +# }, +# "tcp_options": { +# "initial_tcp_mss": 64, +# "window_scale": true +# } +# } +# } +# } +# ] +# } +# ] +# } +# ], +# "global": { +# "policies": [ +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv4": true +# }, +# "source_address": { +# "any_ipv4": true +# } +# }, +# "name": "test_glob", +# "then": { +# "deny": true +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any_ipv6": true +# } +# }, +# "name": "test_glob_1", +# "then": { +# "deny": true +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any_ipv6": true +# } +# }, +# "name": "test_glob_2", +# "then": { +# "deny": true +# } +# } +# ] +# } +# }, +# "before": { +# "global": { +# "policies": [ +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv4": true +# }, +# "source_address": { +# "any_ipv4": true +# } +# }, +# "name": "test_glob", +# "then": { +# "deny": true +# } +# } +# ] +# } +# }, +# "changed": true, +# "commands": " +# +# +# one +# two +# +# test_policy_1 +# +# a1 +# a3 +# +# a2 +# a4 +# +# junos-dhcp-relay +# junos-finger +# test_end_user_profile +# unknown-user +# Enhanced_Web_Chat +# any +# +# +# +# +# +# +# +# +# +# +# test_policy_2 +# +# a1 +# any-ipv6 +# any +# +# +# +# test_dyn_app +# +# SECURITY-SSL-PROXY +# +# +# +# +# +# +# one +# three +# +# test_policy_3 +# +# a1 +# a2 +# any +# +# +# +# +# +# test_traffic_control +# +# gtp1 +# test_icap +# +# +# +# +# +# +# FWClient1 +# +# +# +# 64 +# +# +# +# +# +# +# +# +# test_glob_1 +# +# any-ipv6 +# any-ipv6 +# any +# +# +# +# +# +# +# test_glob_2 +# +# any-ipv6 +# any-ipv6 +# any +# +# +# +# +# +# +# +# +# " +# After state +# ----------- +# +# vagrant@vsrx> show security policies +# Default policy: deny-all +# Pre ID default policy: permit-all +# From zone: one, To zone: two +# Policy: test_policy_1, State: enabled, Index: 5, Scope Policy: 0, Sequence number: 1 +# Source addresses(excluded): a1, a3 +# Destination addresses(excluded): a2, a4 +# Source-end-user-profile: test_end_user_profile(1) +# Applications: junos-dhcp-relay, junos-finger +# Dynamic Applications: any +# Url-category: Enhanced_Web_Chat +# Source identities: unknown-user +# Action: deny, log, count +# Policy: test_policy_2, State: enabled, Index: 6, Scope Policy: 0, Sequence number: 2 +# Source addresses: a1 +# Destination addresses: any-ipv6 +# Applications: any +# Action: reject +# dynapp-redir-profile: test_dyn_app(1) +# From zone: one, To zone: three +# Policy: test_policy_3, State: enabled, Index: 7, Scope Policy: 0, Sequence number: 1 +# Source addresses: a1 +# Destination addresses: a2 +# Applications: any +# Action: permit, firewall authentication, application services, unified access control +# Application traffic control: test_traffic_control +# Global policies: +# Policy: test_glob, State: enabled, Index: 4, Scope Policy: 0, Sequence number: 1 +# From zones: any +# To zones: any +# Source addresses: any-ipv4 +# Destination addresses: any-ipv4 +# Applications: any +# Action: deny +# Policy: test_glob_1, State: enabled, Index: 8, Scope Policy: 0, Sequence number: 2 +# From zones: any +# To zones: any +# Source addresses: any-ipv6 +# Destination addresses: any-ipv6 +# Applications: any +# Action: deny +# Policy: test_glob_2, State: enabled, Index: 9, Scope Policy: 0, Sequence number: 3 +# From zones: any +# To zones: any +# Source addresses: any-ipv6 +# Destination addresses: any-ipv6 +# Applications: any +# Action: deny + + +# Using Replaced +# Before state +# ------------ +# +# vagrant@vsrx> show security policies +# Default policy: deny-all +# Pre ID default policy: permit-all +# From zone: one, To zone: two +# Policy: test_policy_1, State: enabled, Index: 5, Scope Policy: 0, Sequence number: 1 +# Source addresses(excluded): a1, a3 +# Destination addresses(excluded): a2, a4 +# Source-end-user-profile: test_end_user_profile(1) +# Applications: junos-dhcp-relay, junos-finger +# Dynamic Applications: any +# Url-category: Enhanced_Web_Chat +# Source identities: unknown-user +# Action: deny, log, count +# Policy: test_policy_2, State: enabled, Index: 6, Scope Policy: 0, Sequence number: 2 +# Source addresses: a1 +# Destination addresses: any-ipv6 +# Applications: any +# Action: reject +# dynapp-redir-profile: test_dyn_app(1) +# From zone: one, To zone: three +# Policy: test_policy_3, State: enabled, Index: 7, Scope Policy: 0, Sequence number: 1 +# Source addresses: a1 +# Destination addresses: a2 +# Applications: any +# Action: permit, firewall authentication, application services, unified access control +# Application traffic control: test_traffic_control +# Global policies: +# Policy: test_glob, State: enabled, Index: 4, Scope Policy: 0, Sequence number: 1 +# From zones: any +# To zones: any +# Source addresses: any-ipv4 +# Destination addresses: any-ipv4 +# Applications: any +# Action: deny +# Policy: test_glob_1, State: enabled, Index: 8, Scope Policy: 0, Sequence number: 2 +# From zones: any +# To zones: any +# Source addresses: any-ipv6 +# Destination addresses: any-ipv6 +# Applications: any +# Action: deny +# Policy: test_glob_2, State: enabled, Index: 9, Scope Policy: 0, Sequence number: 3 +# From zones: any +# To zones: any +# Source addresses: any-ipv6 +# Destination addresses: any-ipv6 +# Applications: any +# Action: deny +# +- junipernetworks.junos.junos_security_policies: + config: + global: + policies: + - description: test update + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any: true + name: test_glob_3 + then: + deny: true + state: replaced +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "global": { +# "policies": [ +# { +# "description": "test update", +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any": true +# } +# }, +# "name": "test_glob_3", +# "then": { +# "deny": true +# } +# } +# ] +# } +# }, +# "before": { +# "from_zones": [ +# { +# "name": "one", +# "to_zones": [ +# { +# "name": "two", +# "policies": [ +# { +# "match": { +# "application": { +# "names": [ +# "junos-dhcp-relay", +# "junos-finger" +# ] +# }, +# "destination_address": { +# "addresses": [ +# "a2", +# "a4" +# ] +# }, +# "destination_address_excluded": true, +# "dynamic_application": { +# "names": [ +# "any" +# ] +# }, +# "source_address": { +# "addresses": [ +# "a1", +# "a3" +# ] +# }, +# "source_address_excluded": true, +# "source_end_user_profile": "test_end_user_profile", +# "source_identity": { +# "unknown_user": true +# }, +# "url_category": { +# "names": [ +# "Enhanced_Web_Chat" +# ] +# } +# }, +# "name": "test_policy_1", +# "then": { +# "count": true, +# "deny": true, +# "log": "session-close" +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "addresses": [ +# "a1" +# ] +# } +# }, +# "name": "test_policy_2", +# "then": { +# "reject": { +# "enable": true, +# "profile": "test_dyn_app", +# "ssl_proxy": { +# "enable": true, +# "profile_name": "SECURITY-SSL-PROXY" +# } +# } +# } +# } +# ] +# }, +# { +# "name": "three", +# "policies": [ +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "addresses": [ +# "a2" +# ] +# }, +# "source_address": { +# "addresses": [ +# "a1" +# ] +# } +# }, +# "name": "test_policy_3", +# "then": { +# "permit": { +# "application_services": { +# "application_traffic_control_rule_set": "test_traffic_control", +# "gprs_gtp_profile": "gtp1", +# "icap_redirect": "test_icap", +# "reverse_redirect_wx": "True", +# "uac_policy": { +# "enable": true +# } +# }, +# "firewall_authentication": { +# "push_to_identity_management": true, +# "web_authentication": [ +# "FWClient1" +# ] +# }, +# "tcp_options": { +# "initial_tcp_mss": 64, +# "window_scale": true +# } +# } +# } +# } +# ] +# } +# ] +# } +# ], +# "global": { +# "policies": [ +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv4": true +# }, +# "source_address": { +# "any_ipv4": true +# } +# }, +# "name": "test_glob", +# "then": { +# "deny": true +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any_ipv6": true +# } +# }, +# "name": "test_glob_1", +# "then": { +# "deny": true +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any_ipv6": true +# } +# }, +# "name": "test_glob_2", +# "then": { +# "deny": true +# } +# } +# ] +# } +# }, +# "changed": true, +# "commands": " +# +# +# +# +# test_glob_3 +# test update +# +# any +# any-ipv6 +# any +# +# +# +# +# +# +# +# " +# } +# After state +# ----------- +# +# vagrant@vsrx> show security policies +# Default policy: deny-all +# Pre ID default policy: permit-all +# Global policies: +# Policy: test_glob_3, State: enabled, Index: 10, Scope Policy: 0, Sequence number: 1 +# From zones: any +# To zones: any +# Source addresses: any +# Destination addresses: any-ipv6 +# Applications: any +# Action: deny + + +# Using overridden +# +# Before state +# ------------ +# +# vagrant@vsrx> show security policies +# Default policy: deny-all +# Pre ID default policy: permit-all +# From zone: one, To zone: two +# Policy: test_policy_1, State: enabled, Index: 5, Scope Policy: 0, Sequence number: 1 +# Source addresses(excluded): a1, a3 +# Destination addresses(excluded): a2, a4 +# Source-end-user-profile: test_end_user_profile(1) +# Applications: junos-dhcp-relay, junos-finger +# Dynamic Applications: any +# Url-category: Enhanced_Web_Chat +# Source identities: unknown-user +# Action: deny, log, count +# Policy: test_policy_2, State: enabled, Index: 6, Scope Policy: 0, Sequence number: 2 +# Source addresses: a1 +# Destination addresses: any-ipv6 +# Applications: any +# Action: reject +# dynapp-redir-profile: test_dyn_app(1) +# From zone: one, To zone: three +# Policy: test_policy_3, State: enabled, Index: 7, Scope Policy: 0, Sequence number: 1 +# Source addresses: a1 +# Destination addresses: a2 +# Applications: any +# Action: permit, firewall authentication, application services, unified access control +# Application traffic control: test_traffic_control +# Global policies: +# Policy: test_glob, State: enabled, Index: 4, Scope Policy: 0, Sequence number: 1 +# From zones: any +# To zones: any +# Source addresses: any-ipv4 +# Destination addresses: any-ipv4 +# Applications: any +# Action: deny +# Policy: test_glob_1, State: enabled, Index: 8, Scope Policy: 0, Sequence number: 2 +# From zones: any +# To zones: any +# Source addresses: any-ipv6 +# Destination addresses: any-ipv6 +# Applications: any +# Action: deny +# Policy: test_glob_2, State: enabled, Index: 9, Scope Policy: 0, Sequence number: 3 +# From zones: any +# To zones: any +# Source addresses: any-ipv6 +# Destination addresses: any-ipv6 +# Applications: any +# Action: deny +# +- junipernetworks.junos.junos_security_policies: + config: + global: + policies: + - description: test update + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any: true + name: test_glob_3 + then: + deny: true + state: overridden +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "global": { +# "policies": [ +# { +# "description": "test update", +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any": true +# } +# }, +# "name": "test_glob_3", +# "then": { +# "deny": true +# } +# } +# ] +# } +# }, +# "before": { +# "from_zones": [ +# { +# "name": "one", +# "to_zones": [ +# { +# "name": "two", +# "policies": [ +# { +# "match": { +# "application": { +# "names": [ +# "junos-dhcp-relay", +# "junos-finger" +# ] +# }, +# "destination_address": { +# "addresses": [ +# "a2", +# "a4" +# ] +# }, +# "destination_address_excluded": true, +# "dynamic_application": { +# "names": [ +# "any" +# ] +# }, +# "source_address": { +# "addresses": [ +# "a1", +# "a3" +# ] +# }, +# "source_address_excluded": true, +# "source_end_user_profile": "test_end_user_profile", +# "source_identity": { +# "unknown_user": true +# }, +# "url_category": { +# "names": [ +# "Enhanced_Web_Chat" +# ] +# } +# }, +# "name": "test_policy_1", +# "then": { +# "count": true, +# "deny": true, +# "log": "session-close" +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "addresses": [ +# "a1" +# ] +# } +# }, +# "name": "test_policy_2", +# "then": { +# "reject": { +# "enable": true, +# "profile": "test_dyn_app", +# "ssl_proxy": { +# "enable": true, +# "profile_name": "SECURITY-SSL-PROXY" +# } +# } +# } +# } +# ] +# }, +# { +# "name": "three", +# "policies": [ +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "addresses": [ +# "a2" +# ] +# }, +# "source_address": { +# "addresses": [ +# "a1" +# ] +# } +# }, +# "name": "test_policy_3", +# "then": { +# "permit": { +# "application_services": { +# "application_traffic_control_rule_set": "test_traffic_control", +# "gprs_gtp_profile": "gtp1", +# "icap_redirect": "test_icap", +# "reverse_redirect_wx": "True", +# "uac_policy": { +# "enable": true +# } +# }, +# "firewall_authentication": { +# "push_to_identity_management": true, +# "web_authentication": [ +# "FWClient1" +# ] +# }, +# "tcp_options": { +# "initial_tcp_mss": 64, +# "window_scale": true +# } +# } +# } +# } +# ] +# } +# ] +# } +# ], +# "global": { +# "policies": [ +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv4": true +# }, +# "source_address": { +# "any_ipv4": true +# } +# }, +# "name": "test_glob", +# "then": { +# "deny": true +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any_ipv6": true +# } +# }, +# "name": "test_glob_1", +# "then": { +# "deny": true +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any_ipv6": true +# } +# }, +# "name": "test_glob_2", +# "then": { +# "deny": true +# } +# } +# ] +# } +# }, +# "changed": true, +# "commands": " +# +# +# +# +# test_glob_3 +# test update +# +# any +# any-ipv6 +# any +# +# +# +# +# +# +# +# " +# } +# After state +# ----------- +# +# vagrant@vsrx> show security policies +# Default policy: deny-all +# Pre ID default policy: permit-all +# Global policies: +# Policy: test_glob_3, State: enabled, Index: 10, Scope Policy: 0, Sequence number: 1 +# From zones: any +# To zones: any +# Source addresses: any +# Destination addresses: any-ipv6 +# Applications: any +# Action: deny + + +# Using deleted +# +# Before state +# ------------ +# +# vagrant@vsrx> show security policies +# Default policy: deny-all +# Pre ID default policy: permit-all +# Global policies: +# Policy: test_glob_3, State: enabled, Index: 10, Scope Policy: 0, Sequence number: 1 +# From zones: any +# To zones: any +# Source addresses: any +# Destination addresses: any-ipv6 +# Applications: any +# Action: deny +# +- junipernetworks.junos.junos_security_policies: + config: + state: deleted +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# "after": {}, +# "before": { +# "global": { +# "policies": [ +# { +# "description": "test update", +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any": true +# } +# }, +# "name": "test_glob_3", +# "then": { +# "deny": true +# } +# } +# ] +# } +# }, +# "changed": true, +# "commands": " +# " +# +# After state +# ----------- +# +# vagrant@vsrx> show security policies +# Default policy: deny-all +# Pre ID default policy: permit-all + + +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S3.1 +# +# +# +# +# test_ssl_term +# SECURITY-cert +# +# +# +# +# SECURITY-SSL-PROXY +# SECURITY-cert +# +# +# +# +# +# test_icap +# +# test_icap_server +# 10.10.10.11 +# +# +# +# +# +# +# +# test_end_user_profile +# test_domain +# +# device-identity +# Windows +# +# +# +# +# +# +# +# +# global +#
+# a1 +# 200.0.113.0/24 +#
+#
+# a2 +# 201.0.113.0/24 +#
+#
+# a3 +# 202.0.113.0/24 +#
+#
+# a4 +# 203.0.113.0/24 +#
+#
+# +# +# test_dyn_app +# +# +# +# hello_world +# +# +# +# +# +# +# +# one +# two +# +# test_policy_1 +# +# a1 +# a3 +# a2 +# a4 +# +# +# junos-dhcp-relay +# junos-finger +# authenticated-user +# unknown-user +# +# test_end_user_profile +# +# any +# Enhanced_Web_Chat +# +# +# +# +# +# +# +# +# +# +# test_policy_2 +# +# a1 +# any-ipv6 +# any +# +# +# +# test_dyn_app +# +# SECURITY-SSL-PROXY +# +# +# +# +# +# +# one +# three +# +# test_policy_3 +# +# a1 +# a2 +# any +# +# +# +# +# +# FWClient1 +# +# +# +# +# +# +# +# gtp1 +# +# test_icap +# +# test_traffic_control +# +# +# +# +# 64 +# +# +# +# +# +# +# +# +# test_glob_1 +# +# any-ipv6 +# any-ipv6 +# any +# +# +# +# +# +# +# test_glob_2 +# +# any-ipv6 +# any-ipv6 +# any +# +# +# +# +# +# +# +# +# +# one +# +# ge-0/0/0.0 +# +# +# +# two +# +# ge-0/0/1.0 +# +# +# +# three +# +# ge-0/0/2.0 +# +# +# +# +# +# +# gtp1 +# +# +# +#
+# +# +# ge-0/0/0 +# +# 0 +# +# +#
+# 200.0.113.1/24 +#
+#
+#
+#
+#
+# +# ge-0/0/1 +# +# 0 +# +# +#
+# 201.0.113.1/24 +#
+#
+#
+#
+#
+# +# ge-0/0/2 +# +# 0 +# +# +#
+# 202.0.113.1/24 +#
+#
+#
+#
+#
+# +# fxp0 +# +# 0 +# +# +# +# +# +# +# +#
+# +# +# +# test_traffic_control +# +# test_rule +# +# +# +# +# +# +# +# +# +# +# +# +# WEBAUTH +# +# FWClient1 +# +# $9$kq5Ftu1cSe +# +# +# +# +# +# WEBAUTH +# +# +# +#
+# +#
+# +- name: Parse NTP global running config + junipernetworks.junos.junos_security_policies: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# "parsed": { +# "from_zones": [ +# { +# "name": "one", +# "to_zones": [ +# { +# "name": "two", +# "policies": [ +# { +# "match": { +# "application": { +# "names": [ +# "junos-dhcp-relay", +# "junos-finger" +# ] +# }, +# "destination_address": { +# "addresses": [ +# "a2", +# "a4" +# ] +# }, +# "destination_address_excluded": true, +# "dynamic_application": { +# "names": [ +# "any" +# ] +# }, +# "source_address": { +# "addresses": [ +# "a1", +# "a3" +# ] +# }, +# "source_address_excluded": true, +# "source_end_user_profile": "test_end_user_profile", +# "source_identity": { +# "unknown_user": true +# }, +# "url_category": { +# "names": [ +# "Enhanced_Web_Chat" +# ] +# } +# }, +# "name": "test_policy_1", +# "then": { +# "count": true, +# "deny": true, +# "log": "session-close" +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "addresses": [ +# "a1" +# ] +# } +# }, +# "name": "test_policy_2", +# "then": { +# "reject": { +# "enable": true, +# "profile": "test_dyn_app", +# "ssl_proxy": { +# "enable": true, +# "profile_name": "SECURITY-SSL-PROXY" +# } +# } +# } +# } +# ] +# }, +# { +# "name": "three", +# "policies": [ +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "addresses": [ +# "a2" +# ] +# }, +# "source_address": { +# "addresses": [ +# "a1" +# ] +# } +# }, +# "name": "test_policy_3", +# "then": { +# "permit": { +# "application_services": { +# "application_traffic_control_rule_set": "test_traffic_control", +# "gprs_gtp_profile": "gtp1", +# "icap_redirect": "test_icap", +# "reverse_redirect_wx": "True", +# "uac_policy": { +# "enable": true +# } +# }, +# "firewall_authentication": { +# "push_to_identity_management": true, +# "web_authentication": [ +# "FWClient1" +# ] +# }, +# "tcp_options": { +# "initial_tcp_mss": 64, +# "window_scale": true +# } +# } +# } +# } +# ] +# } +# ] +# } +# ], +# "global": { +# "policies": [ +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any_ipv6": true +# } +# }, +# "name": "test_glob_1", +# "then": { +# "deny": true +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any_ipv6": true +# } +# }, +# "name": "test_glob_2", +# "then": { +# "deny": true +# } +# } +# ] +# } +# } + + +# Using gathered +# +# Before state +# ------------ +# +# vagrant@vsrx> show security policies +# Default policy: deny-all +# Pre ID default policy: permit-all +# From zone: one, To zone: two +# Policy: test_policy_1, State: enabled, Index: 4, Scope Policy: 0, Sequence number: 1 +# Source addresses(excluded): a1, a3 +# Destination addresses(excluded): a2, a4 +# Source-end-user-profile: test_end_user_profile(1) +# Applications: junos-dhcp-relay, junos-finger +# Dynamic Applications: any +# Url-category: Enhanced_Web_Chat +# Source identities: authenticated-user, unknown-user +# Action: deny, log, count +# Policy: test_policy_2, State: enabled, Index: 5, Scope Policy: 0, Sequence number: 2 +# Source addresses: a1 +# Destination addresses: any-ipv6 +# Applications: any +# Action: reject +# dynapp-redir-profile: test_dyn_app(1) +# From zone: one, To zone: three +# Policy: test_policy_3, State: enabled, Index: 6, Scope Policy: 0, Sequence number: 1 +# Source addresses: a1 +# Destination addresses: a2 +# Applications: any +# Action: permit, drop-untranslated, firewall authentication, application services, unified access control +# Application traffic control: test_traffic_control +# Global policies: +# Policy: test_glob_1, State: enabled, Index: 7, Scope Policy: 0, Sequence number: 1 +# From zones: any +# To zones: any +# Source addresses: any-ipv6 +# Destination addresses: any-ipv6 +# Applications: any +# Action: deny +# Policy: test_glob_2, State: enabled, Index: 8, Scope Policy: 0, Sequence number: 2 +# From zones: any +# To zones: any +# Source addresses: any-ipv6 +# Destination addresses: any-ipv6 +# Applications: any +# Action: deny +# +- junipernetworks.junos.junos_security_policies: + state: gathered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# "changed": false, +# "gathered": { +# "from_zones": [ +# { +# "name": "one", +# "to_zones": [ +# { +# "name": "two", +# "policies": [ +# { +# "match": { +# "application": { +# "names": [ +# "junos-dhcp-relay", +# "junos-finger" +# ] +# }, +# "destination_address": { +# "addresses": [ +# "a2", +# "a4" +# ] +# }, +# "destination_address_excluded": true, +# "dynamic_application": { +# "names": [ +# "any" +# ] +# }, +# "source_address": { +# "addresses": [ +# "a1", +# "a3" +# ] +# }, +# "source_address_excluded": true, +# "source_end_user_profile": "test_end_user_profile", +# "source_identity": { +# "unknown_user": true +# }, +# "url_category": { +# "names": [ +# "Enhanced_Web_Chat" +# ] +# } +# }, +# "name": "test_policy_1", +# "then": { +# "count": true, +# "deny": true, +# "log": "session-close" +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "addresses": [ +# "a1" +# ] +# } +# }, +# "name": "test_policy_2", +# "then": { +# "reject": { +# "enable": true, +# "profile": "test_dyn_app", +# "ssl_proxy": { +# "enable": true, +# "profile_name": "SECURITY-SSL-PROXY" +# } +# } +# } +# } +# ] +# }, +# { +# "name": "three", +# "policies": [ +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "addresses": [ +# "a2" +# ] +# }, +# "source_address": { +# "addresses": [ +# "a1" +# ] +# } +# }, +# "name": "test_policy_3", +# "then": { +# "permit": { +# "application_services": { +# "application_traffic_control_rule_set": "test_traffic_control", +# "gprs_gtp_profile": "gtp1", +# "icap_redirect": "test_icap", +# "reverse_redirect_wx": "True", +# "uac_policy": { +# "enable": true +# } +# }, +# "firewall_authentication": { +# "push_to_identity_management": true, +# "web_authentication": [ +# "FWClient1" +# ] +# }, +# "tcp_options": { +# "initial_tcp_mss": 64, +# "window_scale": true +# } +# } +# } +# } +# ] +# } +# ] +# } +# ], +# "global": { +# "policies": [ +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any_ipv6": true +# } +# }, +# "name": "test_glob_1", +# "then": { +# "deny": true +# } +# }, +# { +# "match": { +# "application": { +# "any": true +# }, +# "destination_address": { +# "any_ipv6": true +# }, +# "source_address": { +# "any_ipv6": true +# } +# }, +# "name": "test_glob_2", +# "then": { +# "deny": true +# } +# } +# ] +# } +# } +# } + + +# Using rendered +# +# Before state +# ------------ +# +- junipernetworks.junos.junos_security_policies: + config: + global: + policies: + - description: test update + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any: true + name: test_glob_3 + then: + deny: true + state: rendered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "rendered": " +# +# +# +# test_glob_3 +# test update +# +# any +# any-ipv6 +# any +# +# +# +# +# +# +# +# " +""" +RETURN = """ +before: + description: The configuration prior to the module execution. + returned: when state is I(merged), I(replaced), I(overridden) or I(deleted) + type: dict + sample: > + This output will always be in the same format as the + module argspec. +after: + description: The resulting configuration after module execution. + returned: when changed + type: dict + sample: > + This output will always be in the same format as the + module argspec. +commands: + description: The set of commands pushed to the remote device. + returned: when state is I(merged), I(replaced), I(overridden) or I(deleted) + type: list + sample: + - " + + + + + + test_glob_1 + + any-ipv6 + any-ipv6 + any + + + + + + + + + + " +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when state is I(rendered) + type: dict + sample: + - " + + + + + + test_glob_1 + + any-ipv6 + any-ipv6 + any + + + + + + + + + + " +gathered: + description: Facts about the network resource gathered from the remote device as structured data. + returned: when state is I(gathered) + type: dict + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. + returned: when state is I(parsed) + type: dict + sample: > + This output will always be in the same format as the + module argspec. +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.security_policies.security_policies import ( + Security_policiesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.security_policies.security_policies import ( + Security_policies, +) + + +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",)), + ] + + module = AnsibleModule( + argument_spec=Security_policiesArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + + result = Security_policies(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_security_policies_global.py b/ansible_collections/juniper/device/plugins/modules/junos_security_policies_global.py new file mode 100644 index 00000000..89eed120 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_security_policies_global.py @@ -0,0 +1,994 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2022 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 junos_security_policies_global +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +ANSIBLE_METADATA = { + "metadata_version": "1.1", + "status": ["preview"], + "supported_by": "network", +} + +DOCUMENTATION = """ +--- +module: junos_security_policies_global +version_added: 2.9.0 +short_description: Manage global security policy settings on Juniper JUNOS devices +description: This module provides declarative management of global security policy settings on Juniper JUNOS devices +author: Pranav Bhatt (@pranav-bhatt) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: +- This module requires the netconf system service be enabled on the device being managed. +- This module works with connection C(netconf). +- See L(the Junos OS Platform Options,https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html). +- Tested against JunOS v18.4R1 +options: + config: + description: A dictionary of security policies + type: dict + suboptions: + default_policy: + description: + - Configure the default security policy that defines the actions the device takes on a packet that does not match any user-defined policy. + choices: + - deny-all + - permit-all + type: str + policy_rematch: + description: + - Enable the device to reevaluate an active session when its associated security policy is modified. The session remains open if it still matches + the policy that allowed the session initially. + type: dict + suboptions: + enable: + description: + - Enable the device to reevaluate an active session when its associated security policy is modified. + The session remains open if it still matches the policy that allowed the session initially. + type: bool + extensive: + description: + - When a policy is modified or deleted, extensive option checks if any suitable policy permit to keep these sessions alive. + type: bool + policy_stats: + description: + - Configure policies statistics. + type: dict + suboptions: + enable: + description: + - Enable policies statistics. + type: bool + system_wide: + description: + - Configure systemwide policies statistics. + type: bool + pre_id_default_policy_action: + description: + - Configures default policy actions that occur prior to dynamic application identification (AppID) when the packet matches the criteria. + type: dict + suboptions: + log: + description: + - Specifies the log details at session close time and session initialization time. + type: dict + suboptions: + session_init: + description: + - Enable logging on session initialization time + type: bool + session_close: + description: + - Enable logging on session close time + type: bool + session_timeout: + description: + - When you update a session, the session timeout is configured, which specifies the session timeout details in seconds. + type: dict + suboptions: + icmp: + description: + - Timeout value for ICMP sessions (seconds) + type: int + icmp6: + description: + - Timeout value for ICMP6 sessions (seconds) + type: int + ospf: + description: + - Timeout value for OSPF sessions (seconds) + type: int + others: + description: + - Timeout value for other sessions (seconds) + type: int + tcp: + description: + - Timeout value for TCP sessions (seconds) + type: int + udp: + description: + - Timeout value for UDP sessions (seconds) + type: int + traceoptions: + description: A dictionary of security policies + type: dict + suboptions: + file: + description: A dictionary to configure the trace file options + type: dict + suboptions: + files: + description: + - Maximum number of trace files + type: int + match: + description: Refine the output to include lines that contain the regular expression. + type: str + size: + description: The maximum tracefile size + type: str + world_readable: + description: The world_readable option enables any user to read the file. + type: bool + no_world_readable: + description: Log files can be accessed only by the user who configures the tracing operation. + type: bool + flag: + description: + - Trace operation to perform. + choices: + - all + - configuration + - compilation + - ipc + - lookup + - routing-socket + - rules + type: str + no_remote_trace: + description: Disable remote tracing. + type: bool + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the JunOS device + by executing the command B(show security policies). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result. + type: str + state: + choices: + - merged + - replaced + - overridden + - deleted + - rendered + - gathered + - parsed + default: merged + 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. + behaviour for this module. + - The state I(replaced) will replace the running configuration with the provided + configuration + - The state I(replaced) and state I(overridden) have the same behaviour + - 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 security policies detail) executed on device. For state I(parsed) active + connection to remote host is not required. + type: str +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# vagrant@vsrx# show security policies +# default-policy { +# permit-all; +# } +# +- name: Update the running configuration with provided configuration + junipernetworks.junos.junos_security_policies_global: + config: + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + no_world_readable: true + flag: all + no_remote_trace: true + state: merged +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "default_policy": "permit-all", +# "policy_rematch": { +# "enable": true, +# "extensive": true +# }, +# "policy_stats": { +# "enable": true, +# "system_wide": true +# }, +# "pre_id_default_policy_action": { +# "log": { +# "session_init": true +# }, +# "session_timeout": { +# "icmp": 10, +# "others": 10 +# } +# }, +# "traceoptions": { +# "file": { +# "files": 3, +# "match": "/[A-Z]*/gm", +# "no_world_readable": true, +# "size": "10k" +# }, +# "flag": "all", +# "no_remote_trace": true +# } +# }, +# "before": {}, +# "changed": true, +# "commands": " +# +# enable +# 10 +# 10 +# 3/[A-Z]*/gm +# 10kall +# " +# After state +# ----------- +# +# vagrant@vsrx# show security policies +# traceoptions { +# no-remote-trace; +# file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; +# flag all; +# } +# default-policy { +# permit-all; +# } +# policy-rematch extensive; +# policy-stats; +# pre-id-default-policy { +# then { +# log { +# session-init; +# } +# session-timeout { +# icmp 10; +# others 10; +# } +# } +# } +# +# +# Using Replaced +# Before state +# ------------ +# +# vagrant@vsrx# show security policies +# traceoptions { +# no-remote-trace; +# file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; +# flag all; +# } +# default-policy { +# permit-all; +# } +# policy-rematch extensive; +# policy-stats; +# pre-id-default-policy { +# then { +# log { +# session-init; +# } +# session-timeout { +# icmp 10; +# others 10; +# } +# } +# } + +- name: Replace the running configuration with provided configuration + junipernetworks.junos.junos_security_policies_global: + config: + default_policy: deny-all + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + no_world_readable: true + flag: all + no_remote_trace: true + state: replaced +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "default_policy": "deny-all", +# "policy_rematch": { +# "enable": true +# }, +# "policy_stats": { +# "enable": true +# }, +# "pre_id_default_policy_action": { +# "log": { +# "session_init": true +# }, +# "session_timeout": { +# "icmp": 10, +# "others": 10 +# } +# }, +# "traceoptions": { +# "file": { +# "files": 4, +# "match": "/[A-Z]*/gm", +# "no_world_readable": true, +# "size": "10k" +# }, +# "flag": "all", +# "no_remote_trace": true +# } +# }, +# "before": { +# "default_policy": "permit-all", +# "policy_rematch": { +# "enable": true, +# "extensive": true +# }, +# "policy_stats": { +# "enable": true +# }, +# "pre_id_default_policy_action": { +# "log": { +# "session_init": true +# }, +# "session_timeout": { +# "icmp": 10, +# "others": 10 +# } +# }, +# "traceoptions": { +# "file": { +# "files": 4, +# "match": "/[A-Z]*/gm", +# "no_world_readable": true, +# "size": "10k" +# }, +# "flag": "all", +# "no_remote_trace": true +# } +# }, +# "changed": true, +# "commands": " +# +# +# 1010 +# +# 4/[A-Z]*/gm10k +# all +# " +# +# After state +# ----------- +# +# vagrant@vsrx# show security policies +# traceoptions { +# no-remote-trace; +# file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; +# flag all; +# } +# default-policy { +# deny-all; +# } +# policy-rematch; +# policy-stats; +# pre-id-default-policy { +# then { +# log { +# session-init; +# } +# session-timeout { +# icmp 10; +# others 10; +# } +# } +# } + +# Using overridden +# +# Before state +# ------------ +# +# vagrant@vsrx# show security policies +# traceoptions { +# no-remote-trace; +# file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; +# flag all; +# } +# default-policy { +# permit-all; +# } +# policy-rematch extensive; +# policy-stats; +# pre-id-default-policy { +# then { +# log { +# session-init; +# } +# session-timeout { +# icmp 10; +# others 10; +# } +# } +# } + +- name: Replace the running configuration with provided configuration + junipernetworks.junos.junos_security_policies_global: + config: + default_policy: deny-all + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + no_world_readable: true + flag: all + no_remote_trace: true + state: overridden +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "default_policy": "deny-all", +# "policy_rematch": { +# "enable": true +# }, +# "policy_stats": { +# "enable": true +# }, +# "pre_id_default_policy_action": { +# "log": { +# "session_init": true +# }, +# "session_timeout": { +# "icmp": 10, +# "others": 10 +# } +# }, +# "traceoptions": { +# "file": { +# "files": 4, +# "match": "/[A-Z]*/gm", +# "no_world_readable": true, +# "size": "10k" +# }, +# "flag": "all", +# "no_remote_trace": true +# } +# }, +# "before": { +# "default_policy": "permit-all", +# "policy_rematch": { +# "enable": true, +# "extensive": true +# }, +# "policy_stats": { +# "enable": true +# }, +# "pre_id_default_policy_action": { +# "log": { +# "session_init": true +# }, +# "session_timeout": { +# "icmp": 10, +# "others": 10 +# } +# }, +# "traceoptions": { +# "file": { +# "files": 4, +# "match": "/[A-Z]*/gm", +# "no_world_readable": true, +# "size": "10k" +# }, +# "flag": "all", +# "no_remote_trace": true +# } +# }, +# "changed": true, +# "commands": " +# +# +# 1010 +# +# 4/[A-Z]*/gm10k +# all +# " +# +# After state +# ----------- +# +# vagrant@vsrx# show security policies +# traceoptions { +# no-remote-trace; +# file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; +# flag all; +# } +# default-policy { +# deny-all; +# } +# policy-rematch; +# policy-stats; +# pre-id-default-policy { +# then { +# log { +# session-init; +# } +# session-timeout { +# icmp 10; +# others 10; +# } +# } +# } +# +# Using deleted +# +# Before state +# ------------ +# +# vagrant@vsrx# show security policies +# traceoptions { +# no-remote-trace; +# file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; +# flag all; +# } +# default-policy { +# deny-all; +# } +# policy-rematch; +# policy-stats; +# pre-id-default-policy { +# then { +# log { +# session-init; +# } +# session-timeout { +# icmp 10; +# others 10; +# } +# } +# } +# +- name: Delete the running configuration + junipernetworks.junos.junos_security_policies_global: + config: + state: deleted +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": {}, +# "before": { +# "default_policy": "deny-all", +# "policy_rematch": { +# "enable": true +# }, +# "policy_stats": { +# "enable": true +# }, +# "pre_id_default_policy_action": { +# "log": { +# "session_init": true +# }, +# "session_timeout": { +# "icmp": 10, +# "others": 10 +# } +# }, +# "traceoptions": { +# "file": { +# "files": 4, +# "match": "/[A-Z]*/gm", +# "no_world_readable": true, +# "size": "10k" +# }, +# "flag": "all", +# "no_remote_trace": true +# } +# }, +# "changed": true, +# "commands": " +# " +# +# After state +# ----------- +# +# vagrant@vsrx# show security policies +# +# +# Using gathered +# +# Before state +# ------------ +# +# vagrant@vsrx# show security policies +# traceoptions { +# no-remote-trace; +# file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; +# flag all; +# } +# default-policy { +# deny-all; +# } +# policy-rematch; +# policy-stats; +# pre-id-default-policy { +# then { +# log { +# session-init; +# } +# session-timeout { +# icmp 10; +# others 10; +# } +# } +# } +# +- name: Gather the running configuration + junipernetworks.junos.junos_security_policies_global: + config: + state: gathered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "gathered": { +# "default_policy": "deny-all", +# "policy_rematch": { +# "enable": true +# }, +# "policy_stats": { +# "enable": true +# }, +# "pre_id_default_policy_action": { +# "log": { +# "session_init": true +# }, +# "session_timeout": { +# "icmp": 10, +# "others": 10 +# } +# }, +# "traceoptions": { +# "file": { +# "files": 4, +# "match": "/[A-Z]*/gm", +# "no_world_readable": true, +# "size": "10k" +# }, +# "flag": "all", +# "no_remote_trace": true +# } +# } +# +# Using rendered +# +# Before state +# ------------ +# +- name: Render the provided configuration + junipernetworks.junos.junos_security_policies_global: + config: + default_policy: deny-all + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + no_world_readable: true + flag: all + no_remote_trace: true + state: replaced +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "rendered": " +# +# +# 1010 +# 4 +# /[A-Z]*/gm10k +# all +# " +# +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# +# +# +# +# 10k +# 3 +# +# /[A-Z]*/gm +# +# +# all +# +# +# +# +# +# +# +# +# +# enable +# +# +# +# +# +# +# +# 10 +# 10 +# +# +# +# +# +# +# +# +# +- name: Parse security policies global running config + junipernetworks.junos.junos_security_policies_global: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "parsed": { +# "default_policy": "permit-all", +# "policy_rematch": { +# "enable": true, +# "extensive": true +# }, +# "policy_stats": { +# "enable": true, +# "system_wide": true +# }, +# "pre_id_default_policy_action": { +# "log": { +# "session_init": true +# }, +# "session_timeout": { +# "icmp": 10, +# "others": 10 +# } +# }, +# "traceoptions": { +# "file": { +# "files": 3, +# "match": "/[A-Z]*/gm", +# "no_world_readable": true, +# "size": "10k" +# }, +# "flag": "all", +# "no_remote_trace": true +# } +# } +# +# +""" +RETURN = """ +before: + description: The configuration prior to the module execution. + returned: when state is I(merged), I(replaced), I(overridden), I(deleted) + type: dict + sample: > + This output will always be in the same format as the + module argspec. +after: + description: The resulting configuration after module execution. + returned: when changed + type: dict + sample: > + This output will always be in the same format as the + module argspec. +commands: + description: The set of commands pushed to the remote device. + returned: when state is I(merged), I(replaced), I(overridden) or I(deleted) + type: list + sample: + - " + + + + + + + + + + " +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when state is I(rendered) + type: dict + sample: + - " + + + + + + + + + + " +gathered: + description: Facts about the network resource gathered from the remote device as structured data. + returned: when state is I(gathered) + type: dict + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. + returned: when state is I(parsed) + type: dict + sample: > + This output will always be in the same format as the + module argspec. +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.security_policies_global.security_policies_global import ( + Security_policies_globalArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.security_policies_global.security_policies_global import ( + Security_policies_global, +) + + +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",)), + ] + + module = AnsibleModule( + argument_spec=Security_policies_globalArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + + result = Security_policies_global(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_security_zones.py b/ansible_collections/juniper/device/plugins/modules/junos_security_zones.py new file mode 100644 index 00000000..2a97d156 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_security_zones.py @@ -0,0 +1,2002 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2022 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 junos_security_zones +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +ANSIBLE_METADATA = { + "metadata_version": "1.1", + "status": ["preview"], + "supported_by": "network", +} + +DOCUMENTATION = """ +--- +module: junos_security_zones +version_added: 2.9.0 +short_description: Manage security zones on Juniper JUNOS devices +description: This module provides declarative management of security zones on Juniper JUNOS devices +author: Pranav Bhatt (@pranav-bhatt) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: +- This module requires the netconf system service be enabled on the device being managed. +- This module works with connection C(netconf). +- See L(the Junos OS Platform Options,https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html). +- Tested against JunOS v18.4R1 +options: + config: + description: Dictionary of security zone parameters + type: dict + suboptions: + functional_zone_management: + description: + - Functional zone to configure host for out of band management interfaces + type: dict + suboptions: + description: + description: + - Text description of zone + type: str + host_inbound_traffic: &host_inbound_traffic + description: + - Allowed system services & protocols + type: dict + suboptions: + protocols: + description: + - Protocol type of incoming traffic to accept + type: list + elements: dict + suboptions: + name: + description: + - Type of incoming protocol to accept + type: str + except: + description: + - Disallow the specified protocol traffic + type: bool + system_services: + description: + - Type of incoming system-service traffic to accept + type: list + elements: dict + suboptions: + name: + description: + - Type of incoming system-service traffic to accept + type: str + except: + description: + - Disallow the specified incoming system-service traffic + type: bool + interfaces: &interfaces + description: + - Interfaces that are part of this zone + type: list + elements: str + screen: &screen + description: + - Name of ids option object applied to the zone + type: str + zones: + description: + - Security zones + type: list + elements: dict + suboptions: + name: + description: + - Name of the security zone + type: str + address_book: + description: + - Address book entries + type: dict + suboptions: + addresses: + description: + - Define security addresses + type: list + elements: dict + suboptions: + name: + description: + - Name of address + type: str + ip_prefix: + description: + - Numeric IPv4 or IPv6 address with prefix + type: str + description: + description: + - Text description of address + type: str + dns_name: + description: + - DNS address name + type: dict + suboptions: + name: + description: + - Fully qualified hostname + type: str + ipv4_only: + description: + - IPv4 dns address + type: bool + ipv6_only: + description: + - IPv6 dns address + type: bool + range_address: + description: + - Address range + type: dict + suboptions: + from: + description: + - Start of address range + type: str + to: + description: + - End of address range + type: str + wildcard_address: + description: + - Numeric IPv4 wildcard address with in the form of a.d.d.r/netmask + type: str + address_sets: + description: + - Define security address sets + type: list + elements: dict + suboptions: + name: + description: + - Name of address set + type: str + addresses: + description: + - Addresses to be included in this set + type: list + elements: str + address_sets: + description: + - Define an address-set name + type: list + elements: str + description: + description: + - Text description of address set + type: str + advance_policy_based_routing_profile: + description: + - Enable Advance Policy Based Routing on this zone + type: str + advanced_connection_tracking: + description: + - Enable Advance Policy Based Routing on this zone + type: dict + suboptions: + mode: + description: + - Set connection tracking mode + type: str + choices: + - allow-any-host + - allow-target-host + - allow-target-host-port + timeout: + description: + - Timeout value in seconds for advanced-connection-tracking table for this zone + type: int + track_all_policies_to_this_zone: + description: + - Mandate all policies with to-zone set to this zone to do connection track table lookup + type: bool + application_tracking: + description: + - Enable Application tracking support for this zone + type: bool + description: + description: + - Text description of zone + type: str + enable_reverse_reroute: + description: + - Enable Reverse route lookup when there is change in ingress interface + type: bool + host_inbound_traffic: *host_inbound_traffic + interfaces: *interfaces + screen: *screen + source_identity_log: + description: + - Show user and group info in session log for this zone + type: bool + tcp_rst: + description: + - Send RST for NON-SYN packet not matching TCP session + type: bool + unidirectional_session_refreshing: + description: + - Enable unidirectional session refreshing on this zone + type: bool + + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the JunOS device + by executing the command B(show security policies). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result. + type: str + state: + choices: + - merged + - replaced + - overridden + - deleted + - rendered + - gathered + - parsed + default: merged + 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. + behaviour for this module. + - 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 security policies detail) executed on device. For state I(parsed) active + connection to remote host is not required. + type: str +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# vagrant@vsrx# show security zones +# +# [edit] +# vagrant@vsrx# show security zones +# +- name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_security_zones: &merged + config: + functional_zone_management: + description: test description + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + security_zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true + state: merged +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "functional_zone_management": { +# "description": "test description", +# "host_inbound_traffic": { +# "protocols": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "bgp" +# } +# ], +# "system_services": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "dhcp" +# } +# ] +# }, +# "interfaces": [ +# "ge-0/0/1.0", +# "ge-0/0/2.0" +# ], +# "screen": "test_screen" +# }, +# "security_zones": [ +# { +# "address_book": { +# "address_sets": [ +# { +# "addresses": [ +# "test_adr1", +# "test_adr2" +# ], +# "name": "test_adrset1" +# }, +# { +# "addresses": [ +# "test_adr3", +# "test_adr4" +# ], +# "name": "test_adrset2" +# }, +# { +# "address_sets": [ +# "test_adrset1", +# "test_adrset2" +# ], +# "addresses": [ +# "test_adr5" +# ], +# "description": "test description", +# "name": "test_adrset3" +# } +# ], +# "addresses": [ +# { +# "description": "test desc", +# "ip_prefix": "10.0.0.0/24", +# "name": "test_adr1" +# }, +# { +# "dns_name": { +# "ipv6_only": true, +# "name": "1.1.1.1" +# }, +# "name": "test_adr2" +# }, +# { +# "name": "test_adr3", +# "range_address": { +# "from": "10.2.0.1", +# "to": "10.2.0.2" +# } +# }, +# { +# "name": "test_adr4", +# "wildcard_address": "10.3.0.1/24" +# }, +# { +# "description": "test desc", +# "ip_prefix": "10.1.0.0/24", +# "name": "test_adr5" +# } +# ] +# }, +# "advance_policy_based_routing_profile": "test_profile", +# "application_tracking": true, +# "description": "test description", +# "enable_reverse_reroute": true, +# "host_inbound_traffic": { +# "protocols": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "bgp" +# } +# ], +# "system_services": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "dhcp" +# } +# ] +# }, +# "interfaces": [ +# "ge-0/0/3.0", +# "ge-0/0/4.0" +# ], +# "name": "test_sec_zone1", +# "screen": "test_screen", +# "source_identity_log": true, +# "tcp_rst": true +# } +# ] +# }, +# "before": {}, +# "changed": true, +# "commands": +# 't' +# 'est descriptionallbgpalldhcpge-0/0/1.0ge-0/0/2.0test_screentest_sec_zone1test_adr110.0.0.0/24test desctest_adr21.1.1.1test_adr310.2.0.110.2.0.2test_adr410.3.0.1/24test_adr510.1.0.0/24test desctest_adrset1test_adr1test' +# '_adr2test_adrset2test_adr3test_adr4test_adrset3test_adr5test_adrset1test_adrset2test descriptiontest_profiletest descriptionallbgpalldhcpge-0/0/3.0ge-0/0/4.0test_screen' + +# After state +# ----------- +# +# vagrant@vsrx# show system ntp +# functional-zone management { +# interfaces { +# ge-0/0/1.0; +# ge-0/0/2.0; +# } +# screen test_screen; +# host-inbound-traffic { +# system-services { +# all; +# dhcp { +# except; +# } +# } +# protocols { +# all; +# bgp { +# except; +# } +# } +# } +# description "test description"; +# } +# security-zone test_sec_zone1 { +# description "test description"; +# tcp-rst; +# address-book { +# address test_adr1 { +# description "test desc"; +# 10.0.0.0/24; +# } +# address test_adr2 { +# dns-name 1.1.1.1 { +# ipv6-only; +# } +# } +# address test_adr3 { +# range-address 10.2.0.1 { +# to { +# 10.2.0.2; +# } +# } +# } +# address test_adr4 { +# wildcard-address 10.3.0.1/24; +# } +# address test_adr5 { +# description "test desc"; +# 10.1.0.0/24; +# } +# address-set test_adrset1 { +# address test_adr1; +# address test_adr2; +# } +# address-set test_adrset2 { +# address test_adr3; +# address test_adr4; +# } +# address-set test_adrset3 { +# description "test description"; +# address test_adr5; +# address-set test_adrset1; +# address-set test_adrset2; +# } +# } +# screen test_screen; +# host-inbound-traffic { +# system-services { +# all; +# dhcp { +# except; +# } +# } +# protocols { +# all; +# bgp { +# except; +# } +# } +# } +# interfaces { +# ge-0/0/3.0; +# ge-0/0/4.0; +# } +# application-tracking; +# source-identity-log; +# advance-policy-based-routing-profile { +# test_profile; +# } +# enable-reverse-reroute; +# } +# +# +# Using Replaced +# Before state +# ------------ +# +# vagrant@vsrx# show security zones +# functional-zone management { +# interfaces { +# ge-0/0/1.0; +# ge-0/0/2.0; +# } +# screen test_screen; +# host-inbound-traffic { +# system-services { +# all; +# dhcp { +# except; +# } +# } +# protocols { +# all; +# bgp { +# except; +# } +# } +# } +# description "test description"; +# } +# security-zone test_sec_zone1 { +# description "test description"; +# tcp-rst; +# address-book { +# address test_adr1 { +# description "test desc"; +# 10.0.0.0/24; +# } +# address test_adr2 { +# dns-name 1.1.1.1 { +# ipv6-only; +# } +# } +# address test_adr3 { +# range-address 10.2.0.1 { +# to { +# 10.2.0.2; +# } +# } +# } +# address test_adr4 { +# wildcard-address 10.3.0.1/24; +# } +# address test_adr5 { +# description "test desc"; +# 10.1.0.0/24; +# } +# address-set test_adrset1 { +# address test_adr1; +# address test_adr2; +# } +# address-set test_adrset2 { +# address test_adr3; +# address test_adr4; +# } +# address-set test_adrset3 { +# description "test description"; +# address test_adr5; +# address-set test_adrset1; +# address-set test_adrset2; +# } +# } +# screen test_screen; +# host-inbound-traffic { +# system-services { +# all; +# dhcp { +# except; +# } +# } +# protocols { +# all; +# bgp { +# except; +# } +# } +# } +# interfaces { +# ge-0/0/3.0; +# ge-0/0/4.0; +# } +# application-tracking; +# source-identity-log; +# advance-policy-based-routing-profile { +# test_profile; +# } +# enable-reverse-reroute; +# } +# +# + +- name: Replaced running security zones configuration with provided configuration + junipernetworks.junos.junos_security_zones: + config: + functional_zone_management: + description: test description + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + state: replaced +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "functional_zone_management": { +# "description": "test description", +# "host_inbound_traffic": { +# "protocols": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "bgp" +# } +# ], +# "system_services": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "dhcp" +# } +# ] +# }, +# "interfaces": [ +# "ge-0/0/1.0", +# "ge-0/0/2.0" +# ], +# "screen": "test_screen" +# } +# }, +# "before": { +# "functional_zone_management": { +# "description": "test description", +# "host_inbound_traffic": { +# "protocols": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "bgp" +# } +# ], +# "system_services": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "dhcp" +# } +# ] +# }, +# "interfaces": [ +# "ge-0/0/1.0", +# "ge-0/0/2.0" +# ], +# "screen": "test_screen" +# }, +# "security_zones": [ +# { +# "address_book": { +# "address_sets": [ +# { +# "addresses": [ +# "test_adr1", +# "test_adr2" +# ], +# "name": "test_adrset1" +# }, +# { +# "addresses": [ +# "test_adr3", +# "test_adr4" +# ], +# "name": "test_adrset2" +# }, +# { +# "address_sets": [ +# "test_adrset1", +# "test_adrset2" +# ], +# "addresses": [ +# "test_adr5" +# ], +# "description": "test description", +# "name": "test_adrset3" +# } +# ], +# "addresses": [ +# { +# "description": "test desc", +# "ip_prefix": "10.0.0.0/24", +# "name": "test_adr1" +# }, +# { +# "dns_name": { +# "ipv6_only": true, +# "name": "1.1.1.1" +# }, +# "name": "test_adr2" +# }, +# { +# "name": "test_adr3", +# "range_address": { +# "from": "10.2.0.1", +# "to": "10.2.0.2" +# } +# }, +# { +# "name": "test_adr4", +# "wildcard_address": "10.3.0.1/24" +# }, +# { +# "description": "test desc", +# "ip_prefix": "10.1.0.0/24", +# "name": "test_adr5" +# } +# ] +# }, +# "advance_policy_based_routing_profile": "test_profile", +# "application_tracking": true, +# "description": "test description", +# "enable_reverse_reroute": true, +# "host_inbound_traffic": { +# "protocols": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "bgp" +# } +# ], +# "system_services": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "dhcp" +# } +# ] +# }, +# "interfaces": [ +# "ge-0/0/3.0", +# "ge-0/0/4.0" +# ], +# "name": "test_sec_zone1", +# "screen": "test_screen", +# "source_identity_log": true, +# "tcp_rst": true +# } +# ] +# }, +# "changed": true, +# "commands": +# 'test descriptionallbgpalldhcpge-0/0/1.0ge-0/0/2.0test_screen' +# +# +# After state +# ----------- +# +# vagrant@vsrx# show system ntp +# functional-zone management { +# interfaces { +# ge-0/0/1.0; +# ge-0/0/2.0; +# } +# screen test_screen; +# host-inbound-traffic { +# system-services { +# all; +# dhcp { +# except; +# } +# } +# protocols { +# all; +# bgp { +# except; +# } +# } +# } +# description "test description"; +# } +# +# +# Using overridden +# +# Before state +# ------------ +# +# vagrant@vsrx# show security zones +# functional-zone management { +# interfaces { +# ge-0/0/1.0; +# ge-0/0/2.0; +# } +# screen test_screen; +# host-inbound-traffic { +# system-services { +# all; +# dhcp { +# except; +# } +# } +# protocols { +# all; +# bgp { +# except; +# } +# } +# } +# description "test description"; +# } +# security-zone test_sec_zone1 { +# description "test description"; +# tcp-rst; +# address-book { +# address test_adr1 { +# description "test desc"; +# 10.0.0.0/24; +# } +# address test_adr2 { +# dns-name 1.1.1.1 { +# ipv6-only; +# } +# } +# address test_adr3 { +# range-address 10.2.0.1 { +# to { +# 10.2.0.2; +# } +# } +# } +# address test_adr4 { +# wildcard-address 10.3.0.1/24; +# } +# address test_adr5 { +# description "test desc"; +# 10.1.0.0/24; +# } +# address-set test_adrset1 { +# address test_adr1; +# address test_adr2; +# } +# address-set test_adrset2 { +# address test_adr3; +# address test_adr4; +# } +# address-set test_adrset3 { +# description "test description"; +# address test_adr5; +# address-set test_adrset1; +# address-set test_adrset2; +# } +# } +# screen test_screen; +# host-inbound-traffic { +# system-services { +# all; +# dhcp { +# except; +# } +# } +# protocols { +# all; +# bgp { +# except; +# } +# } +# } +# interfaces { +# ge-0/0/3.0; +# ge-0/0/4.0; +# } +# application-tracking; +# source-identity-log; +# advance-policy-based-routing-profile { +# test_profile; +# } +# enable-reverse-reroute; +# } +# +# + +- name: Override running security zones configuration with provided configuration + junipernetworks.junos.junos_security_zones: + config: + functional_zone_management: + description: test description + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + state: overridden +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "functional_zone_management": { +# "description": "test description", +# "host_inbound_traffic": { +# "protocols": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "bgp" +# } +# ], +# "system_services": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "dhcp" +# } +# ] +# }, +# "interfaces": [ +# "ge-0/0/1.0", +# "ge-0/0/2.0" +# ], +# "screen": "test_screen" +# } +# }, +# "before": { +# "functional_zone_management": { +# "description": "test description", +# "host_inbound_traffic": { +# "protocols": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "bgp" +# } +# ], +# "system_services": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "dhcp" +# } +# ] +# }, +# "interfaces": [ +# "ge-0/0/1.0", +# "ge-0/0/2.0" +# ], +# "screen": "test_screen" +# }, +# "security_zones": [ +# { +# "address_book": { +# "address_sets": [ +# { +# "addresses": [ +# "test_adr1", +# "test_adr2" +# ], +# "name": "test_adrset1" +# }, +# { +# "addresses": [ +# "test_adr3", +# "test_adr4" +# ], +# "name": "test_adrset2" +# }, +# { +# "address_sets": [ +# "test_adrset1", +# "test_adrset2" +# ], +# "addresses": [ +# "test_adr5" +# ], +# "description": "test description", +# "name": "test_adrset3" +# } +# ], +# "addresses": [ +# { +# "description": "test desc", +# "ip_prefix": "10.0.0.0/24", +# "name": "test_adr1" +# }, +# { +# "dns_name": { +# "ipv6_only": true, +# "name": "1.1.1.1" +# }, +# "name": "test_adr2" +# }, +# { +# "name": "test_adr3", +# "range_address": { +# "from": "10.2.0.1", +# "to": "10.2.0.2" +# } +# }, +# { +# "name": "test_adr4", +# "wildcard_address": "10.3.0.1/24" +# }, +# { +# "description": "test desc", +# "ip_prefix": "10.1.0.0/24", +# "name": "test_adr5" +# } +# ] +# }, +# "advance_policy_based_routing_profile": "test_profile", +# "application_tracking": true, +# "description": "test description", +# "enable_reverse_reroute": true, +# "host_inbound_traffic": { +# "protocols": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "bgp" +# } +# ], +# "system_services": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "dhcp" +# } +# ] +# }, +# "interfaces": [ +# "ge-0/0/3.0", +# "ge-0/0/4.0" +# ], +# "name": "test_sec_zone1", +# "screen": "test_screen", +# "source_identity_log": true, +# "tcp_rst": true +# } +# ] +# }, +# "changed": true, +# "commands": +# 'test descriptionallbgpalldhcpge-0/0/1.0ge-0/0/2.0test_screen' +# +# +# After state +# ----------- +# +# vagrant@vsrx# show system ntp +# functional-zone management { +# interfaces { +# ge-0/0/1.0; +# ge-0/0/2.0; +# } +# screen test_screen; +# host-inbound-traffic { +# system-services { +# all; +# dhcp { +# except; +# } +# } +# protocols { +# all; +# bgp { +# except; +# } +# } +# } +# description "test description"; +# } +# +# +# Using deleted +# +# Before state +# ------------ +# +# vagrant@vsrx# show security zones +# functional-zone management { +# interfaces { +# ge-0/0/1.0; +# ge-0/0/2.0; +# } +# screen test_screen; +# host-inbound-traffic { +# system-services { +# all; +# dhcp { +# except; +# } +# } +# protocols { +# all; +# bgp { +# except; +# } +# } +# } +# description "test description"; +# } +# +# +- name: Delete running security zones configuration + junipernetworks.junos.junos_security_zones: + config: + state: deleted +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": {}, +# "before": { +# "functional_zone_management": { +# "description": "test description", +# "host_inbound_traffic": { +# "protocols": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "bgp" +# } +# ], +# "system_services": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "dhcp" +# } +# ] +# }, +# "interfaces": [ +# "ge-0/0/1.0", +# "ge-0/0/2.0" +# ], +# "screen": "test_screen" +# } +# }, +# "changed": true, +# "commands": +# "" +# "" +# +# +# After state +# ----------- +# +# vagrant@vsrx# show security zones +# +# [edit] +# Using gathered +# +# Before state +# ------------ +# +# vagrant@vsrx# show system ntp +# functional-zone management { +# interfaces { +# ge-0/0/1.0; +# ge-0/0/2.0; +# } +# screen test_screen; +# host-inbound-traffic { +# system-services { +# all; +# dhcp { +# except; +# } +# } +# protocols { +# all; +# bgp { +# except; +# } +# } +# } +# description "test description"; +# } +# security-zone test_sec_zone1 { +# description "test description"; +# tcp-rst; +# address-book { +# address test_adr1 { +# description "test desc"; +# 10.0.0.0/24; +# } +# address test_adr2 { +# dns-name 1.1.1.1 { +# ipv6-only; +# } +# } +# address test_adr3 { +# range-address 10.2.0.1 { +# to { +# 10.2.0.2; +# } +# } +# } +# address test_adr4 { +# wildcard-address 10.3.0.1/24; +# } +# address test_adr5 { +# description "test desc"; +# 10.1.0.0/24; +# } +# address-set test_adrset1 { +# address test_adr1; +# address test_adr2; +# } +# address-set test_adrset2 { +# address test_adr3; +# address test_adr4; +# } +# address-set test_adrset3 { +# description "test description"; +# address test_adr5; +# address-set test_adrset1; +# address-set test_adrset2; +# } +# } +# screen test_screen; +# host-inbound-traffic { +# system-services { +# all; +# dhcp { +# except; +# } +# } +# protocols { +# all; +# bgp { +# except; +# } +# } +# } +# interfaces { +# ge-0/0/3.0; +# ge-0/0/4.0; +# } +# application-tracking; +# source-identity-log; +# advance-policy-based-routing-profile { +# test_profile; +# } +# enable-reverse-reroute; +# } +- name: Gather running security zones configuration + junipernetworks.junos.junos_security_zones: + state: gathered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "gathered": { +# "functional_zone_management": { +# "description": "test description", +# "host_inbound_traffic": { +# "protocols": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "bgp" +# } +# ], +# "system_services": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "dhcp" +# } +# ] +# }, +# "interfaces": [ +# "ge-0/0/1.0", +# "ge-0/0/2.0" +# ], +# "screen": "test_screen" +# }, +# "security_zones": [ +# { +# "address_book": { +# "address_sets": [ +# { +# "addresses": [ +# "test_adr1", +# "test_adr2" +# ], +# "name": "test_adrset1" +# }, +# { +# "addresses": [ +# "test_adr3", +# "test_adr4" +# ], +# "name": "test_adrset2" +# }, +# { +# "address_sets": [ +# "test_adrset1", +# "test_adrset2" +# ], +# "addresses": [ +# "test_adr5" +# ], +# "description": "test description", +# "name": "test_adrset3" +# } +# ], +# "addresses": [ +# { +# "description": "test desc", +# "ip_prefix": "10.0.0.0/24", +# "name": "test_adr1" +# }, +# { +# "dns_name": { +# "ipv6_only": true, +# "name": "1.1.1.1" +# }, +# "name": "test_adr2" +# }, +# { +# "name": "test_adr3", +# "range_address": { +# "from": "10.2.0.1", +# "to": "10.2.0.2" +# } +# }, +# { +# "name": "test_adr4", +# "wildcard_address": "10.3.0.1/24" +# }, +# { +# "description": "test desc", +# "ip_prefix": "10.1.0.0/24", +# "name": "test_adr5" +# } +# ] +# }, +# "advance_policy_based_routing_profile": "test_profile", +# "application_tracking": true, +# "description": "test description", +# "enable_reverse_reroute": true, +# "host_inbound_traffic": { +# "protocols": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "bgp" +# } +# ], +# "system_services": [ +# { +# "name": "all" +# }, +# { +# "except": true, +# "name": "dhcp" +# } +# ] +# }, +# "interfaces": [ +# "ge-0/0/3.0", +# "ge-0/0/4.0" +# ], +# "name": "test_sec_zone1", +# "screen": "test_screen", +# "source_identity_log": true, +# "tcp_rst": true +# } +# ] +# } +# "changed": false, +# +# +# Using rendered +# +# Before state +# ------------ +# +- name: Render xml for provided facts. + junipernetworks.junos.junos_security_zones: + config: + functional_zone_management: + description: test description + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + security_zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + - addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true + state: rendered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "rendered": +# 't' +# 'est descriptionallbgpalldhcpge-0/0/1.0ge-0/0/2.0test_screentest_sec_zone1test_adr110.0.0.0/24test desctest_adr21.1.1.1test_adr310.2.0.110.2.0.2test_adr410.3.0.1/24test_adr510.1.0.0/24test desctest_adrset1test_adr1test' +# '_adr2test_adrset2test_adr3test_adr4test_adrset3test_adr5test_adrset1test_adrset2test descriptiontest_profiletest descriptionallbgpalldhcpge-0/0/3.0ge-0/0/4.0test_screen' +# +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# +# +# +# test description +# +# +# all +# +# +# bgp +# +# +# +# all +# +# +# dhcp +# +# +# +# +# ge-0/0/1.0 +# +# +# ge-0/0/2.0 +# +# test_screen +# +# +# +# test_sec_zone1 +# +#
+# test_adr1 +# 10.0.0.0/24 +# test desc +#
+#
+# test_adr2 +# +# 1.1.1.1 +# +# +#
+#
+# test_adr3 +# +# 10.2.0.1 +# +# 10.2.0.2 +# +# +#
+#
+# test_adr4 +# +# 10.3.0.1/24 +# +#
+#
+# test_adr5 +# 10.1.0.0/24 +# test desc +#
+# +# test_adrset1 +#
+# test_adr1 +#
+#
+# test_adr2 +#
+#
+# +# test_adrset2 +#
+# test_adr3 +#
+#
+# test_adr4 +#
+#
+# +# test_adrset3 +#
+# test_adr5 +#
+# +# test_adrset1 +# +# +# test_adrset2 +# +# test description +#
+#
+# +# test_profile +# +# +# test description +# +# +# +# all +# +# +# bgp +# +# +# +# all +# +# +# dhcp +# +# +# +# +# ge-0/0/3.0 +# +# +# ge-0/0/4.0 +# +# test_screen +# +# +#
+#
+#
+#
+#
+# +- name: Parse security zones running config + junipernetworks.junos.junos_security_zones: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "parsed": { +# "functional_zone_management": { +# "description": "test description 2", +# "host_inbound_traffic": { +# "protocols": [{"name": "all"}, {"except": True, "name": "bgp"}, {"except": True, "name": "bfd"}], +# "system_services": [{"name": "all"}, {"except": True, "name": "dhcp"}, {"except": True, "name": "dhcpv6"}], +# }, +# "interfaces": ["ge-0/0/1.0", "ge-0/0/2.0"], +# "screen": "test_screen", +# }, +# "security_zones": [ +# { +# "address_book": { +# "address_sets": [ +# {"addresses": ["test_adr1", "test_adr2"], "name": "test_adrset1"}, +# {"addresses": ["test_adr3", "test_adr4"], "name": "test_adrset2"}, +# { +# "address_sets": ["test_adrset1", "test_adrset2"], +# "addresses": ["test_adr5"], +# "description": "test description", +# "name": "test_adrset3", +# }, +# ], +# "addresses": [ +# {"description": "test desc", "ip_prefix": "10.0.0.0/24", "name": "test_adr1"}, +# {"dns_name": {"ipv6_only": True, "name": "1.1.1.1"}, "name": "test_adr2"}, +# {"name": "test_adr3", "range_address": {"from": "10.2.0.1", "to": "10.2.0.2"}}, +# {"name": "test_adr4", "wildcard_address": "10.3.0.1/24"}, +# {"description": "test desc", "ip_prefix": "10.1.0.0/24", "name": "test_adr5"}, +# ], +# }, +# "advance_policy_based_routing_profile": "test_profile", +# "application_tracking": True, +# "description": "test description", +# "enable_reverse_reroute": True, +# "host_inbound_traffic": { +# "protocols": [{"name": "all"}, {"except": True, "name": "bgp"}], +# "system_services": [{"name": "all"}, {"except": True, "name": "dhcp"}], +# }, +# "interfaces": ["ge-0/0/3.0", "ge-0/0/4.0"], +# "name": "test_sec_zone1", +# "screen": "test_screen", +# "source_identity_log": True, +# "tcp_rst": True, +# }, +# {"name": "test_sec_zone2", "source_identity_log": True, "tcp_rst": True}, +# ], +# } +# +# +""" +RETURN = """ +before: + description: The configuration prior to the module execution. + returned: when state is I(merged), I(replaced), I(overridden), I(deleted) or I(purged) + type: dict + sample: > + This output will always be in the same format as the + module argspec. +after: + description: The resulting configuration after module execution. + returned: when changed + type: dict + sample: > + This output will always be in the same format as the + module argspec. +commands: + description: The set of commands pushed to the remote device. + returned: when state is I(merged), I(replaced), I(overridden), I(deleted) or I(purged) + type: list + sample: + - " + + + + + + test_glob_1 + + any-ipv6 + any-ipv6 + any + + + + + + + + + + " +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when state is I(rendered) + type: dict + sample: + - " + + + + + + test_glob_1 + + any-ipv6 + any-ipv6 + any + + + + + + + + + + " +gathered: + description: Facts about the network resource gathered from the remote device as structured data. + returned: when state is I(gathered) + type: dict + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. + returned: when state is I(parsed) + type: dict + sample: > + This output will always be in the same format as the + module argspec. +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.security_zones.security_zones import ( + Security_zonesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.security_zones.security_zones import ( + Security_zones, +) + + +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",)), + ] + + module = AnsibleModule( + argument_spec=Security_zonesArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + + result = Security_zones(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_snmp_server.py b/ansible_collections/juniper/device/plugins/modules/junos_snmp_server.py new file mode 100644 index 00000000..0b997828 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_snmp_server.py @@ -0,0 +1,1584 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2021 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# 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 junos_snmp_server +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +ANSIBLE_METADATA = { + "metadata_version": "1.1", + "status": ["preview"], + "supported_by": "network", +} + +DOCUMENTATION = """ +--- +module: junos_snmp_server +version_added: 2.9.0 +short_description: Manage SNMP server configuration on Junos devices. +description: This module manages SNMP server configuration on devices running Junos. +author: Rohit Thakur (@rohitthakur2590) +requirements: + - ncclient (>=v0.6.4) + - xmltodict (>=0.12.0) +notes: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection C(netconf). + - See L(the Junos OS Platform Options,https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html). + - Tested against JunOS v18.4R1 +options: + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show system snmp). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result. + type: str + config: + description: A dictionary of SNMP server configuration. + type: dict + suboptions: + arp: + description: Specify JVision arp setting. + type: dict + suboptions: + set: + description: Set JVision arp. + type: bool + host_name_resolution: + description: Enable host name resolution. + type: bool + client_lists: + description: Specify client list. + type: list + elements: dict + suboptions: + name: + description: Specify client list name. + type: str + addresses: + description: Specify list of addresses/prefixes. + type: list + elements: dict + suboptions: + address: + description: Specify address or prefix. + type: str + restrict: + description: Deny access. + type: bool + routing_instance_access: &routing_instance_access + description: SNMP routing-instance options. + type: dict + suboptions: + set: + description: Set routing_instance_access. + type: bool + access_lists: + description: Allow/Deny SNMP access to routing-instances. + type: list + elements: str + communities: + description: Specify list of community string. + type: list + elements: dict + suboptions: + name: + description: Specify name of the community. + type: str + authorization: + description: Specify Authorization type. + type: str + choices: ["read-only", "read-write"] + client_list_name: &client_list_name + description: Specify the name of client list or prefix list. + type: str + clients: &clients + description: Specify List of source address prefix ranges to accept. + type: list + elements: dict + suboptions: + address: + description: Specify address or prefix. + type: str + restrict: + description: Deny access. + type: bool + routing_instances: &routing_instances + description: Use routing-instance name for v1/v2c clients. + type: list + elements: dict + suboptions: + name: + description: Specify routing-instances. + type: str + client_list_name: *client_list_name + clients: *clients + logical_system: &logical_system + description: Use logical-system name for v1/v2c clients. + type: list + elements: str + view: + description: Specify view name. + type: str + contact: + description: Specify contact information for administrator. + type: str + customization: + description: Customize SNMP behaviour based on knob. + type: dict + suboptions: + ether_stats_ifd_only: + description: To stop exposing IFLs as part of etherStatsTable. + type: bool + description: + description: System description. + type: str + engine_id: + description: Specify SNMPv3 engine ID + type: dict + suboptions: + local: + description: Local engine ID. + type: str + use_default_ip_address: + description: Use default IP address for the engine ID. + type: bool + use_mac_address: + description: Uses management interface MAC Address for the engine ID. + type: bool + filter_duplicates: + description: Filter requests with duplicate source address/port and request ID. + type: bool + filter_interfaces: + description: List of interfaces that needs to be filtered. + type: dict + suboptions: + set: + description: Set filter-interfaces. + type: bool + all_internal_interfaces: + description: Filter all internal interfaces. + type: bool + interfaces: + description: Specify filter specified interfaces. + type: list + elements: str + health_monitor: + description: Specify health monitoring configuration. + type: dict + suboptions: + set: + description: Set health-monitor configuration. + type: bool + falling_threshold: + description: Falling threshold applied to all monitored objects. + type: int + rising_threshold: + description: Rising threshold applied to all monitored objects. + type: int + idp: + description: IDP health monitor configuration. + type: bool + interval: + description: Interval between samples. + type: int + if_count_with_filter_interfaces: + description: Filter interfaces config for ifNumber and ipv6Interfaces. + type: bool + interfaces: + description: Restrict SNMP requests to interfaces. + type: list + elements: str + location: + description: Specify physical location of system. + type: str + logical_system_trap_filter: + description: Allow only logical-system specific traps. + type: bool + name: + description: System name override. + type: str + nonvolatile: + description: Configure the handling of nonvolatile SNMP Set requests. + type: dict + suboptions: + commit_delay: + description: Delay between affirmative SNMP Set reply and start of commit (seconds). + type: int + proxies: + description: SNMP proxy configuration. + type: list + elements: dict + suboptions: + name: + description: Specify proxy name. + type: str + device_name: + description: Satellite/Proxied Device name or IP address. + type: str + logical_system: *logical_system + routing_instances: *routing_instances + version_v1: + description: Specify For v1 proxy configuration define snmp-community. + type: dict + suboptions: + no_default_comm_to_v3_config: + description: Specify No default snmp-community and v3 configuration. + type: bool + snmp_community: + description: Specify community name. + type: str + version_v2c: + description: For v2c proxy configuration define snmp-community. + type: dict + suboptions: + no_default_comm_to_v3_config: + description: Specify No default snmp-community and v3 configuration. + type: bool + snmp_community: + description: Specify community name. + type: str + version_v3: + description: For v3 proxy configuration define security-name. + type: dict + suboptions: + context: + description: pecify context name associated to this security-name. + type: bool + security_name: + description: Specify v3 security-name. + type: str + rmon: + description: Specify Remote Monitoring configuration. + type: dict + suboptions: + set: + description: Set Remote monitoring configuration. + type: bool + alarms: + description: RMON alarm entries. + type: list + elements: dict + suboptions: + id: + description: Specify alarm ID. + type: str + description: + description: General description of alarm (stored in alarmOwner). + type: str + falling_event_index: + description: Event triggered after falling threshold is crossed. + type: int + falling_threshold: + description: Specify falling-threshold. + type: int + falling_threshold_interval: + description: Interval between samples during falling-threshold test. + type: int + interval: + description: Interval between samples. + type: int + request_type: + description: Type of SNMP request to issue for alarm. + type: str + choices: ["get-next-request", "get-request", "walk-request"] + rising_event_index: + description: Event triggered after rising threshold is crossed. + type: int + rising_threshold: + description: The rising threshold. + type: int + sample_type: + description: Method of sampling the selected variable. + type: str + choices: ["absolute-value", "delta-value"] + startup_alarm: + description: The alarm that may be sent upon entry startup. + type: str + choices: ["falling-alarm", "rising-alarm", "rising-or-falling-alarm"] + syslog_subtag: + description: Tag to be added to syslog messages. + type: str + variable: + description: OID of MIB variable to be monitored. + type: str + events: + description: RMON event entries. + type: list + elements: dict + suboptions: + id: + description: Specify event ID. + type: int + community: + description: The community (trap group) for outgoing traps. + type: str + description: + description: General description of event. + type: str + type: + description: The type of notification for this event. + type: str + choices: ["log", "log-and-trap", "none", "snmptrap"] + subagent: + description: SNMP subagent configuration. + type: dict + suboptions: + tcp: + description: Allow SNMP subagent tcp connection. + type: dict + suboptions: + set: + description: Set SNMP subagent TCP. + type: bool + routing_instances_default: + description: Specify routing-instance name for tcp connection. + type: bool + traceoptions: + description: Configure trace options for SNMP. + type: dict + suboptions: + file: + description: Specify trace file options. + type: dict + suboptions: + match: + description: Regular expression for lines to be logged. + type: str + files: + description: Specify maximum number of trace files. + type: int + no_world_readable: + description: Don't allow any user to read the log file. + type: bool + world_readable: + description: Allow any user to read the log file. + type: bool + size: + description: Specify maximum trace file size. + type: int + flag: + description: Specify flag traceoptions. + type: dict + suboptions: + all: + description: Trace everything. + type: bool + general: + description: Trace general events. + type: bool + interface_stats: + description: Trace interface statistics (logical and physical). + type: bool + nonvolatile_sets: + description: Nonvolatile SNMP set request handling. + type: bool + pdu: + description: Dump SNMP request/response packets. + type: bool + protocol_timeouts: + description: Trace SNMP request timeouts. + type: bool + routing_socket: + description: Trace routing socket calls. + type: bool + subagent: + description: Trace master-agent interations with sub-agents. + type: bool + timer: + description: Trace internal timer events. + type: bool + varbind_error: + description: Trace varbind errors. + type: bool + memory_trace: + description: Memory tracing information. + type: dict + suboptions: + set: + description: set memory traceoptions. + type: bool + size: + description: Specify Memory size reserved for tracing. + type: int + no_remote_trace: + description: Disable remote tracing. + type: bool + trap_groups: + description: Specify SNMP trap options. + type: list + elements: dict + suboptions: + name: + description: Specify trap group name. + type: str + categories: + description: Specify Trap categories. + type: dict + suboptions: + authentication: + description: Specify Authentication failures. + type: bool + chassis: + description: Specify Chassis or environment notifications. + type: bool + chassis_cluster: + description: Specify Clustering notifications. + type: bool + configuration: + description: Configuration notifications. + type: bool + dot3oam_events: + description: Specify 802.3ah notifications. + type: bool + link: + description: Link up-down transitions. + type: bool + otn_alarms: + description: OTN alarm trap subcategories. + type: dict + suboptions: + set: + description: Set otn_alarms. + type: bool + oc_lof: + description: Loss of frame alarm notifications. + type: bool + oc_lom: + description: Loss of multiframe alarm notification. + type: bool + oc_los: + description: Loss of signal alarm notification. + type: bool + odu_ais: + description: ODU Alarm indication signal alarm notification. + type: bool + odu_bbe_threshold: + description: ODU Background block error threshold alarm notification. + type: bool + odu_bdi: + description: ODU Backward defect indication alarm notification. + type: bool + odu_bdodu_es_threshold: + description: ODU Errored Second threshold alarm notification. + type: bool + odu_lck: + description: ODU Locked alarm notification. + type: bool + odu_oci: + description: ODU Open connection indicator alarm notifications. + type: bool + odu_rx_aps_change: + description: ODU Receive APS change notifications. + type: bool + odu_sd: + description: ODU Signal degrade alarm notifications. + type: bool + odu_ses_threshold: + description: ODU Severely Errored Second threshold alarm notification. + type: bool + odu_sf: + description: ODU Signal fail alarm notification. + type: bool + odu_ttim: + description: ODU Trace identification mismatch alarm notification. + type: bool + odu_uas_threshold: + description: ODU Unavailable Second threshold alarm notification. + type: bool + opu_ptm: + description: ODU Payload Type Mismatch alarm notification. + type: bool + otu_ais: + description: OTU Alarm indication signal alarm notification. + type: bool + otu_bbe_threshold: + description: OTU Background block error threshold alarm notification. + type: bool + otu_bdi: + description: OTU Backward defect indication alarm notification. + type: bool + otu_es_threshold: + description: OTU Errored Second threshold alarm notification. + type: bool + otu_fec_deg: + description: OTU Fec degraded errors alarm notification. + type: bool + otu_fec_exe: + description: OTU Fec excessive errors alarm notification. + type: bool + otu_iae: + description: OTU Incoming alignment error alarm notification. + type: bool + otu_sd: + description: OTU Signal degrade alarm notification. + type: bool + otu_ses_threshold: + description: OTU Severely Errored Second threshold alarm notification. + type: bool + otu_sf: + description: OTU Signal fail alarm notification. + type: bool + otu_ttim: + description: OTU Trace identification mismatch alarm notification. + type: bool + otu_uas_threshold: + description: OTU Unavailable Second threshold alarm notification. + type: bool + wavelength_lock: + description: Wavelength lock alarm notification. + type: bool + remote_operations: + description: Remote operations. + type: bool + rmon_alarm: + description: RMON rising and falling alarms. + type: bool + routing: + description: Routing protocol notifications. + type: bool + services: + description: Services notifications. + type: bool + startup: + description: System warm and cold starts. + type: bool + vrrp_events: + description: VRRP notifications. + type: bool + destination_port: + description: SNMP trap receiver port number + type: int + logical_system: *logical_system + routing_instance: + description: Routing instance for trap destination. + type: str + targets: + description: Targets for trap messages + type: list + elements: str + version: + description: SNMP version. + type: str + choices: ["all", "v1", "v2"] + trap_options: + description: SNMP trap options. + type: dict + suboptions: + set: + description: Set trap options. + type: bool + agent_address: + description: Agent address for v1 trap PDUs. + type: dict + suboptions: + outgoing_interface: + description: Use address on outgoing interfaces. + type: bool + context_oid: + description: Add context oid in varbind of all traps at the end. + type: bool + enterprise_oid: + description: Add snmpTrapEnterprise oid in varbind of all traps. + type: bool + logical_system: *logical_system + routing_instance: + description: Specify routing-instance. + type: str + source_address: + description: IPv4/IPv6 source address for trap PDUs. + type: dict + suboptions: + address: + description: Use specified address. + type: str + lowest_loopback: + description: Use lowest address on loopback interfaces. + type: bool + snmp_v3: + description: SNMPv3 configuration information. + type: dict + suboptions: + notify: + description: Used to select management targets for notifications as well as the type of notifications. + type: list + elements: dict + suboptions: + name: + description: Specify notify name. + type: str + tag: + description: Notifications will be sent to all targets configured with this tag. + type: str + type: + description: Notification type. + type: str + notify_filter: + description: Filters to apply to SNMP notifications. + type: list + elements: dict + suboptions: + name: + description: Specify notify filter name. + type: str + oids: + description: OID to include/exclude from notify filter. + type: list + elements: dict + suboptions: + oid: + description: Specify OID. + type: str + exclude: + description: Exclude this OID from the notify filtered. + type: bool + include: + description: Include this OID in the notify filter. + type: bool + snmp_community: + description: SNMP community and view-based access control model configuration. + type: list + elements: dict + suboptions: + community_index: + description: Unique index value in this community table entry. + type: str + security_name: + description: Security name used when performing access control. + type: str + community_name: + description: SNMPv1/v2c community name (default is same as community-index). + type: str + context: + description: Context used when performing access control. + type: str + tag: + description: Tag identifier for set of targets allowed to use this community string. + type: str + target_addresses: + description: Identifies notification targets as well as allowed management stations. + type: list + elements: dict + suboptions: + name: + description: SNMP target address name. + type: str + address: + description: SNMP target address. + type: str + address_mask: + description: Mask range of addresses for community string access control. + type: str + logical_system: + description: Logical-system name for trap destination. + type: str + port: + description: SNMP target port number. + type: int + retry_count: + description: Maximum retry count for confirmed SNMP notifications. + type: int + routing_instance: + description: Routing instance for trap destination. + type: str + tag_list: + description: SNMP tag list used to select target addresses. + type: str + target_parameters: + description: SNMPv3 target parameter name in the target parameters table. + type: str + timeout: + description: Acknowledgment timeout for confirmed SNMP notifications (seconds). + type: int + target_parameters: + description: SNMPv3 target parameter name in the target parameters table. + type: list + elements: dict + suboptions: + name: + description: SNMPv3 target parameters name. + type: str + notify_filter: + description: Notify filter with filter name to apply to notifications. + type: str + parameters: + description: Parameters used when sending notifications. + type: dict + suboptions: + message_processing_model: + description: The message processing model to be used when generating SNMP notifications. + type: str + choices: ["v1", "v2c", "v3"] + security_level: + description: Security-level used when generating SNMP notifications. + type: str + choices: ["authentication", "none", "privacy"] + security_model: + description: Security-model used when generating SNMP notifications. + type: str + choices: ["usm", "v1", "v2c"] + security_name: + description: Security name used when generating SNMP notifications. + type: str + usm: + description: User-based security model (USM) information. + type: dict + suboptions: + local_engine: + description: Local engine user configuration. + type: dict + suboptions: + users: &users + description: SNMPv3 USM user information. + type: list + elements: dict + suboptions: + name: + description: User name. + type: str + authentication_md5: + description: Configure MD5 authentication. + type: dict + suboptions: + key: + description: Encrypted key used for user authentication. + type: str + password: + description: User's authentication password + type: str + authentication_none: + description: Set no authentication for the user. + type: bool + authentication_sha: + description: Configure SHA authentication. + type: dict + suboptions: + key: + description: Encrypted key used for user authentication. + type: str + password: + description: User's authentication password + type: str + privacy_3des: + description: Configure Triple DES privacy. + type: dict + suboptions: + key: + description: Encrypted key used for user privacy. + type: str + password: + description: User's privacy password + type: str + privacy_aes128: + description: Configure AES128 privacy. + type: dict + suboptions: + key: + description: Encrypted key used for user privacy. + type: str + password: + description: User's privacy password + type: str + privacy_des: + description: Configure DES privacy. + type: dict + suboptions: + key: + description: Encrypted key used for user privacy. + type: str + password: + description: User's privacy password + type: str + privacy_none: + description: Set no privacy for the user. + type: bool + remote_engine: + description: Remote engine user configuration. + type: list + elements: dict + suboptions: + id: + description: Remote engine id. + type: str + users: *users + views: + description: Define MIB views. + type: list + elements: dict + suboptions: + name: + description: MIB view name. + type: str + oids: + description: OID include/exclude list + type: list + elements: dict + suboptions: + oid: + description: OID to include or exclude from view. + type: str + exclude: + description: Exclude this OID from the view. + type: bool + include: + description: Include this OID from the view. + type: bool + state: + description: + - The state the configuration should be left in. + - Refer to examples for more details. + type: str + choices: + - merged + - replaced + - deleted + - overridden + - parsed + - gathered + - rendered + default: merged +""" +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# vagrant@vsrx# show routing-instances +# clv1 { +# description clv1; +# } +# clv2 { +# description clv2; +# } +- name: Merge provided SNMP configuration into running configuration. + junipernetworks.junos.junos_snmp_server: + config: + arp: + set: true + host_name_resolution: true + client_lists: # ATTR-----2 + - name: cl1 + addresses: + - address: "192.16.1.0/24" + - address: "192.16.2.0/24" + - address: "11.11.11.11" + restrict: true + - name: cl2 + addresses: + - address: "192.16.4.0/24" + routing_instance_access: # ATTR-----3 + set: true + access_lists: + - "clv1" + - "clv2" + state: merged +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "arp": { +# "host_name_resolution": true +# }, +# "client_lists": [ +# { +# "addresses": [ +# { +# "address": "192.16.1.0/24" +# }, +# { +# "address": "192.16.2.0/24" +# }, +# { +# "address": "11.11.11.11/32", +# "restrict": true +# } +# ], +# "name": "cl1" +# }, +# { +# "addresses": [ +# { +# "address": "192.16.4.0/24" +# } +# ], +# "name": "cl2" +# } +# ], +# "routing_instance_access": { +# "access_lists": [ +# "clv1", +# "clv2" +# ] +# } +# }, +# "before": {}, +# "changed": true, +# "commands": [ +# "" +# "cl1" +# "192.16.1.0/24" +# "192.16.2.0/24" +# "11.11.11.11" +# "cl2192.16.4.0/24" +# "clv1" +# "clv2" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show snmp +# client-list cl1 { +# 192.16.1.0/24; +# 192.16.2.0/24; +# 11.11.11.11/32 { +# restrict; +# } +# } +# client-list cl2 { +# 192.16.4.0/24; +# } +# routing-instance-access { +# access-list { +# clv1; +# clv2; +# } +# } +# arp { +# host-name-resolution; +# } +# vagrant@vsrx# show routing-instances +# clv1 { +# description clv1; +# } +# clv2 { +# description clv2; +# } +# +# Using Replaced +# Before state +# ------------ +# +# vagrant@vsrx# show snmp +# client-list cl1 { +# 192.16.1.0/24; +# 192.16.2.0/24; +# 11.11.11.11/32 { +# restrict; +# } +# } +# client-list cl2 { +# 192.16.4.0/24; +# } +# routing-instance-access { +# access-list { +# clv1; +# clv2; +# } +# } +# arp { +# host-name-resolution; +# } +# vagrant@vsrx# show routing-instances +# clv1 { +# description clv1; +# } +# clv2 { +# description clv2; +# } + +- name: Replaced running SNMP server configuration with provided configuration + junipernetworks.junos.junos_snmp_server: + config: + contact: "ansiblesupport11@redhat.com" + customization: + ether_stats_ifd_only: true + description: "Local SNMP Server" + engine_id: + local: "local1" + use_default_ip_address: true + use_mac_address: true + filter_duplicates: true + filter_interfaces: + set: true + all_internal_interfaces: true + interfaces: + - "eth1" + - "eth2" + state: replaced +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "contact": "ansiblesupport11@redhat.com", +# "customization": { +# "ether_stats_ifd_only": true +# }, +# "description": "Local SNMP Server", +# "engine_id": { +# "use_mac_address": true +# }, +# "filter_duplicates": true, +# "filter_interfaces": { +# "all_internal_interfaces": true, +# "interfaces": [ +# "eth1", +# "eth2" +# ] +# } +# }, +# "before": +# { +# "arp": { +# "host_name_resolution": true +# }, +# "client_lists": [ +# { +# "addresses": [ +# { +# "address": "192.16.1.0/24" +# }, +# { +# "address": "192.16.2.0/24" +# }, +# { +# "address": "11.11.11.11/32", +# "restrict": true +# } +# ], +# "name": "cl1" +# }, +# { +# "addresses": [ +# { +# "address": "192.16.4.0/24" +# } +# ], +# "name": "cl2" +# } +# ], +# "routing_instance_access": { +# "access_lists": [ +# "clv1", +# "clv2" +# ] +# } +# }, +# "changed": true, +# "commands": [ +# "", +# "", +# "" +# "ansiblesupport11@redhat.com" +# "Local SNMP Server" +# "local1" +# "" +# "eth1eth2" +# "" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show routing-instances +# clv1 { +# description clv1; +# } +# clv2 { +# description clv2; +# } +# vagrant@vsrx# show snmp +# description "Local SNMP Server"; +# contact "ansiblesupport11@redhat.com"; +# filter-interfaces { +# interfaces { +# eth1; +# eth2; +# } +# all-internal-interfaces; +# } +# filter-duplicates; +# engine-id { +# use-mac-address; +# } +# customization { +# ether-stats-ifd-only; +# } + +# Using overridden +# +# Before state +# ------------ +# +# vagrant@vsrx# show snmp +# client-list cl1 { +# 192.16.1.0/24; +# 192.16.2.0/24; +# 11.11.11.11/32 { +# restrict; +# } +# } +# client-list cl2 { +# 192.16.4.0/24; +# } +# routing-instance-access { +# access-list { +# clv1; +# clv2; +# } +# } +# arp { +# host-name-resolution; +# } +# vagrant@vsrx# show routing-instances +# clv1 { +# description clv1; +# } +# clv2 { +# description clv2; +# } +- name: Override running SNMP server configuration with provided configuration + junipernetworks.junos.junos_snmp_server: + config: + contact: "ansiblesupport11@redhat.com" + customization: + ether_stats_ifd_only: true + description: "Local SNMP Server" + engine_id: + local: "local1" + use_default_ip_address: true + use_mac_address: true + filter_duplicates: true + filter_interfaces: + set: true + all_internal_interfaces: true + interfaces: + - "eth1" + - "eth2" + state: overridden +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": { +# "contact": "ansiblesupport11@redhat.com", +# "customization": { +# "ether_stats_ifd_only": true +# }, +# "description": "Local SNMP Server", +# "engine_id": { +# "use_mac_address": true +# }, +# "filter_duplicates": true, +# "filter_interfaces": { +# "all_internal_interfaces": true, +# "interfaces": [ +# "eth1", +# "eth2" +# ] +# } +# }, +# "before": +# { +# "arp": { +# "host_name_resolution": true +# }, +# "client_lists": [ +# { +# "addresses": [ +# { +# "address": "192.16.1.0/24" +# }, +# { +# "address": "192.16.2.0/24" +# }, +# { +# "address": "11.11.11.11/32", +# "restrict": true +# } +# ], +# "name": "cl1" +# }, +# { +# "addresses": [ +# { +# "address": "192.16.4.0/24" +# } +# ], +# "name": "cl2" +# } +# ], +# "routing_instance_access": { +# "access_lists": [ +# "clv1", +# "clv2" +# ] +# } +# }, +# "changed": true, +# "commands": [ +# "", +# "", +# "" +# "ansiblesupport11@redhat.com" +# "Local SNMP Server" +# "local1" +# "" +# "eth1eth2" +# "" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show routing-instances +# clv1 { +# description clv1; +# } +# clv2 { +# description clv2; +# } +# vagrant@vsrx# show snmp +# description "Local SNMP Server"; +# contact "ansiblesupport11@redhat.com"; +# filter-interfaces { +# interfaces { +# eth1; +# eth2; +# } +# all-internal-interfaces; +# } +# filter-duplicates; +# engine-id { +# use-mac-address; +# } +# customization { +# ether-stats-ifd-only; +# } +# +# Using deleted +# +# Before state +# ------------ +# +# vagrant@vsrx# show routing-instances +# clv1 { +# description clv1; +# } +# clv2 { +# description clv2; +# } +# vagrant@vsrx# show snmp +# description "Local SNMP Server"; +# contact "ansiblesupport11@redhat.com"; +# filter-interfaces { +# interfaces { +# eth1; +# eth2; +# } +# all-internal-interfaces; +# } +# filter-duplicates; +# engine-id { +# use-mac-address; +# } +# customization { +# ether-stats-ifd-only; +# } +# +- name: Delete running SNMP server configuration + junipernetworks.junos.junos_snmp_server: + config: + state: deleted +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": {}, +# "before": { +# "contact": "ansiblesupport11@redhat.com", +# "customization": { +# "ether_stats_ifd_only": true +# }, +# "description": "Local SNMP Server", +# "engine_id": { +# "use_mac_address": true +# }, +# "filter_duplicates": true, +# "filter_interfaces": { +# "all_internal_interfaces": true, +# "interfaces": [ +# "eth1", +# "eth2" +# ] +# } +# }, +# "changed": true, +# "commands": [ +# "", +# "" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show routing-instances +# clv1 { +# description clv1; +# } +# clv2 { +# description clv2; +# } +# vagrant@vsrx# show snmp +# description "Local SNMP Server"; +# contact "ansiblesupport11@redhat.com"; +# filter-interfaces { +# interfaces { +# eth1; +# eth2; +# } +# all-internal-interfaces; +# } +# filter-duplicates; +# engine-id { +# use-mac-address; +# } +# customization { +# ether-stats-ifd-only; +# } +# +- name: Gather running SNMP server configuration + junipernetworks.junos.junos_snmp_server: + state: gathered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "gathered": { +# "contact": "ansiblesupport11@redhat.com", +# "customization": { +# "ether_stats_ifd_only": true +# }, +# "description": "Local SNMP Server", +# "engine_id": { +# "use_mac_address": true +# }, +# "filter_duplicates": true, +# "filter_interfaces": { +# "all_internal_interfaces": true, +# "interfaces": [ +# "eth1", +# "eth2" +# ] +# } +# }, +# "changed": false, +# Using rendered +# +# Before state +# ------------ +# +- name: Render xml for provided facts. + junipernetworks.junos.junos_snmp_server: + config: + arp: + set: true + host_name_resolution: true + routing_instance_access: # ATTR-----3 + set: true + access_lists: + - "clv1" + - "clv2" + state: rendered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "rendered": [ +# "" +# "" +# "clv1clv2" +# "" +# ] +# +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# +# +# cl1 +# +# 192.16.1.0/24 +# +# +# 192.16.2.0/24 +# +# +# 11.11.11.11/32 +# +# +# +# +# cl2 +# +# 192.16.4.0/24 +# +# +# +# +# clv1 +# +# +# clv2 +# +# +# +# +# +# +# +# +# +# +- name: Parse SNMP server running config + junipernetworks.junos.junos_snmp_server: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "parsed": { +# "arp": { +# "host_name_resolution": true +# }, +# "client_lists": [ +# { +# "addresses": [ +# { +# "address": "192.16.1.0/24" +# }, +# { +# "address": "192.16.2.0/24" +# }, +# { +# "address": "11.11.11.11/32", +# "restrict": true +# } +# ], +# "name": "cl1" +# }, +# { +# "addresses": [ +# { +# "address": "192.16.4.0/24" +# } +# ], +# "name": "cl2" +# } +# ], +# "routing_instance_access": { +# "access_lists": [ +# "clv1", +# "clv2" +# ] +# } +# } +# +# +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: dict +after: + description: The resulting configuration model invocation. + returned: when changed + sample: > + The configuration returned will always be in the same format + of the parameters above. + type: dict +commands: + description: The set of commands pushed to the remote device. + returned: always + type: list + sample: ['"', + ''] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.snmp_server.snmp_server import ( + Snmp_serverArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.config.snmp_server.snmp_server import ( + Snmp_server, +) + + +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",)), + ] + module = AnsibleModule( + argument_spec=Snmp_serverArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + + result = Snmp_server(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_static_routes.py b/ansible_collections/juniper/device/plugins/modules/junos_static_routes.py new file mode 100644 index 00000000..2baa63b9 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_static_routes.py @@ -0,0 +1,513 @@ +#!/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 junos_static_routes +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_static_routes +short_description: Static routes resource module +description: This module provides declarative management of static routes on Juniper + JUNOS devices +version_added: 1.0.0 +author: Daniel Mellado (@dmellado) +requirements: +- ncclient (>=v0.6.4) +- xmltodict (>=0.12) +notes: +- This module requires the netconf system service be enabled on the device being managed. +- This module works with connection C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +- Tested against JunOS v18.4R1 +options: + config: + description: A dictionary of static routes options + type: list + elements: dict + suboptions: + vrf: + description: + - Virtual Routing and Forwarding (VRF) name + type: str + address_families: + description: + - Address family to use for the static routes + elements: dict + type: list + suboptions: + afi: + description: + - afi to use for the static routes + type: str + required: true + choices: + - ipv4 + - ipv6 + routes: + description: + - Static route configuration + elements: dict + type: list + suboptions: + dest: + description: + - Static route destination including prefix + type: str + next_hop: + elements: dict + type: list + description: + - Next hop to destination + suboptions: + forward_router_address: + description: + - List of next hops + type: str + metric: + description: + - Metric value for the static route + type: int + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show routing-options). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + description: + - The state the configuration should be left in + type: str + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - rendered + - parsed + default: merged +""" + +EXAMPLES = """ +# Using deleted + +# Before state +# ------------ +# +# admin# show routing-options +# static { +# route 192.168.47.0/24 next-hop 172.16.1.2; +# route 192.168.16.0/24 next-hop 172.16.1.2; +# } + +- name: Delete provided configuration (default operation is merge) + junipernetworks.junos.junos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.16.0/24 + next_hop: + - forward_router_address: 172.16.1.2 + state: deleted + +# Task Output +# ----------- +# before: +# - address_families: +# - afi: ipv4 +# routes: +# - dest: 192.168.47.0/24 +# next_hop: +# - forward_router_address: 172.16.1.2 +# - dest: 192.168.16.0/24 +# next_hop: +# - forward_router_address: 172.16.1.2 +# commands: +# - '192.168.16.0/24' +# - '' +# after: +# - address_families: +# - afi: ipv4 +# routes: +# - dest: 192.168.47.0/24 +# next_hop: +# - forward_router_address: 172.16.1.2 + +# After state: +# ------------ +# +# admin# show routing-options +# static { +# route 192.168.47.0/24 next-hop 172.16.1.2; +# } + +# Using merged + +# Before state +# ------------ +# +# admin# show routing-options +# static { +# route 192.168.47.0/24 next-hop 172.16.1.2; +# } + +- name: Merge provided configuration with device configuration (default operation + is merge) + junipernetworks.junos.junos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.16.0/24 + next_hop: + - forward_router_address: 172.16.1.2 + state: merged + +# Task Output +# ----------- +# before: +# - address_families: +# - afi: ipv4 +# routes: +# - dest: 192.168.47.0/24 +# next_hop: +# - forward_router_address: 172.16.1.2 +# commands: +# - '192.168.16.0/24 +# 172.16.1.2' +# - '' +# after: +# - address_families: +# - afi: ipv4 +# routes: +# - dest: 192.168.47.0/24 +# next_hop: +# - forward_router_address: 172.16.1.2 +# - dest: 192.168.16.0/24 +# next_hop: +# - forward_router_address: 172.16.1.2 +# After state: +# ------------ +# +# admin# show routing-options +# static { +# route 192.168.47.0/24 next-hop 172.16.1.2; +# route 192.168.16.0/24 next-hop 172.16.1.2; +# } + +# Using overridden + +# Before state +# ------------ +# +# admin# show routing-options +# static { +# route 192.168.47.0/24 next-hop 172.16.1.2; +# route 192.168.16.0/24 next-hop 172.16.1.2; +# } + +- name: Override running configuration with provided configuration (default operation + is merge) + junipernetworks.junos.junos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.16.0/24 + next_hop: + - forward_router_address: 172.16.0.1 + state: overridden +# Task Output: +# ------------ +# before: +# - address_families: +# - afi: ipv4 +# routes: +# - dest: 192.168.47.0/24 +# next_hop: +# - forward_router_address: 172.16.1.2 +# - dest: 192.168.16.0/24 +# next_hop: +# - forward_router_address: 172.16.1.2 +# commands: +# - >- +# 192.168.47.0/24192.168.16.0/24192.168.16.0/24172.16.0.1 +# - '' +# after: +# - address_families: +# - afi: ipv4 +# routes: +# - dest: 192.168.16.0/24 +# next_hop: +# - forward_router_address: 172.16.0.1 + +# After state: +# ------------ +# +# admin# show routing-options +# static { +# route 192.168.16.0/24 next-hop 172.16.0.1; +# } + +# Using replaced + +# Before state +# ------------ +# +# admin# show routing-options +# static { +# route 192.168.47.0/24 next-hop 172.16.1.2; +# route 192.168.16.0/24 next-hop 172.16.1.2; +# } + +- name: Replace provided configuration with device configuration (default operation + is merge) + junipernetworks.junos.junos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.47.0/24 + next_hop: + - forward_router_address: 10.200.16.2 + state: replaced + +# Task Output: +# ------------ +# before: +# - address_families: +# - afi: ipv4 +# routes: +# - dest: 192.168.47.0/24 +# next_hop: +# - forward_router_address: 172.16.1.2 +# - dest: 192.168.16.0/24 +# next_hop: +# - forward_router_address: 172.16.1.2 +# commands: +# - >- +# 192.168.47.0/24192.168.47.0/2410.200.16.2 +# - '' +# after: +# - address_families: +# - afi: ipv4 +# routes: +# - dest: 192.168.16.0/24 +# next_hop: +# - forward_router_address: 172.16.1.2 +# - dest: 192.168.47.0/24 +# next_hop: +# - forward_router_address: 10.200.16.2 + +# After state: +# ------------ +# +# admin# show routing-options +# static { +# route 192.168.47.0/24 next-hop 10.200.16.2; +# route 192.168.16.0/24 next-hop 172.16.1.2; +# } + +# Using gathered to gather static route facts from the device +# Before state +# ------------ +# admin# show routing-options +# static { +# route 192.168.16.0/24 next-hop 172.16.1.2; +# route 192.168.47.0/24 next-hop 10.200.16.2; +# } +- name: Gather static routes facts from the device using junos_static_routes module + junipernetworks.junos.junos_static_routes: + state: gathered + +# Task output: +# ------------ +# gathered: +# - address_families: +# - afi: ipv4 +# routes: +# - dest: 192.168.16.0/24 +# next_hop: +# - forward_router_address: 172.16.1.2 +# - dest: 192.168.47.0/24 +# next_hop: +# - forward_router_address: 10.200.16.2 + +# Using rendered + +- name: Render platform specific commands (without connecting to the device) + junipernetworks.junos.junos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.16.0/24 + next_hop: + - forward_router_address: 172.16.1.2 + state: rendered + +# Task output: +# ------------ +# rendered: +# - '192.168.16.0/24 +# 172.16.1.2' + +# Using parsed + +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# +# +# 192.168.16.0/24 +# 172.16.1.2 +# 172.16.1.3 +# +# +# 192.168.47.0/24 +# 10.200.16.2 +# +# +# +# +# + +- name: Parsed running config (without connecting to the device) + junipernetworks.junos.junos_static_routes: + running_config: "{{ lookup('file', 'parsed.cfg') }}" + state: parsed + +# Task output: +# ------------ +# parsed: +# - address_families: +# - afi: ipv4 +# routes: +# - dest: 192.168.16.0/24 +# next_hop: +# - forward_router_address: '[''172.16.1.2'', ''172.16.1.3'']' +# - dest: 192.168.47.0/24 +# next_hop: +# - forward_router_address: 10.200.16.2 +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + type: str + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration model invocation. + returned: when changed + type: str + 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: ['command 1', 'command 2', 'command 3'] +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - +gathered: + description: Facts about the network resource gathered from the remote device as structured data. + returned: when I(state) is C(gathered) + type: list + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. + returned: when I(state) is C(parsed) + type: list + sample: > + This output will always be in the same format as the + module argspec. +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.static_routes.static_routes import ( + Static_routesArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.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", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_config",)), + ] + module = AnsibleModule( + argument_spec=Static_routesArgs.argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + result = Static_routes(module).execute_module() + + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_system.py b/ansible_collections/juniper/device/plugins/modules/junos_system.py new file mode 100644 index 00000000..c8f3387b --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_system.py @@ -0,0 +1,207 @@ +#!/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 + + +DOCUMENTATION = """ +module: junos_system +author: Ganesh Nalawade (@ganeshrn) +short_description: Manage the system attributes on Juniper JUNOS devices +description: +- This module provides declarative management of node system attributes on Juniper + JUNOS devices. It provides an option to configure host system parameters or remove + those parameters from the device active configuration. +version_added: 1.0.0 +extends_documentation_fragment: +- junipernetworks.junos.junos +options: + hostname: + description: + - Configure the device hostname parameter. This option takes an ASCII string value. + type: str + 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. + type: str + 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. + type: list + elements: str + 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. + type: list + elements: str + 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 + type: str + default: present + choices: + - present + - absent + active: + description: + - Specifies whether or not the configuration is active or deactivated + default: true + type: bool +requirements: +- ncclient (>=v0.5.2) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. +- Recommended connection is C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +- This module also works with C(local) connections for legacy playbooks. +""" + +EXAMPLES = """ +- name: configure hostname and domain name + junipernetworks.junos.junos_system: + hostname: junos01 + domain_name: test.example.com + domain-search: + - ansible.com + - redhat.com + - juniper.net + +- name: remove configuration + junipernetworks.junos.junos_system: + state: absent + +- name: configure name servers + junipernetworks.junos.junos_system: + name_servers: + - 8.8.8.8 + - 8.8.4.4 +""" + +RETURN = """ +diff.prepared: + description: Configuration difference before and after applying change. + returned: when configuration is changed and diff option is enabled. + type: str + sample: > + [edit system] + + host-name test; + + domain-name ansible.com; + + domain-search redhat.com; + [edit system name-server] + 172.26.1.1 { ... } + + 8.8.8.8; +""" +import collections + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + commit_configuration, + discard_changes, + load_config, + locked_config, + map_obj_to_ele, + map_params_to_obj, + tostring, +) + + +USE_PERSISTENT_CONNECTION = True + + +def validate_param_values(module, obj): + for key in obj: + # validate the param value (if validator func exists) + validator = globals().get("validate_%s" % key) + if callable(validator): + validator(module.params.get(key), module) + + +def main(): + """main entry point for module execution""" + argument_spec = dict( + hostname=dict(), + domain_name=dict(), + domain_search=dict(type="list", elements="str"), + name_servers=dict(type="list", elements="str"), + state=dict(choices=["present", "absent"], default="present"), + active=dict(default=True, type="bool"), + ) + + params = ["hostname", "domain_name", "domain_search", "name_servers"] + required_if = [ + ("state", "present", params, True), + ("state", "absent", params, True), + ("state", "active", params, True), + ("state", "suspend", params, True), + ] + + module = AnsibleModule( + argument_spec=argument_spec, + required_if=required_if, + supports_check_mode=True, + ) + + warnings = list() + result = {"changed": False} + + if warnings: + result["warnings"] = warnings + + top = "system" + + param_to_xpath_map = collections.OrderedDict() + param_to_xpath_map.update( + [ + ("hostname", {"xpath": "host-name", "leaf_only": True}), + ("domain_name", {"xpath": "domain-name", "leaf_only": True}), + ( + "domain_search", + { + "xpath": "domain-search", + "leaf_only": True, + "value_req": True, + }, + ), + ("name_servers", {"xpath": "name-server/name", "is_key": True}), + ], + ) + + validate_param_values(module, param_to_xpath_map) + + want = map_params_to_obj(module, param_to_xpath_map) + ele = map_obj_to_ele(module, want, top) + + with locked_config(module): + diff = load_config(module, tostring(ele), warnings, action="merge") + + commit = not module.check_mode + if diff: + if commit: + commit_configuration(module) + else: + discard_changes(module) + result["changed"] = True + + if module._diff: + result["diff"] = {"prepared": diff} + + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_user.py b/ansible_collections/juniper/device/plugins/modules/junos_user.py new file mode 100644 index 00000000..038e4af0 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_user.py @@ -0,0 +1,457 @@ +#!/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 + + +DOCUMENTATION = """ +module: junos_user +author: Peter Sprygada (@privateip) +short_description: Manage local user accounts on Juniper JUNOS devices +description: +- This module manages locally configured user accounts on remote network devices running + the JUNOS operating system. It provides a set of arguments for creating, removing + and updating locally defined accounts +version_added: 1.0.0 +extends_documentation_fragment: +- junipernetworks.junos.junos +options: + aggregate: + description: + - The C(aggregate) argument defines a list of users to be configured on the remote + device. The list of users will be compared against the current users and only + changes will be added or removed from the device configuration. This argument + is mutually exclusive with the name argument. + aliases: + - users + - collection + type: list + elements: dict + suboptions: + name: + description: + - The C(name) argument defines the username of the user to be created on the system. This + argument must follow appropriate usernaming conventions for the target device + running JUNOS. This argument is mutually exclusive with the C(aggregate) argument. + required: true + type: str + full_name: + description: + - The C(full_name) argument provides the full name of the user account to be created + on the remote device. This argument accepts any text string value. + type: str + role: + description: + - The C(role) argument defines the role of the user account on the remote system. User + accounts can have more than one role configured. + type: str + choices: + - operator + - read-only + - super-user + - unauthorized + sshkey: + description: + - The C(sshkey) argument defines the public SSH key to be configured for the user + account on the remote system. This argument must be a valid SSH key + type: str + encrypted_password: + description: + - The C(encrypted_password) argument set already hashed password for the user + account on the remote system. + type: str + purge: + description: + - The C(purge) argument instructs the module to consider the users definition + absolute. It will remove any previously configured users on the device with + the exception of the current defined set of aggregate. + type: bool + default: false + state: + description: + - The C(state) argument configures the state of the user definitions as it relates + to the device operational configuration. When set to I(present), the user should + be configured in the device active configuration and when set to I(absent) the + user should not be in the device active configuration + type: str + choices: + - present + - absent + active: + description: + - Specifies whether or not the configuration is active or deactivated + type: bool + name: + description: + - The C(name) argument defines the username of the user to be created on the system. This + argument must follow appropriate usernaming conventions for the target device + running JUNOS. This argument is mutually exclusive with the C(aggregate) argument. + type: str + full_name: + description: + - The C(full_name) argument provides the full name of the user account to be created + on the remote device. This argument accepts any text string value. + type: str + role: + description: + - The C(role) argument defines the role of the user account on the remote system. User + accounts can have more than one role configured. + type: str + choices: + - operator + - read-only + - super-user + - unauthorized + sshkey: + description: + - The C(sshkey) argument defines the public SSH key to be configured for the user + account on the remote system. This argument must be a valid SSH key + type: str + encrypted_password: + description: + - The C(encrypted_password) argument set already hashed password for the user + account on the remote system. + type: str + purge: + description: + - The C(purge) argument instructs the module to consider the users definition + absolute. It will remove any previously configured users on the device with + the exception of the current defined set of aggregate. + type: bool + default: false + state: + description: + - The C(state) argument configures the state of the user definitions as it relates + to the device operational configuration. When set to I(present), the user should + be configured in the device active configuration and when set to I(absent) the + user should not be in the device active configuration + type: str + default: present + choices: + - present + - absent + active: + description: + - Specifies whether or not the configuration is active or deactivated + type: bool + default: true +requirements: +- ncclient (>=v0.5.2) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. +- Recommended connection is C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +- This module also works with C(local) connections for legacy playbooks. +""" + +EXAMPLES = """ +- name: create new user account + junipernetworks.junos.junos_user: + name: ansible + role: super-user + sshkey: "{{ lookup('file', '~/.ssh/ansible.pub') }}" + state: present + +- name: remove a user account + junipernetworks.junos.junos_user: + name: ansible + state: absent + +- name: remove all user accounts except ansible + junipernetworks.junos.junos_user: + aggregate: + - name: ansible + purge: true + +- name: set user password + junipernetworks.junos.junos_user: + name: ansible + role: super-user + encrypted_password: "{{ 'my-password' | password_hash('sha512') }}" + state: present + +- name: Create list of users + junipernetworks.junos.junos_user: + aggregate: + - {name: test_user1, full_name: test_user2, role: operator, state: present} + - {name: test_user2, full_name: test_user2, role: read-only, state: present} + +- name: Delete list of users + junipernetworks.junos.junos_user: + aggregate: + - {name: test_user1, full_name: test_user2, role: operator, state: absent} + - {name: test_user2, full_name: test_user2, role: read-only, state: absent} +""" +RETURN = """ +diff.prepared: + description: Configuration difference before and after applying change. + returned: when configuration is changed and diff option is enabled. + type: str + sample: > + [edit system login] + + user test-user { + + uid 2005; + + class read-only; + + } +""" +from copy import deepcopy +from functools import partial + +from ansible.module_utils._text import to_text +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import ConnectionError +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + remove_default_spec, +) + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + commit_configuration, + discard_changes, + get_connection, + load_config, + locked_config, + tostring, +) + + +try: + from lxml.etree import Element, SubElement +except ImportError: + from xml.etree.ElementTree import Element, SubElement + +ROLES = ["operator", "read-only", "super-user", "unauthorized"] +USE_PERSISTENT_CONNECTION = True + + +def handle_purge(module, want): + want_users = [item["name"] for item in want] + element = Element("system") + login = SubElement(element, "login") + + conn = get_connection(module) + try: + reply = conn.execute_rpc( + tostring(Element("get-configuration")), + ignore_warning=False, + ) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) + + users = reply.xpath("configuration/system/login/user/name") + if users: + for item in users: + name = item.text + if name not in want_users and name != "root": + user = SubElement(login, "user", {"operation": "delete"}) + SubElement(user, "name").text = name + if element.xpath("/system/login/user/name"): + return element + + +def map_obj_to_ele(module, want): + element = Element("system") + login = SubElement(element, "login") + + for item in want: + if item["state"] != "present": + if item["name"] == "root": + module.fail_json(msg="cannot delete the 'root' account.") + operation = "delete" + else: + operation = "merge" + + if item["name"] != "root": + user = SubElement(login, "user", {"operation": operation}) + SubElement(user, "name").text = item["name"] + else: + user = auth = SubElement( + element, + "root-authentication", + {"operation": operation}, + ) + + if operation == "merge": + if item["name"] == "root" and (not item["active"] or item["role"] or item["full_name"]): + module.fail_json( + msg="'root' account cannot be deactivated or be assigned a role and a full name", + ) + + if item["active"]: + user.set("active", "active") + else: + user.set("inactive", "inactive") + + if item["role"]: + SubElement(user, "class").text = item["role"] + + if item.get("full_name"): + SubElement(user, "full-name").text = item["full_name"] + + if item.get("sshkey"): + auth = SubElement(user, "authentication") + if "ssh-rsa" in item["sshkey"]: + ssh_rsa = SubElement(auth, "ssh-rsa") + elif "ssh-dss" in item["sshkey"]: + ssh_rsa = SubElement(auth, "ssh-dsa") + elif "ecdsa-sha2" in item["sshkey"]: + ssh_rsa = SubElement(auth, "ssh-ecdsa") + elif "ssh-ed25519" in item["sshkey"]: + ssh_rsa = SubElement(auth, "ssh-ed25519") + SubElement(ssh_rsa, "name").text = item["sshkey"] + + if item.get("encrypted_password"): + auth = SubElement(user, "authentication") + SubElement(auth, "encrypted-password").text = item["encrypted_password"] + + return element + + +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): + aggregate = module.params["aggregate"] + if not aggregate: + if not module.params["name"] and module.params["purge"]: + return list() + elif not module.params["name"]: + module.fail_json(msg="missing required argument: name") + else: + collection = [{"name": module.params["name"]}] + else: + collection = list() + for item in aggregate: + if not isinstance(item, dict): + collection.append({"username": item}) + elif "name" not in item: + module.fail_json(msg="missing required argument: name") + else: + collection.append(item) + + objects = list() + + for item in collection: + get_value = partial(get_param_value, item=item, module=module) + item.update( + { + "full_name": get_value("full_name"), + "role": get_value("role"), + "encrypted_password": get_value("encrypted_password"), + "sshkey": get_value("sshkey"), + "state": get_value("state"), + "active": get_value("active"), + }, + ) + + for key, value in iteritems(item): + # validate the param value (if validator func exists) + validator = globals().get("validate_%s" % key) + if all((value, validator)): + validator(value, module) + + objects.append(item) + + return objects + + +def main(): + """main entry point for module execution""" + element_spec = dict( + name=dict(), + full_name=dict(), + role=dict(choices=ROLES), + encrypted_password=dict(no_log=True), + sshkey=dict(no_log=False), + state=dict(choices=["present", "absent"], default="present"), + purge=dict(type="bool", default=False), + active=dict(type="bool", default=True), + ) + + 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=["collection", "users"], + ), + purge=dict(default=False, type="bool"), + ) + aggregate_spec["purge"] = dict(type="bool", default=False) + + argument_spec.update(element_spec) + + mutually_exclusive = [["aggregate", "name"]] + + 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) + ele = map_obj_to_ele(module, want) + + purge_request = None + if module.params["purge"]: + purge_request = handle_purge(module, want) + + with locked_config(module): + if purge_request: + load_config( + module, + tostring(purge_request), + warnings, + action="replace", + ) + diff = load_config(module, tostring(ele), warnings, action="merge") + + commit = not module.check_mode + if diff: + if commit: + commit_configuration(module) + else: + discard_changes(module) + result["changed"] = True + + if module._diff: + result["diff"] = {"prepared": diff} + + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/juniper/device/plugins/modules/junos_vlans.py b/ansible_collections/juniper/device/plugins/modules/junos_vlans.py new file mode 100644 index 00000000..5f7c5b42 --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_vlans.py @@ -0,0 +1,467 @@ +#!/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 junos_vlans +""" + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + + +DOCUMENTATION = """ +module: junos_vlans +short_description: VLANs resource module +description: +- This module creates and manages VLAN configurations on Junos OS. +version_added: 1.0.0 +author: Daniel Mellado (@dmellado) +requirements: +- ncclient (>=v0.6.4) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed +- Tested against Junos OS 18.4R1 +- This module works with connection C(netconf). +- See L(the Junos OS Platform Options,https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html). +options: + config: + description: A dictionary of Vlan options + type: list + elements: dict + suboptions: + vlan_id: + description: + - IEEE 802.1q VLAN identifier for VLAN (1..4094). + type: int + name: + description: + - Name of VLAN. + type: str + required: true + description: + description: + - Text description of VLANs + type: str + l3_interface: + description: + - Name of logical layer 3 interface. + type: str + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the Junos device + by executing the command B(show vlans). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result + type: str + state: + description: + - The state of the configuration after module completion. + type: str + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - parsed + - rendered + default: merged +""" + +EXAMPLES = """ +# Using merged +# +# Before state +# ------------ +# +# vagrant@vsrx# show vlans +# +# [edit] + +- name: Merge provided Junos vlans config with running-config + junipernetworks.junos.junos_vlans: + config: + - name: vlan1 + vlan_id: 1 + - name: vlan2 + vlan_id: 2 + l3_interface: irb.12 + state: merged +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": [ +# { +# "name": "vlan1", +# "vlan_id": 1 +# }, +# { +# "l3_interface": "irb.12", +# "name": "vlan2", +# "vlan_id": 2 +# } +# ], +# "before": [], +# "changed": true, +# "commands": [ +# "" +# "vlan11" +# "vlan22irb.12" +# "" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show vlans +# vlan1 { +# vlan-id 1; +# } +# vlan2 { +# vlan-id 2; +# l3-interface irb.12; +# } + +# Using replaced +# +# Before state +# ------------ +# +# vagrant@vsrx# show vlans +# vlan1 { +# vlan-id 1; +# } +# vlan2 { +# vlan-id 2; +# l3-interface irb.12; +# } + +- name: Replace Junos vlans running-config with the provided config + junipernetworks.junos.junos_vlans: + config: + - name: vlan1 + vlan_id: 11 + l3_interface: irb.10 + + - name: vlan2 + vlan_id: 2 + state: replaced +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": [ +# { +# "l3_interface": "irb.10", +# "name": "vlan1", +# "vlan_id": 11 +# }, +# { +# "name": "vlan2", +# "vlan_id": 2 +# } +# ], +# "before": [ +# { +# "name": "vlan1", +# "vlan_id": 1 +# }, +# { +# "l3_interface": "irb.12", +# "name": "vlan2", +# "vlan_id": 2 +# } +# ], +# "changed": true, +# "commands": [ +# "" +# "vlan1" +# "vlan2" +# "vlan111" +# "irb.10" +# "vlan22" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show vlans +# vlan1 { +# vlan-id 11; +# l3-interface irb.10; +# } +# vlan2 { +# vlan-id 2; +# } +# +# Using overridden +# +# Before state +# ------------ +# +# vagrant@vsrx# show vlans +# vlan1 { +# vlan-id 11; +# l3-interface irb.10; +# } +# vlan2 { +# vlan-id 2; +# } +- name: Override Junos running-config with provided config + junipernetworks.junos.junos_vlans: + config: + - name: vlan3 + vlan_id: 3 + l3_interface: irb.13 + state: overridden +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": [ +# { +# "l3_interface": "irb.13", +# "name": "vlan3", +# "vlan_id": 3 +# } +# ], +# "before": [ +# { +# "l3_interface": "irb.10", +# "name": "vlan1", +# "vlan_id": 11 +# }, +# { +# "name": "vlan2", +# "vlan_id": 2 +# } +# ], +# "changed": true, +# "commands": [ +# "" +# "vlan1" +# "vlan2vlan33" +# "irb.13" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show vlans +# vlan3 { +# vlan-id 3; +# l3-interface irb.13; +# } +# +# Using deleted +# +# Before state +# ------------ +# +# vagrant@vsrx# show vlans +# vlan3 { +# vlan-id 3; +# l3-interface irb.13; +# } +- name: Delete specific vlan + junipernetworks.junos.junos_vlans: + config: + - name: vlan3 + state: deleted +# ------------------------- +# Module Execution Result +# ------------------------- +# "after": [], +# "changed": true, +# "commands": [ +# " +# "vlan3" +# ] +# After state +# ----------- +# +# vagrant@vsrx# show vlans +# vlan1 { +# vlan-id 11; +# l3-interface irb.10; +# } +# vlan2 { +# vlan-id 2; +# } + + +- name: Gather running vlans configuration + junipernetworks.junos.junos_vlans: + state: gathered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "gathered": [ +# { +# "l3_interface": "irb.10", +# "name": "vlan1", +# "vlan_id": 11 +# }, +# { +# "name": "vlan2", +# "vlan_id": 2 +# } +# ], +# "changed": false, +# +# Using rendered +# +# Before state +# ------------ +# +- name: Render xml for provided facts. + junipernetworks.junos.junos_vlans: + config: + - name: vlan1 + vlan_id: 1 + + - name: vlan2 + vlan_id: 2 + l3_interface: irb.12 + state: rendered +# +# ------------------------- +# Module Execution Result +# ------------------------- +# "rendered": [ +# "" +# "vlan11" +# "vlan22irb.12" +# "" +# ] +# Using parsed +# parsed.cfg +# ------------ +# +# +# +# 18.4R1-S2.4 +# +# +# vlan1 +# 1 +# +# +# vlan2 +# 2 +# irb.12 +# +# +# +# + +- name: Parse routing instance running config + junipernetworks.junos.junos_vlans: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "parsed": [ +# { +# "name": "vlan1", +# "vlan_id": 1 +# }, +# { +# "l3_interface": "irb.12", +# "name": "vlan2", +# "vlan_id": 2 +# } +# ] +# +""" + +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: [' + vlan11 + vlan22 + irb.12', 'xml 2', 'xml 3'] +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.argspec.vlans.vlans import ( + VlansArgs, +) +from ansible_collections.juniper.device.plugins.module_utils.network.junos.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", "rendered", ("config",)), + ("state", "overridden", ("config",)), + ("state", "parsed", ("running_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/ansible_collections/juniper/device/plugins/modules/junos_vrf.py b/ansible_collections/juniper/device/plugins/modules/junos_vrf.py new file mode 100644 index 00000000..ed7278ff --- /dev/null +++ b/ansible_collections/juniper/device/plugins/modules/junos_vrf.py @@ -0,0 +1,342 @@ +#!/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 + + +DOCUMENTATION = """ +module: junos_vrf +author: Ganesh Nalawade (@ganeshrn) +short_description: Manage the VRF definitions on Juniper JUNOS devices +description: +- This module provides declarative management of VRF definitions on Juniper JUNOS + devices. It allows playbooks to manage individual or the entire VRF collection. +version_added: 1.0.0 +extends_documentation_fragment: +- junipernetworks.junos.junos +options: + 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(aggregate) argument + type: str + 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. + type: str + 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. + type: list + elements: str + 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. + type: list + elements: str + target: + description: + - It configures VRF target community configuration. The target value takes the + form of C(target:A:B) where C(A) and C(B) are both numeric values. + type: list + elements: str + table_label: + description: + - Causes JUNOS to allocate a VPN label per VRF rather than per VPN FEC. This allows + for forwarding of traffic to directly connected subnets, COS Egress filtering + etc. + default: true + type: bool + aggregate: + description: + - The set of VRF definition objects to be configured on the remote JUNOS 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. + type: list + elements: dict + suboptions: + 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(aggregate) argument + required: true + type: str + 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. + type: str + 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. + type: list + elements: str + 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. + type: list + elements: str + target: + description: + - It configures VRF target community configuration. The target value takes the + form of C(target:A:B) where C(A) and C(B) are both numeric values. + type: list + elements: str + table_label: + description: + - Causes JUNOS to allocate a VPN label per VRF rather than per VPN FEC. This allows + for forwarding of traffic to directly connected subnets, COS Egress filtering + etc. + 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 + type: str + choices: + - present + - absent + active: + description: + - Specifies whether or not the configuration is active or deactivated + 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 + type: str + default: present + choices: + - present + - absent + active: + description: + - Specifies whether or not the configuration is active or deactivated + default: true + type: bool +requirements: +- ncclient (>=v0.5.2) +notes: +- This module requires the netconf system service be enabled on the remote device + being managed. +- Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. +- Recommended connection is C(netconf). See L(the Junos OS Platform Options,../network/user_guide/platform_junos.html). +- This module also works with C(local) connections for legacy playbooks. +""" + +EXAMPLES = """ +- name: Configure vrf configuration + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + state: present + +- name: Remove vrf configuration + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + state: absent + +- name: Deactivate vrf configuration + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + active: false + +- name: Activate vrf configuration + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + active: true + +- name: Create vrf using aggregate + junipernetworks.junos.junos_vrf: + aggregate: + - name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + - name: test-2 + description: test-vrf-2 + interfaces: + - ge-0/0/4 + - ge-0/0/5 + rd: 192.0.2.2:10 + target: target:65515:114 + state: present +""" + +RETURN = """ +diff.prepared: + description: Configuration difference before and after applying change. + returned: when configuration is changed and diff option is enabled. + type: str + sample: > + [edit routing-instances] + + test-1 { + + description test-vrf-1; + + instance-type vrf; + + interface ge-0/0/2.0; + + interface ge-0/0/3.0; + + route-distinguisher 192.0.2.1:10; + + vrf-target target:65514:113; + + } +""" +import collections + +from copy import deepcopy + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + remove_default_spec, +) + +from ansible_collections.juniper.device.plugins.module_utils.network.junos.junos import ( + commit_configuration, + discard_changes, + load_config, + locked_config, + map_obj_to_ele, + map_params_to_obj, + to_param_list, + tostring, +) + + +USE_PERSISTENT_CONNECTION = True + + +def main(): + """main entry point for module execution""" + element_spec = dict( + name=dict(), + description=dict(), + rd=dict(type="list", elements="str"), + interfaces=dict(type="list", elements="str"), + target=dict(type="list", elements="str"), + state=dict(default="present", choices=["present", "absent"]), + active=dict(default=True, type="bool"), + table_label=dict(default=True, type="bool"), + ) + + 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) + + required_one_of = [["aggregate", "name"]] + mutually_exclusive = [["aggregate", "name"]] + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + ) + + warnings = list() + result = {"changed": False} + + if warnings: + result["warnings"] = warnings + + top = "routing-instances/instance" + + param_to_xpath_map = collections.OrderedDict() + param_to_xpath_map.update( + [ + ("name", {"xpath": "name", "is_key": True}), + ("description", "description"), + ("type", "instance-type"), + ("rd", "route-distinguisher/rd-type"), + ("interfaces", "interface/name"), + ("target", "vrf-target/community"), + ("table_label", {"xpath": "vrf-table-label", "tag_only": True}), + ], + ) + + params = to_param_list(module) + requests = list() + + for param in params: + # if key doesn't exist in the item, get it from module.params + for key in param: + if param.get(key) is None: + param[key] = module.params[key] + + item = param.copy() + item["type"] = "vrf" + + want = map_params_to_obj(module, param_to_xpath_map, param=item) + requests.append(map_obj_to_ele(module, want, top, param=item)) + + with locked_config(module): + for req in requests: + diff = load_config(module, tostring(req), warnings, action="merge") + + commit = not module.check_mode + if diff: + if commit: + commit_configuration(module) + else: + discard_changes(module) + result["changed"] = True + + if module._diff: + result["diff"] = {"prepared": diff} + + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/junipernetworks/junos/.ansible-lint b/ansible_collections/junipernetworks/junos/.ansible-lint new file mode 100644 index 00000000..8d9bb70b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.ansible-lint @@ -0,0 +1,5 @@ +--- +profile: production + +exclude_paths: + - changelogs/changelog.yaml diff --git a/ansible_collections/junipernetworks/junos/.flake8 b/ansible_collections/junipernetworks/junos/.flake8 new file mode 100644 index 00000000..03be6924 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.flake8 @@ -0,0 +1,67 @@ +[flake8] + +builtins = _ + +# Print the total number of errors: +count = true + +# Don't even try to analyze these: +extend-exclude = + # No need to traverse egg info dir + *.egg-info, + # tool cache dirs + *_cache + # project env vars + .env, + # GitHub configs + .github, + # Cache files of MyPy + .mypy_cache, + # Cache files of pytest + .pytest_cache, + # Temp dir of pytest-testmon + .tmontmp, + # Occasional virtualenv dir + .venv + # VS Code + .vscode, + # Temporary build dir + build, + # This contains sdists and wheels of ansible-navigator that we don't want to check + dist, + # Metadata of `pip wheel` cmd is autogenerated + pip-wheel-metadata, + # adjacent venv + venv + # ansible won't let me + __init__.py + +# IMPORTANT: avoid using ignore option, always use extend-ignore instead +# Completely and unconditionally ignore the following errors: +extend-ignore = + F841, + # line-length + E501, + # module level import not at top of file + E402 + +# Accessibility/large fonts and PEP8 unfriendly: +max-line-length = 120 + +# Allow certain violations in certain files: +# Please keep both sections of this list sorted, as it will be easier for others to find and add entries in the future +per-file-ignores = + # The following ignores have been researched and should be considered permanent + # each should be preceeded with an explanation of each of the error codes + # If other ignores are added for a specific file in the section following this, + # these will need to be added to that line as well. + + + # S101: Allow the use of assert within the tests directory, since tests require it. + tests/**.py: S101 + + # The following were present during the initial implementation. + # They are expected to be fixed and unignored over time. + +# Count the number of occurrences of each error/warning code and print a report: +statistics = true diff --git a/ansible_collections/junipernetworks/junos/.github/dependabot.yml b/ansible_collections/junipernetworks/junos/.github/dependabot.yml new file mode 100644 index 00000000..5b32d4c1 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.github/dependabot.yml @@ -0,0 +1,9 @@ +--- +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: daily + labels: + - "skip-changelog" diff --git a/ansible_collections/junipernetworks/junos/.github/release-drafter.yml b/ansible_collections/junipernetworks/junos/.github/release-drafter.yml new file mode 100644 index 00000000..e3e5966e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.github/release-drafter.yml @@ -0,0 +1,3 @@ +--- +# see https://github.com/ansible-community/devtools +_extends: ansible-community/devtools diff --git a/ansible_collections/junipernetworks/junos/.github/workflows/check_label.yml b/ansible_collections/junipernetworks/junos/.github/workflows/check_label.yml new file mode 100644 index 00000000..b120bfa3 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.github/workflows/check_label.yml @@ -0,0 +1,11 @@ +--- +name: "Check label" +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true +on: # yamllint disable-line rule:truthy + pull_request_target: + types: [opened, labeled, unlabeled, synchronize] +jobs: + check_label: + uses: ansible/ansible-content-actions/.github/workflows/check_label.yaml@main diff --git a/ansible_collections/junipernetworks/junos/.github/workflows/codecoverage.yml b/ansible_collections/junipernetworks/junos/.github/workflows/codecoverage.yml new file mode 100644 index 00000000..b425edcc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.github/workflows/codecoverage.yml @@ -0,0 +1,15 @@ +--- +name: Code Coverage + +on: # yamllint disable-line rule:truthy + push: + pull_request: + branches: [ main ] + +jobs: + codecoverage: + uses: ansible-network/github_actions/.github/workflows/coverage_network_devices.yml@main + with: + collection_pre_install: >- + git+https://github.com/ansible-collections/ansible.utils.git + git+https://github.com/ansible-collections/ansible.netcommon.git diff --git a/ansible_collections/junipernetworks/junos/.github/workflows/draft_release.yml b/ansible_collections/junipernetworks/junos/.github/workflows/draft_release.yml new file mode 100644 index 00000000..b65c12cc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.github/workflows/draft_release.yml @@ -0,0 +1,18 @@ +--- +name: "Draft release" +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true +on: # yamllint disable-line rule:truthy + workflow_dispatch: +env: + NAMESPACE: ${{ github.repository_owner }} + COLLECTION_NAME: junos + ANSIBLE_COLLECTIONS_PATHS: ./ +jobs: + update_release_draft: + uses: ansible/ansible-content-actions/.github/workflows/draft_release.yaml@main + with: + repo: ${{ github.event.pull_request.head.repo.full_name }} + secrets: + BOT_PAT: ${{ secrets.BOT_PAT }} diff --git a/ansible_collections/junipernetworks/junos/.github/workflows/release.yml b/ansible_collections/junipernetworks/junos/.github/workflows/release.yml new file mode 100644 index 00000000..6dbb1aa3 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.github/workflows/release.yml @@ -0,0 +1,14 @@ +--- +name: "Release collection" +on: # yamllint disable-line rule:truthy + release: + types: [published] + +jobs: + release: + uses: ansible/ansible-content-actions/.github/workflows/release.yaml@main + with: + environment: release + secrets: + ah_token: ${{ secrets.AH_TOKEN }} + ansible_galaxy_api_key: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} diff --git a/ansible_collections/junipernetworks/junos/.github/workflows/tests.yml b/ansible_collections/junipernetworks/junos/.github/workflows/tests.yml new file mode 100644 index 00000000..c0bf515a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.github/workflows/tests.yml @@ -0,0 +1,52 @@ +--- +name: "CI" + +concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +on: # yamllint disable-line rule:truthy + pull_request: + branches: [main] + workflow_dispatch: + schedule: + - cron: '0 0 * * *' + +jobs: + changelog: + uses: ansible/ansible-content-actions/.github/workflows/changelog.yaml@main + if: github.event_name == 'pull_request' + build-import: + uses: ansible/ansible-content-actions/.github/workflows/build_import.yaml@main + ansible-lint: + uses: ansible/ansible-content-actions/.github/workflows/ansible_lint.yaml@main + sanity: + uses: ansible/ansible-content-actions/.github/workflows/sanity.yaml@main + unit-galaxy: + uses: ansible/ansible-content-actions/.github/workflows/unit.yaml@main + unit-source: + uses: ansible-network/github_actions/.github/workflows/unit_source.yml@main + with: + collection_pre_install: >- + git+https://github.com/ansible-collections/ansible.utils.git + git+https://github.com/ansible-collections/ansible.netcommon.git + all_green: + if: ${{ always() && (github.event_name != 'schedule') }} + needs: + - changelog + - build-import + - sanity + - unit-galaxy + - ansible-lint + runs-on: ubuntu-latest + steps: + - run: >- + python -c "assert 'failure' not in + set([ + '${{ needs.changelog.result }}', + '${{ needs.build-import.result }}', + '${{ needs.sanity.result }}', + '${{ needs.unit-galaxy.result }}' + '${{ needs.ansible-lint.result }}' + '${{ needs.unit-source.result }}' + ])" diff --git a/ansible_collections/junipernetworks/junos/.gitignore b/ansible_collections/junipernetworks/junos/.gitignore new file mode 100644 index 00000000..ba1431e6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.gitignore @@ -0,0 +1,2 @@ +.tox +__pycache__ diff --git a/ansible_collections/junipernetworks/junos/.isort.cfg b/ansible_collections/junipernetworks/junos/.isort.cfg new file mode 100644 index 00000000..96237a01 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.isort.cfg @@ -0,0 +1,6 @@ +[settings] +known_first_party=ansible_collections.junipernetworks.junos +line_length=100 +lines_after_imports=2 +lines_between_types=1 +profile=black diff --git a/ansible_collections/junipernetworks/junos/.pre-commit-config.yaml b/ansible_collections/junipernetworks/junos/.pre-commit-config.yaml new file mode 100644 index 00000000..94a9eeab --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.pre-commit-config.yaml @@ -0,0 +1,56 @@ +--- +ci: + # format compatible with commitlint + autoupdate_commit_msg: "chore: pre-commit autoupdate" + autoupdate_schedule: monthly + autofix_commit_msg: "chore: auto fixes from pre-commit.com hooks" + +repos: + - repo: https://github.com/ansible-network/collection_prep + rev: 1.1.1 + hooks: + - id: update-docs + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: check-merge-conflict + - id: check-symlinks + - id: debug-statements + - id: end-of-file-fixer + - id: no-commit-to-branch + args: [--branch, main] + - id: trailing-whitespace + + - repo: https://github.com/asottile/add-trailing-comma + rev: v3.1.0 + hooks: + - id: add-trailing-comma + + - repo: https://github.com/pre-commit/mirrors-prettier + rev: "v4.0.0-alpha.8" + hooks: + - id: prettier + entry: env CI=1 bash -c "prettier --list-different . || ec=$? && prettier --loglevel=error --write . && exit $ec" + pass_filenames: false + args: [] + additional_dependencies: + - prettier + - prettier-plugin-toml + + - repo: https://github.com/PyCQA/isort + rev: 6.0.1 + hooks: + - id: isort + name: Sort import statements using isort + args: ["--filter-files"] + + - repo: https://github.com/psf/black + rev: 25.1.0 + hooks: + - id: black + + - repo: https://github.com/pycqa/flake8 + rev: 7.1.2 + hooks: + - id: flake8 diff --git a/ansible_collections/junipernetworks/junos/.prettierignore b/ansible_collections/junipernetworks/junos/.prettierignore new file mode 100644 index 00000000..cfabbc1d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.prettierignore @@ -0,0 +1,23 @@ +# Stuff we don't want priettier to ever to look into +.*/ + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# A linked collection directory created by pytest-ansible-units + +collections/ + +# Tracked but not manually edited + +# Tracked but manually formatted + +# WIP +tests/integration/targets/junos_config/templates/config.js +README.md diff --git a/ansible_collections/junipernetworks/junos/.yamllint b/ansible_collections/junipernetworks/junos/.yamllint new file mode 100644 index 00000000..3adaf90c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/.yamllint @@ -0,0 +1,15 @@ +--- +extends: default + +ignore: | + .tox + changelogs/* + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + line-length: disable diff --git a/ansible_collections/junipernetworks/junos/CHANGELOG.rst b/ansible_collections/junipernetworks/junos/CHANGELOG.rst new file mode 100644 index 00000000..450f3a56 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/CHANGELOG.rst @@ -0,0 +1,618 @@ +============================================== +Junipernetworks Junos Collection Release Notes +============================================== + +.. contents:: Topics + +v9.1.0 +====== + +Minor Changes +------------- + +- Add implementation to gather ether-channels for gig-ether-options. +- Added support for virtual-switch instances. +- Based on ether-option-type create supported commands for config module. +- Implemented bridge-domains configuration management for routing instances. +- Implemented support for setting the Maximum Transmission Unit (MTU) in Layer 3 (L3) Internet Protocol (IP) interfaces. +- Tested successfully on Junos MX204. + +Bugfixes +-------- + +- Fix the lag_interfaces facts for gigether supported model. + +v9.0.0 +====== + +Release Summary +--------------- + +Starting from this release, the minimum `ansible-core` version this collection requires is `2.15.0`. The last known version compatible with ansible-core<2.15 is v8.0.0. + +Major Changes +------------- + +- Bumping `requires_ansible` to `>=2.15.0`, since previous ansible-core versions are EoL now. + +v8.0.0 +====== + +Major Changes +------------- + +- Update the netcommon base version 6.1.0 to support cli_restore plugin. + +Minor Changes +------------- + +- Add support for cli_restore functionality. +- Please refer the PR to know more about core changes (https://github.com/ansible-collections/ansible.netcommon/pull/618). +- cli_restore module is part of netcommon. + +v7.0.0 +====== + +Major Changes +------------- + +- This release removes previously deprecated modules from this collection. Please refer to the **Removed Features** section for details. + +Removed Features (previously deprecated) +---------------------------------------- + +- Remove deprected junos_logging module which is replaced by junos_logging_global resource module. + +Bugfixes +-------- + +- Fix the empty facts list placement + +v6.0.2 +====== + +Bugfixes +-------- + +- acls +- initialize facts dictionary with empty containers for respective resources mentioned below +- lldp_global +- lldp_interfaces +- logging_global +- ntp_global +- ospf_interfaces +- ospfv2 +- ospfv3 +- prefix_lists +- routing_instances +- routing_options +- security_policies +- security_policies_global +- security_zones +- snmp_server +- static_routes +- vlans + +Documentation Changes +--------------------- + +- Remove the part of the description which incorrectly describes the behavior and type of confirm attribute. +- Update example performing `confirm_commit`. +- Update with more examples using the `confirm` option to set a timer. + +v6.0.1 +====== + +Bugfixes +-------- + +- Prevents module_defaults from were being incorrectly applied to the platform action, instead of the concerned module. + +v6.0.0 +====== + +Release Summary +--------------- + +Starting from this release, the minimum `ansible-core` version this collection requires is `2.14.0`. That last known version compatible with ansible-core<2.14 is `v5.3.1`. + +Major Changes +------------- + +- Bumping `requires_ansible` to `>=2.14.0`, since previous ansible-core versions are EoL now. + +v5.3.1 +====== + +Bugfixes +-------- + +- fix to gather l2_interfaces facts with default port-mode access. + +Documentation Changes +--------------------- + +- Improve docs of prefix-lists RM. +- ios_l2_interfaces - Fixed module documentation and examples. +- ios_l3_interfaces - Fixed module documentation and examples. + +v5.3.0 +====== + +Minor Changes +------------- + +- add overridden state opperation support. + +Bugfixes +-------- + +- fix `no_advertise_adjacency_segment` config implementation. +- fix `no_eligible_backup` config implementation. +- fix `no_eligible_remote_backup` config implementation. +- fix `no_interface_state_traps` config implementation. +- fix `no_neighbor_down_notification` config implementation. +- fix `node_link_protection` implementation. +- fix md5 authentication which allows list of keys to be configured. + +v5.2.0 +====== + +Minor Changes +------------- + +- `junos_ospfv2` - Fix the authentication config when password is configured +- `junos_ospfv2` - Rename key ospf to ospfv2 in facts. +- `junos_ospfv2` - add area_ranges attribute which supports list of dict attributes. +- `junos_ospfv2` - add attributes `allow_route_leaking`, `stub_network` and `as-external` to overload dict. +- `junos_ospfv2` - add attributes `no_ignore_out_externals` to spf_options dict. +- `junos_ospfv2` - fix to gather reference_bandwidth and rfc1583compatibility. +- add acl_interfaces key for junos_facts output. + +Deprecated Features +------------------- + +- `junos_ospfv2` - add deprecate warning for area_range. +- add deprecate warning for junos_acl_interfaces key for junos facts results. + +Documentation Changes +--------------------- + +- Update examples for junos_ospfv3 + +v5.1.0 +====== + +Minor Changes +------------- + +- Adding unlink option to junos package installation. + +Bugfixes +-------- + +- Fix enabled attribute implementation. +- Fix lldp_global_assertion. +- Fix sanity issues. +- Fix the snmp view and traps configuration. +- fix the implementation of disabling interface. +- module should return with failure when rollback is 0 and device is not reachable. + +Documentation Changes +--------------------- + +- Update bgp_address_family docs with examples. +- Update bgp_global docs with examples. +- junos_interfaces - Updated documentation with examples and task output. +- junos_static_routes - add task output to module documentation examples. (https://github.com/ansible-collections/junipernetworks.junos/pull/402). + +v5.0.0 +====== + +Major Changes +------------- + +- change gathered key from junos_acls to acls + +Bugfixes +-------- + +- enable provider support for junos_scp and junos_package. +- fix diff to result when prepared diff exists. +- fix junos_security_zones facts gathering when we have single interface configured. +- revert diff mode to default. + +v4.1.0 +====== + +Minor Changes +------------- + +- Implement file_size as string. +- Used xmltodict to gather the sub-module chassis list and return it as a dictionary. + +v4.0.0 +====== + +Major Changes +------------- + +- Use of connection: local and the provider option are no longer valid on any modules in this collection. + +Removed Features (previously deprecated) +---------------------------------------- + +- Remove following deprecated Junos Modules. +- junos_interface +- junos_l2_interface +- junos_l3_interface +- junos_linkagg +- junos_lldp +- junos_lldp_interface +- junos_static_route +- junos_vlan + +v3.1.0 +====== + +Minor Changes +------------- + +- Add mac-vrf instance type. + +Bugfixes +-------- + +- fixes the nighbors list overwrite issue. + +v3.0.1 +====== + +Bugfixes +-------- + +- Fix incorrect param pass to to_text. + +v3.0.0 +====== + +Major Changes +------------- + +- Minimum required ansible.netcommon version is 2.5.1. +- Updated base plugin references to ansible.netcommon. +- `junos_facts` - change default gather_subset to `min` from `!config`. + +Bugfixes +-------- + +- Fix junos_acl fact gathering when only destination port defined (https://github.com/ansible-collections/junipernetworks.junos/issues/268). + +v2.10.0 +======= + +Minor Changes +------------- + +- Added junos_security_policies module. +- Added junos_security_policies_global module. +- Added junos_security_zones module. + +New Modules +----------- + +- junos_security_policies - Create and manage security policies on Juniper JUNOS devices +- junos_security_policies_global - Manage global security policy settings on Juniper JUNOS devices +- junos_security_zones - Manage security zones on Juniper JUNOS devices + +v2.9.0 +====== + +Minor Changes +------------- + +- Add junos_hostname resource module. +- Allow interfaces resource module to configure and gather logical interface description. + +Bugfixes +-------- + +- Fix junos_command output when empty config response is received for show commands (https://github.com/ansible-collections/junipernetworks.junos/issues/249). + +New Modules +----------- + +- junos_hostname - Manage Hostname server configuration on Junos devices. +- junos_snmp_server - Manage SNMP server configuration on Junos devices. + +v2.8.0 +====== + +Minor Changes +------------- + +- Add junos_routing_options resource module. +- Add junos_snmp_server resource module. + +Deprecated Features +------------------- + +- 'router_id' options is deprecated from junos_ospf_interfaces, junos_ospfv2 and junos_ospfv3 resuorce module. + +New Modules +----------- + +- junos_routing_options - Manage routing-options configuration on Junos devices. + +v2.7.1 +====== + +Bugfixes +-------- + +- Fix ospf router_id overlap issue. + +v2.7.0 +====== + +Documentation Changes +--------------------- + +- Add note for router_id deprecation from ospf-interfaces resource module. +- make sure router_id facts and config operation works fine for ospfv2 and ospfv3 RM + +v2.6.0 +====== + +Minor Changes +------------- + +- Add junos_ntp_global resource module. + +Deprecated Features +------------------- + +- Deprecated router_id from ospfv2 resource module. + +New Modules +----------- + +- junos_ntp_global - Manage NTP configuration on Junos devices. + +v2.5.0 +====== + +Minor Changes +------------- + +- Improve junos ospfv2 integration and unit tests coverage and router id assignment check implemented. +- Improve junos vlans integration and unit tests coverage and facts gathering logic modification. + +Deprecated Features +------------------- + +- Deprecated router_id from ospfv3 resource module. + +v2.4.0 +====== + +Minor Changes +------------- + +- Add junos_logging_global Resource Module. +- Add support for backup_format option in junos_config +- support l3_interface in junos vlans + +Deprecated Features +------------------- + +- The junos_logging module has been deprecated in favor of the new junos_logging_global resource module and will be removed in a release after '2023-08-01'. + +Bugfixes +-------- + +- fix lacp force-up without port-priority in junos_lacp_interfaces +- fix netconf test-case for lacp revert +- junos_acls failed to parse acl when multiple addresses defined within a single term (https://github.com/ansible-collections/junipernetworks.junos/issues/190) + +New Modules +----------- + +- junos_logging_global - Manage logging configuration on Junos devices. + +v2.3.0 +====== + +Minor Changes +------------- + +- Add junos_prefix_lists Resource Module. + +v2.2.0 +====== + +Minor Changes +------------- + +- Change src element from str to path for junos_scp. +- Improve junos_bgp_address_family unit test coverage. + +v2.1.0 +====== + +Minor Changes +------------- + +- Add junos_routing_instances Resource Module. +- Add support for available_network_resources key, which allows to fetch the available resources for a platform (https://github.com/ansible-collections/junipernetworks.junos/issues/160). +- Replace unsupported parameter `vlan-id` in junipernetworks.junos.junos_vlans module with `vlan_id` + +Security Fixes +-------------- + +- Mask values of sensitive keys in module result(https://github.com/ansible-collections/junipernetworks.junos/issues/165). + +New Modules +----------- + +- junos_routing_instances - Manage routing instances on Junos devices. + +v2.0.1 +====== + +Minor Changes +------------- + +- Add support df_bit and size option for junos_ping (https://github.com/ansible-collections/junipernetworks.junos/pull/136). + +v2.0.0 +====== + +Major Changes +------------- + +- Please refer to ansible.netcommon `changelog `_ for more details. +- Requires ansible.netcommon v2.0.0+ to support `ansible_network_single_user_mode` and `ansible_network_import_modules`. + +Minor Changes +------------- + +- Add junos_bgp_address_family resource module. +- Add support for autonomous-system routing-options for bgp global and updating tests and documentation. +- Add support for bgp group and neighbors in bgp_global resource module. +- Add support for configuration caching (single_user_mode). +- Re-use device_info dictionary in cliconf. + +New Modules +----------- + +- junos_bgp_address_family - Manage BGP Address Family attributes of interfaces on Junos devices. + +v1.3.0 +====== + +Minor Changes +------------- + +- Add junos bgp global resource module. +- Add ospf interfaces resource module. + +Bugfixes +-------- + +- changing prefix list type to list and correcting facts gathering (https://github.com/ansible-collections/junipernetworks.junos/issues/131) +- constructing the facts based on the addresses per unit (https://github.com/ansible-collections/junipernetworks.junos/issues/111) +- release version added updated to 1.3.0 for junos_ospf_interfaces and junos_bgp_global module + +New Modules +----------- + +- junos_bgp_global - Manages BGP Global configuration on devices running Juniper JUNOS. +- junos_ospf_interfaces - OSPF Interfaces Resource Module. + +v1.2.1 +====== + +Bugfixes +-------- + +- Add version key to galaxy.yaml to work around ansible-galaxy bug +- Updating unit tests for resource modules (https://github.com/ansible-collections/junipernetworks.junos/pull/127) +- allowing partial config filter for junos commands (https://github.com/ansible-collections/junipernetworks.junos/issues/112) +- checking for units and family attributes in conf dictionary (https://github.com/ansible-collections/junipernetworks.junos/issues/121) + +v1.2.0 +====== + +Minor Changes +------------- + +- Add ospfv3 resource module. + +New Modules +----------- + +- junos_ospfv3 - OSPFv3 resource module + +v1.1.1 +====== + +Minor Changes +------------- + +- Use FQCN to M() references in modules documentation (https://github.com/ansible-collections/junipernetworks.junos/pull/79) + +v1.1.0 +====== + +Minor Changes +------------- + +- Gathered state operation enabled, Parsed and rendered state operations implemented for junos_lacp. +- Gathered state operation enabled, Parsed and rendered state operations implemented for junos_lldp_global. +- Gathered state operation enabled, Parsed and rendered state operations implemented for junos_lldp_interfaces. +- Gathered state operation enabled, Parsed and rendered state operations implemented for ospfv2, acl_interfaces, vlans and static_routes RM. +- Gathered state operation enabled. Parsed and rendered state operations implemented. +- Gathered state operation enabledand Parsed and rendered state operations implemented. + +Bugfixes +-------- + +- set_config called only when state is not gathered so that gathered opeartion works fine (https://github.com/ansible-collections/junipernetworks.junos/issues/89). +- set_config called only when state is not gathered so that gathered opeartion works fine (https://github.com/ansible-collections/junipernetworks.junos/issues/93). +- set_config called only when state is not gathered so that gathered opeartion works fine for l2_interfaces resource module (https://github.com/ansible-collections/junipernetworks.junos/issues/91). + +v1.0.1 +====== + +Bugfixes +-------- + +- Make `src`, `backup` and `backup_options` in junos_config work when module alias is used (https://github.com/ansible-collections/junipernetworks.junos/pull/83). +- Update docs after sanity fixes to modules. + +v1.0.0 +====== + +New Plugins +----------- + +Cliconf +~~~~~~~ + +- junos - Use junos cliconf to run command on Juniper Junos OS platform + +Netconf +~~~~~~~ + +- junos - Use junos netconf plugin to run netconf commands on Juniper JUNOS platform + +New Modules +----------- + +- junos_acl_interfaces - ACL interfaces resource module +- junos_acls - ACLs resource module +- junos_banner - Manage multiline banners on Juniper JUNOS devices +- junos_command - Run arbitrary commands on an Juniper JUNOS device +- junos_config - Manage configuration on devices running Juniper JUNOS +- junos_facts - Collect facts from remote devices running Juniper Junos +- junos_interfaces - Junos Interfaces resource module +- junos_l2_interfaces - L2 interfaces resource module +- junos_l3_interfaces - L3 interfaces resource module +- junos_lacp - Global Link Aggregation Control Protocol (LACP) Junos resource module +- junos_lacp_interfaces - LACP interfaces resource module +- junos_lag_interfaces - Link Aggregation Juniper JUNOS resource module +- junos_lldp_global - LLDP resource module +- junos_lldp_interfaces - LLDP interfaces resource module +- junos_logging - Manage logging on network devices +- junos_netconf - Configures the Junos Netconf system service +- junos_ospfv2 - OSPFv2 resource module +- junos_package - Installs packages on remote devices running Junos +- junos_ping - Tests reachability using ping from devices running Juniper JUNOS +- junos_rpc - Runs an arbitrary RPC over NetConf on an Juniper JUNOS device +- junos_scp - Transfer files from or to remote devices running Junos +- junos_static_routes - Static routes resource module +- junos_system - Manage the system attributes on Juniper JUNOS devices +- junos_user - Manage local user accounts on Juniper JUNOS devices +- junos_vlans - VLANs resource module +- junos_vrf - Manage the VRF definitions on Juniper JUNOS devices diff --git a/ansible_collections/junipernetworks/junos/LICENSE b/ansible_collections/junipernetworks/junos/LICENSE new file mode 100644 index 00000000..f288702d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program 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. + + This program 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 this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/ansible_collections/junipernetworks/junos/README.md b/ansible_collections/junipernetworks/junos/README.md new file mode 100644 index 00000000..cccb6c25 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/README.md @@ -0,0 +1,187 @@ +# Juniper Networks Junos Collection + +[![CI](https://zuul-ci.org/gated.svg)](https://dashboard.zuul.ansible.com/t/ansible/project/github.com/ansible-collections/junipernetworks.junos) +[![Codecov](https://codecov.io/gh/ansible-collections/junipernetworks.junos/branch/main/graph/badge.svg)](https://codecov.io/gh/ansible-collections/junipernetworks.junos) +[![CI](https://github.com/ansible-collections/junipernetworks.junos/actions/workflows/tests.yml/badge.svg?branch=main&event=schedule)](https://github.com/ansible-collections/junipernetworks.junos/actions/workflows/tests.yml) + +The Ansible Juniper Networks Junos collection includes a variety of Ansible content to help automate the management of Juniper Networks Junos network appliances. + +This collection has been tested against Juniper Networks Junos OS 18.4R1. + +## Support + +As a Red Hat Ansible [Certified Content](https://catalog.redhat.com/software/search?target_platforms=Red%20Hat%20Ansible%20Automation%20Platform), this collection is entitled to [support](https://access.redhat.com/support/) through [Ansible Automation Platform](https://www.redhat.com/en/technologies/management/ansible) (AAP). + +If a support case cannot be opened with Red Hat and the collection has been obtained either from [Galaxy](https://galaxy.ansible.com/ui/) or [GitHub](https://github.com/ansible-collections/junipernetworks.junos), there is community support available at no charge. + +You can join us on [#network:ansible.com](https://matrix.to/#/#network:ansible.com) room or the [Ansible Forum Network Working Group](https://forum.ansible.com/g/network-wg). + +For more information you can check the communication section below. + +## Communication + +* Join the Ansible forum: + * [Get Help](https://forum.ansible.com/c/help/6): get help or help others. + * [Posts tagged with 'juniper'](https://forum.ansible.com/tag/juniper): subscribe to participate in collection-related conversations. + * [Ansible Network Automation Working Group](https://forum.ansible.com/g/network-wg/): by joining the team you will automatically get subscribed to the posts tagged with [network](https://forum.ansible.com/tags/network). + * [Social Spaces](https://forum.ansible.com/c/chat/4): gather and interact with fellow enthusiasts. + * [News & Announcements](https://forum.ansible.com/c/news/5): track project-wide announcements including social events. + +* The Ansible [Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn): used to announce releases and important changes. + +For more information about communication, see the [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html). + + +## Ansible version compatibility + +This collection has been tested against following Ansible versions: **>=2.15.0**. + +For collections that support Ansible 2.9, please ensure you update your `network_os` to use the +fully qualified collection name (for example, `cisco.ios.ios`). +Plugins and modules within a collection may be tested with only specific Ansible versions. +A collection may contain metadata that identifies these versions. +PEP440 is the schema used to describe the versions of Ansible. + + +### Supported connections + +The Juniper Networks Junos collection supports `network_cli` and `netconf` connections. + +## Included content + + +### Cliconf plugins +Name | Description +--- | --- +[junipernetworks.junos.junos](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_cliconf.rst)|Use junos cliconf to run command on Juniper Junos OS platform + +### Netconf plugins +Name | Description +--- | --- +[junipernetworks.junos.junos](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_netconf.rst)|Use junos netconf plugin to run netconf commands on Juniper JUNOS platform + +### Modules +Name | Description +--- | --- +[junipernetworks.junos.junos_acl_interfaces](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_acl_interfaces_module.rst)|ACL interfaces resource module +[junipernetworks.junos.junos_acls](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_acls_module.rst)|ACLs resource module +[junipernetworks.junos.junos_banner](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_banner_module.rst)|Manage multiline banners on Juniper JUNOS devices +[junipernetworks.junos.junos_bgp_address_family](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_bgp_address_family_module.rst)|Manage BGP Address Family attributes of interfaces on Junos devices. +[junipernetworks.junos.junos_bgp_global](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_bgp_global_module.rst)|Manages BGP Global configuration on devices running Juniper JUNOS. +[junipernetworks.junos.junos_command](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_command_module.rst)|Run arbitrary commands on an Juniper JUNOS device +[junipernetworks.junos.junos_config](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_config_module.rst)|Manage configuration on devices running Juniper JUNOS +[junipernetworks.junos.junos_facts](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_facts_module.rst)|Collect facts from remote devices running Juniper Junos +[junipernetworks.junos.junos_hostname](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_hostname_module.rst)|Manage Hostname server configuration on Junos devices. +[junipernetworks.junos.junos_interfaces](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_interfaces_module.rst)|Junos Interfaces resource module +[junipernetworks.junos.junos_l2_interfaces](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_l2_interfaces_module.rst)|L2 interfaces resource module +[junipernetworks.junos.junos_l3_interfaces](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_l3_interfaces_module.rst)|L3 interfaces resource module +[junipernetworks.junos.junos_lacp](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_lacp_module.rst)|Global Link Aggregation Control Protocol (LACP) Junos resource module +[junipernetworks.junos.junos_lacp_interfaces](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_lacp_interfaces_module.rst)|LACP interfaces resource module +[junipernetworks.junos.junos_lag_interfaces](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_lag_interfaces_module.rst)|Link Aggregation Juniper JUNOS resource module +[junipernetworks.junos.junos_lldp_global](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_lldp_global_module.rst)|LLDP resource module +[junipernetworks.junos.junos_lldp_interfaces](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_lldp_interfaces_module.rst)|LLDP interfaces resource module +[junipernetworks.junos.junos_logging_global](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_logging_global_module.rst)|Manage logging configuration on Junos devices. +[junipernetworks.junos.junos_netconf](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_netconf_module.rst)|Configures the Junos Netconf system service +[junipernetworks.junos.junos_ntp_global](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_ntp_global_module.rst)|Manage NTP configuration on Junos devices. +[junipernetworks.junos.junos_ospf_interfaces](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_ospf_interfaces_module.rst)|OSPF Interfaces Resource Module. +[junipernetworks.junos.junos_ospfv2](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_ospfv2_module.rst)|OSPFv2 resource module +[junipernetworks.junos.junos_ospfv3](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_ospfv3_module.rst)|OSPFv3 resource module +[junipernetworks.junos.junos_package](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_package_module.rst)|Installs packages on remote devices running Junos +[junipernetworks.junos.junos_ping](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_ping_module.rst)|Tests reachability using ping from devices running Juniper JUNOS +[junipernetworks.junos.junos_prefix_lists](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_prefix_lists_module.rst)|Manage prefix-lists attributes of interfaces on Junos devices. +[junipernetworks.junos.junos_routing_instances](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_routing_instances_module.rst)|Manage routing instances on Junos devices. +[junipernetworks.junos.junos_routing_options](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_routing_options_module.rst)|Manage routing-options configuration on Junos devices. +[junipernetworks.junos.junos_rpc](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_rpc_module.rst)|Runs an arbitrary RPC over NetConf on an Juniper JUNOS device +[junipernetworks.junos.junos_scp](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_scp_module.rst)|Transfer files from or to remote devices running Junos +[junipernetworks.junos.junos_security_policies](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_security_policies_module.rst)|Create and manage security policies on Juniper JUNOS devices +[junipernetworks.junos.junos_security_policies_global](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_security_policies_global_module.rst)|Manage global security policy settings on Juniper JUNOS devices +[junipernetworks.junos.junos_security_zones](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_security_zones_module.rst)|Manage security zones on Juniper JUNOS devices +[junipernetworks.junos.junos_snmp_server](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_snmp_server_module.rst)|Manage SNMP server configuration on Junos devices. +[junipernetworks.junos.junos_static_routes](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_static_routes_module.rst)|Static routes resource module +[junipernetworks.junos.junos_system](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_system_module.rst)|Manage the system attributes on Juniper JUNOS devices +[junipernetworks.junos.junos_user](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_user_module.rst)|Manage local user accounts on Juniper JUNOS devices +[junipernetworks.junos.junos_vlans](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_vlans_module.rst)|VLANs resource module +[junipernetworks.junos.junos_vrf](https://github.com/ansible-collections/junipernetworks.junos/blob/main/docs/junipernetworks.junos.junos_vrf_module.rst)|Manage the VRF definitions on Juniper JUNOS devices + + + +Click the `Content` button to see the list of content included in this collection. + +## Installing this collection + +You can install the Juniper Networks Junos collection with the Ansible Galaxy CLI: + + ansible-galaxy collection install junipernetworks.junos + +You can also include it in a `requirements.yml` file and install it with `ansible-galaxy collection install -r requirements.yml`, using the format: + +```yaml +--- +collections: + - name: junipernetworks.junos +``` + +## Using this collection + +You can call modules by their Fully Qualified Collection Namespace (FQCN), such as `junipernetworks.junos.junos_l2_interfaces`. +The following example task replaces configuration changes in the existing configuration on a Juniper Networks Junos network device, using the FQCN: + +```yaml +--- +- name: "Replace provided configuration with device configuration" + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/3 + access: + vlan: v101 + - name: ge-0/0/4 + trunk: + allowed_vlans: + - vlan30 + native_vlan: 50 + state: replaced +``` + +### See Also: + +- [Juniper Junos Platform options](https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html). +- [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details. + +## Contributing to this collection + +We welcome community contributions to this collection. If you find problems, please open an issue or create a PR against the [Juniper Networks Junos collection repository](https://github.com/ansible-collections/junipernetworks.junos). See [Contributing to Ansible-maintained collections](https://docs.ansible.com/ansible/devel/community/contributing_maintained_collections.html#contributing-maintained-collections) for complete details. + +You can also join us on: + +- IRC - the `#ansible-network` [irc.libera.chat](https://libera.chat/) channel +- Slack - https://ansiblenetwork.slack.com + +See the [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html) for details on contributing to Ansible. + +### Code of Conduct + +This collection follows the Ansible project's +[Code of Conduct](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html). +Please read and familiarize yourself with this document. + +## Release notes + +Release notes are available [here](https://github.com/ansible-collections/junipernetworks.junos/blob/main/CHANGELOG.rst). + +## Roadmap + + + +## More information + +- [Ansible network resources](https://docs.ansible.com/ansible/latest/network/getting_started/network_resources.html) +- [Ansible Collection overview](https://github.com/ansible-collections/overview) +- [Ansible User guide](https://docs.ansible.com/ansible/latest/user_guide/index.html) +- [Ansible Developer guide](https://docs.ansible.com/ansible/latest/dev_guide/index.html) +- [Ansible Community code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html) + +## Licensing + +GNU General Public License v3.0 or later. + +See [LICENSE](https://www.gnu.org/licenses/gpl-3.0.txt) to see the full text. diff --git a/ansible_collections/junipernetworks/junos/bindep.txt b/ansible_collections/junipernetworks/junos/bindep.txt new file mode 100644 index 00000000..cffe80b2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/bindep.txt @@ -0,0 +1,7 @@ +# This is a cross-platform list tracking distribution packages needed by tests; +# see https://docs.openstack.org/infra/bindep/ for additional information. + +gcc-c++ [doc test platform:rpm] +python3-devel [test platform:rpm] +python3 [test platform:rpm] +libssh-devel [compile platform:rpm] diff --git a/ansible_collections/junipernetworks/junos/changelogs/.plugin-cache.yaml b/ansible_collections/junipernetworks/junos/changelogs/.plugin-cache.yaml new file mode 100644 index 00000000..9fe8f6c3 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/changelogs/.plugin-cache.yaml @@ -0,0 +1,226 @@ +objects: + role: {} +plugins: + become: {} + cache: {} + callback: {} + cliconf: + junos: + description: Use junos cliconf to run command on Juniper Junos OS platform + name: junos + version_added: 1.0.0 + connection: {} + filter: {} + httpapi: {} + inventory: {} + lookup: {} + module: + junos_acl_interfaces: + description: ACL interfaces resource module + name: junos_acl_interfaces + namespace: "" + version_added: 1.0.0 + junos_acls: + description: ACLs resource module + name: junos_acls + namespace: "" + version_added: 1.0.0 + junos_banner: + description: Manage multiline banners on Juniper JUNOS devices + name: junos_banner + namespace: "" + version_added: 1.0.0 + junos_bgp_address_family: + description: Manage BGP Address Family attributes of interfaces on Junos devices. + name: junos_bgp_address_family + namespace: "" + version_added: 1.3.0 + junos_bgp_global: + description: Manages BGP Global configuration on devices running Juniper JUNOS. + name: junos_bgp_global + namespace: "" + version_added: 1.3.0 + junos_command: + description: Run arbitrary commands on an Juniper JUNOS device + name: junos_command + namespace: "" + version_added: 1.0.0 + junos_config: + description: Manage configuration on devices running Juniper JUNOS + name: junos_config + namespace: "" + version_added: 1.0.0 + junos_facts: + description: Collect facts from remote devices running Juniper Junos + name: junos_facts + namespace: "" + version_added: 1.0.0 + junos_hostname: + description: Manage Hostname server configuration on Junos devices. + name: junos_hostname + namespace: "" + version_added: 2.9.0 + junos_interfaces: + description: Junos Interfaces resource module + name: junos_interfaces + namespace: "" + version_added: 1.0.0 + junos_l2_interfaces: + description: L2 interfaces resource module + name: junos_l2_interfaces + namespace: "" + version_added: 1.0.0 + junos_l3_interfaces: + description: L3 interfaces resource module + name: junos_l3_interfaces + namespace: "" + version_added: 1.0.0 + junos_lacp: + description: + Global Link Aggregation Control Protocol (LACP) Junos resource + module + name: junos_lacp + namespace: "" + version_added: 1.0.0 + junos_lacp_interfaces: + description: LACP interfaces resource module + name: junos_lacp_interfaces + namespace: "" + version_added: 1.0.0 + junos_lag_interfaces: + description: Link Aggregation Juniper JUNOS resource module + name: junos_lag_interfaces + namespace: "" + version_added: 1.0.0 + junos_lldp_global: + description: LLDP resource module + name: junos_lldp_global + namespace: "" + version_added: 1.0.0 + junos_lldp_interfaces: + description: LLDP interfaces resource module + name: junos_lldp_interfaces + namespace: "" + version_added: 1.0.0 + junos_logging_global: + description: Manage logging configuration on Junos devices. + name: junos_logging_global + namespace: "" + version_added: 2.4.0 + junos_netconf: + description: Configures the Junos Netconf system service + name: junos_netconf + namespace: "" + version_added: 1.0.0 + junos_ntp_global: + description: Manage NTP configuration on Junos devices. + name: junos_ntp_global + namespace: "" + version_added: 2.6.0 + junos_ospf_interfaces: + description: OSPF Interfaces Resource Module. + name: junos_ospf_interfaces + namespace: "" + version_added: 1.3.0 + junos_ospfv2: + description: OSPFv2 resource module + name: junos_ospfv2 + namespace: "" + version_added: 1.0.0 + junos_ospfv3: + description: OSPFv3 resource module + name: junos_ospfv3 + namespace: "" + version_added: 1.2.0 + junos_package: + description: Installs packages on remote devices running Junos + name: junos_package + namespace: "" + version_added: 1.0.0 + junos_ping: + description: Tests reachability using ping from devices running Juniper JUNOS + name: junos_ping + namespace: "" + version_added: 1.0.0 + junos_prefix_lists: + description: Manage prefix-lists attributes of interfaces on Junos devices. + name: junos_prefix_lists + namespace: "" + version_added: 2.1.0 + junos_routing_instances: + description: Manage routing instances on Junos devices. + name: junos_routing_instances + namespace: "" + version_added: 2.1.0 + junos_routing_options: + description: Manage routing-options configuration on Junos devices. + name: junos_routing_options + namespace: "" + version_added: 2.8.0 + junos_rpc: + description: Runs an arbitrary RPC over NetConf on an Juniper JUNOS device + name: junos_rpc + namespace: "" + version_added: 1.0.0 + junos_scp: + description: Transfer files from or to remote devices running Junos + name: junos_scp + namespace: "" + version_added: 1.0.0 + junos_security_policies: + description: Create and manage security policies on Juniper JUNOS devices + name: junos_security_policies + namespace: "" + version_added: 2.9.0 + junos_security_policies_global: + description: Manage global security policy settings on Juniper JUNOS devices + name: junos_security_policies_global + namespace: "" + version_added: 2.9.0 + junos_security_zones: + description: Manage security zones on Juniper JUNOS devices + name: junos_security_zones + namespace: "" + version_added: 2.9.0 + junos_snmp_server: + description: Manage SNMP server configuration on Junos devices. + name: junos_snmp_server + namespace: "" + version_added: 2.9.0 + junos_static_routes: + description: Static routes resource module + name: junos_static_routes + namespace: "" + version_added: 1.0.0 + junos_system: + description: Manage the system attributes on Juniper JUNOS devices + name: junos_system + namespace: "" + version_added: 1.0.0 + junos_user: + description: Manage local user accounts on Juniper JUNOS devices + name: junos_user + namespace: "" + version_added: 1.0.0 + junos_vlans: + description: VLANs resource module + name: junos_vlans + namespace: "" + version_added: 1.0.0 + junos_vrf: + description: Manage the VRF definitions on Juniper JUNOS devices + name: junos_vrf + namespace: "" + version_added: 1.0.0 + netconf: + junos: + description: + Use junos netconf plugin to run netconf commands on Juniper JUNOS + platform + name: junos + version_added: 1.0.0 + shell: {} + strategy: {} + test: {} + vars: {} +version: 9.1.0 diff --git a/ansible_collections/junipernetworks/junos/changelogs/changelog.yaml b/ansible_collections/junipernetworks/junos/changelogs/changelog.yaml new file mode 100644 index 00000000..111ba0a6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/changelogs/changelog.yaml @@ -0,0 +1,687 @@ +ancestor: null +releases: + 1.0.0: + modules: + - description: ACL interfaces resource module + name: junos_acl_interfaces + namespace: "" + - description: ACLs resource module + name: junos_acls + namespace: "" + - description: Manage multiline banners on Juniper JUNOS devices + name: junos_banner + namespace: "" + - description: Run arbitrary commands on an Juniper JUNOS device + name: junos_command + namespace: "" + - description: Manage configuration on devices running Juniper JUNOS + name: junos_config + namespace: "" + - description: Collect facts from remote devices running Juniper Junos + name: junos_facts + namespace: "" + - description: Junos Interfaces resource module + name: junos_interfaces + namespace: "" + - description: L2 interfaces resource module + name: junos_l2_interfaces + namespace: "" + - description: L3 interfaces resource module + name: junos_l3_interfaces + namespace: "" + - description: + Global Link Aggregation Control Protocol (LACP) Junos resource + module + name: junos_lacp + namespace: "" + - description: LACP interfaces resource module + name: junos_lacp_interfaces + namespace: "" + - description: Link Aggregation Juniper JUNOS resource module + name: junos_lag_interfaces + namespace: "" + - description: LLDP resource module + name: junos_lldp_global + namespace: "" + - description: LLDP interfaces resource module + name: junos_lldp_interfaces + namespace: "" + - description: Manage logging on network devices + name: junos_logging + namespace: "" + - description: Configures the Junos Netconf system service + name: junos_netconf + namespace: "" + - description: OSPFv2 resource module + name: junos_ospfv2 + namespace: "" + - description: Installs packages on remote devices running Junos + name: junos_package + namespace: "" + - description: Tests reachability using ping from devices running Juniper JUNOS + name: junos_ping + namespace: "" + - description: Runs an arbitrary RPC over NetConf on an Juniper JUNOS device + name: junos_rpc + namespace: "" + - description: Transfer files from or to remote devices running Junos + name: junos_scp + namespace: "" + - description: Static routes resource module + name: junos_static_routes + namespace: "" + - description: Manage the system attributes on Juniper JUNOS devices + name: junos_system + namespace: "" + - description: Manage local user accounts on Juniper JUNOS devices + name: junos_user + namespace: "" + - description: VLANs resource module + name: junos_vlans + namespace: "" + - description: Manage the VRF definitions on Juniper JUNOS devices + name: junos_vrf + namespace: "" + plugins: + cliconf: + - description: Use junos cliconf to run command on Juniper Junos OS platform + name: junos + namespace: null + netconf: + - description: + Use junos netconf plugin to run netconf commands on Juniper JUNOS + platform + name: junos + namespace: null + release_date: "2020-06-23" + 1.0.1: + changes: + bugfixes: + - Make `src`, `backup` and `backup_options` in junos_config work when module + alias is used (https://github.com/ansible-collections/junipernetworks.junos/pull/83). + - Update docs after sanity fixes to modules. + fragments: + - fix_config_module_src_backup.yaml + - update_docs.yaml + release_date: "2020-08-07" + 1.1.0: + changes: + bugfixes: + - set_config called only when state is not gathered so that gathered opeartion + works fine (https://github.com/ansible-collections/junipernetworks.junos/issues/89). + - set_config called only when state is not gathered so that gathered opeartion + works fine (https://github.com/ansible-collections/junipernetworks.junos/issues/93). + - set_config called only when state is not gathered so that gathered opeartion + works fine for l2_interfaces resource module (https://github.com/ansible-collections/junipernetworks.junos/issues/91). + minor_changes: + - Gathered state operation enabled, Parsed and rendered state operations implemented + for junos_lacp. + - Gathered state operation enabled, Parsed and rendered state operations implemented + for junos_lldp_global. + - Gathered state operation enabled, Parsed and rendered state operations implemented + for junos_lldp_interfaces. + - Gathered state operation enabled, Parsed and rendered state operations implemented + for ospfv2, acl_interfaces, vlans and static_routes RM. + - Gathered state operation enabled. Parsed and rendered state operations implemented. + - Gathered state operation enabledand Parsed and rendered state operations implemented. + fragments: + - 89_gathered_opr_fix_junos_interfaces.yaml + - 91_gathered_opr_fix_junos_l2interfaces.yaml + - 93_gathered_opr_fix_junos_l3_interfaces.yaml + - junos_rm_state_opr_updated.yaml + - lacp_global_state_opr_updated.yaml + - lacp_interfaces_state_opr_updated.yaml + - lag_interfaces_state_opr_updated.yaml + - lldp_global_state_opr_updated.yaml + - lldp_interfaces_state_opr_added.yaml + release_date: "2020-08-31" + 1.1.1: + changes: + minor_changes: + - Use FQCN to M() references in modules documentation (https://github.com/ansible-collections/junipernetworks.junos/pull/79) + fragments: + - 79-Use-FQCN-to-M-references + release_date: "2020-10-01" + 1.2.0: + changes: + minor_changes: + - Add ospfv3 resource module. + fragments: + - add_junos_ospfv3.yaml + modules: + - description: OSPFv3 resource module + name: junos_ospfv3 + namespace: "" + release_date: "2020-10-30" + 1.2.1: + changes: + bugfixes: + - Add version key to galaxy.yaml to work around ansible-galaxy bug + - Updating unit tests for resource modules (https://github.com/ansible-collections/junipernetworks.junos/pull/127) + - allowing partial config filter for junos commands (https://github.com/ansible-collections/junipernetworks.junos/issues/112) + - checking for units and family attributes in conf dictionary (https://github.com/ansible-collections/junipernetworks.junos/issues/121) + fragments: + - 112_partial_config_fix.yaml + - 121_error_with_junos_acl_interfaces_facts.yaml + - galaxy-version.yaml + - unit_tests_updates.yaml + release_date: "2020-11-26" + 1.3.0: + changes: + bugfixes: + - changing prefix list type to list and correcting facts gathering (https://github.com/ansible-collections/junipernetworks.junos/issues/131) + - constructing the facts based on the addresses per unit (https://github.com/ansible-collections/junipernetworks.junos/issues/111) + - release version added updated to 1.3.0 for junos_ospf_interfaces and junos_bgp_global + module + minor_changes: + - Add junos bgp global resource module. + - Add ospf interfaces resource module. + fragments: + - junos_acl_prefix_list_fix.yaml + - junos_bgp_global_module.yaml + - junos_l3_interfaces_unit_fix.yaml + - junos_ospf_interfaces.yaml + - junos_version_added_updated.yaml + modules: + - description: Manages BGP Global configuration on devices running Juniper JUNOS. + name: junos_bgp_global + namespace: "" + - description: OSPF Interfaces Resource Module. + name: junos_ospf_interfaces + namespace: "" + release_date: "2021-01-28" + 2.0.0: + changes: + major_changes: + - Please refer to ansible.netcommon `changelog `_ + for more details. + - Requires ansible.netcommon v2.0.0+ to support `ansible_network_single_user_mode` + and `ansible_network_import_modules`. + minor_changes: + - Add junos_bgp_address_family resource module. + - Add support for autonomous-system routing-options for bgp global and updating + tests and documentation. + - Add support for bgp group and neighbors in bgp_global resource module. + - Add support for configuration caching (single_user_mode). + - Re-use device_info dictionary in cliconf. + fragments: + - 156-remove_tests_sanity_requirements.yml + - add_bgp_address_family.yaml + - asn_handling_doc_updates.yaml + - fix_junos_sanity.yaml + - implementing_group_and_neighbor.yaml + - single_user_mode.yaml + modules: + - description: Manage BGP Address Family attributes of interfaces on Junos devices. + name: junos_bgp_address_family + namespace: "" + release_date: "2021-02-25" + 2.0.1: + changes: + minor_changes: + - Add support df_bit and size option for junos_ping (https://github.com/ansible-collections/junipernetworks.junos/pull/136). + fragments: + - int-test-fix.yaml + - junos_ping_df_rapid.yaml + - remove-check_required.yaml + release_date: "2021-03-29" + 2.1.0: + changes: + minor_changes: + - Add junos_routing_instances Resource Module. + - Add support for available_network_resources key, which allows to fetch the + available resources for a platform (https://github.com/ansible-collections/junipernetworks.junos/issues/160). + - Replace unsupported parameter `vlan-id` in junipernetworks.junos.junos_vlans + module with `vlan_id` + security_fixes: + - Mask values of sensitive keys in module result(https://github.com/ansible-collections/junipernetworks.junos/issues/165). + fragments: + - 117_junos_routing_instances_resource_module.yaml + - ansible_networl_resources_facts.yaml + - junos_vlans.yaml + - no_log_sanity_fixes.yaml + modules: + - description: Manage routing instances on Junos devices. + name: junos_routing_instances + namespace: "" + release_date: "2021-04-28" + 2.10.0: + changes: + minor_changes: + - Added junos_security_policies module. + - Added junos_security_policies_global module. + - Added junos_security_zones module. + fragments: + - black_fix.yml + - fix_sanity_list.yml + - junos_security_policies_global_module.yaml + - junos_security_policies_resource_module.yaml + - junos_security_zones_module.yml + modules: + - description: Create and manage security policies on Juniper JUNOS devices + name: junos_security_policies + namespace: "" + - description: Manage global security policy settings on Juniper JUNOS devices + name: junos_security_policies_global + namespace: "" + - description: Manage security zones on Juniper JUNOS devices + name: junos_security_zones + namespace: "" + release_date: "2022-03-29" + 2.2.0: + changes: + minor_changes: + - Change src element from str to path for junos_scp. + - Improve junos_bgp_address_family unit test coverage. + fragments: + - change_junos_scp_src_element.yaml + - changelog_doc_path_update.yaml + - improve_bgp_address_family_test_coverage.yaml + - update_author_bgp_global.yaml + release_date: "2021-05-18" + 2.3.0: + changes: + minor_changes: + - Add junos_prefix_lists Resource Module. + fragments: + - 118_junos_prefix_lists_resource_module.yaml + - update_readme.yml + release_date: "2021-06-22" + 2.4.0: + changes: + bugfixes: + - fix lacp force-up without port-priority in junos_lacp_interfaces + - fix netconf test-case for lacp revert + - junos_acls failed to parse acl when multiple addresses defined within a single + term (https://github.com/ansible-collections/junipernetworks.junos/issues/190) + deprecated_features: + - The junos_logging module has been deprecated in favor of the new junos_logging_global + resource module and will be removed in a release after '2023-08-01'. + minor_changes: + - Add junos_logging_global Resource Module. + - Add support for backup_format option in junos_config + - support l3_interface in junos vlans + fragments: + - 109_support_l3_interface_in_vlans.yaml + - deprecate_junos_logging.yaml + - fix_no_port_priority.yml + - junos_acl_multi_address_port_acls.yaml + - junos_config_backup_format.yaml + - junos_logging_global_module.yaml + modules: + - description: Manage logging configuration on Junos devices. + name: junos_logging_global + namespace: "" + release_date: "2021-07-28" + 2.5.0: + changes: + deprecated_features: + - Deprecated router_id from ospfv3 resource module. + minor_changes: + - Improve junos ospfv2 integration and unit tests coverage and router id assignment + check implemented. + - Improve junos vlans integration and unit tests coverage and facts gathering + logic modification. + fragments: + - deprecate_ospfv3_router_id.yaml + - ospfv2_test_coverage_improvement.yaml + - vlans_tests_coverage_improvement.yaml + release_date: "2021-08-30" + 2.6.0: + changes: + deprecated_features: + - Deprecated router_id from ospfv2 resource module. + minor_changes: + - Add junos_ntp_global resource module. + fragments: + - deprecate_ospfv2_router_id.yaml + - junos_ntp_global.yaml + - rename_key_to_key_id_junos_ntp_global.yaml + - set_allow_duplicates.yaml + modules: + - description: Manage NTP configuration on Junos devices. + name: junos_ntp_global + namespace: "" + release_date: "2021-09-24" + 2.7.0: + changes: + doc_changes: + - Add note for router_id deprecation from ospf-interfaces resource module. + - make sure router_id facts and config operation works fine for ospfv2 and ospfv3 + RM + fragments: + - 0-copy_ignore_txt.yml + - junos_ospf_router_if_fix.yaml + release_date: "2021-11-25" + 2.7.1: + changes: + bugfixes: + - Fix ospf router_id overlap issue. + fragments: + - fix_ospf_facts_issue.yaml + release_date: "2021-12-07" + 2.8.0: + changes: + deprecated_features: + - "'router_id' options is deprecated from junos_ospf_interfaces, junos_ospfv2 + and junos_ospfv3 resuorce module." + minor_changes: + - Add junos_routing_options resource module. + - Add junos_snmp_server resource module. + fragments: + - junos_routing_options_resource_module.yaml + - junos_snmp_server_module.yaml + modules: + - description: Manage routing-options configuration on Junos devices. + name: junos_routing_options + namespace: "" + release_date: "2021-12-09" + 2.9.0: + changes: + bugfixes: + - Fix junos_command output when empty config response is received for show commands + (https://github.com/ansible-collections/junipernetworks.junos/issues/249). + minor_changes: + - Add junos_hostname resource module. + - Allow interfaces resource module to configure and gather logical interface + description. + fragments: + - 249_fix_junos_command_output.yaml + - implement_intf_unit_description.yaml + - junos_hostname_module.yaml + modules: + - description: Manage Hostname server configuration on Junos devices. + name: junos_hostname + namespace: "" + - description: Manage SNMP server configuration on Junos devices. + name: junos_snmp_server + namespace: "" + release_date: "2022-02-01" + 3.0.0: + changes: + bugfixes: + - Fix junos_acl fact gathering when only destination port defined (https://github.com/ansible-collections/junipernetworks.junos/issues/268). + major_changes: + - Minimum required ansible.netcommon version is 2.5.1. + - Updated base plugin references to ansible.netcommon. + - "`junos_facts` - change default gather_subset to `min` from `!config`." + fragments: + - 0-ignore.yml + - add_fqcn_ansible_connection.yaml + - fix_acl_facts_gathering_issue.yml + - junos_facts.yaml + - netcommon_ref_update.yaml + - runtime_fix.yml + release_date: "2022-04-27" + 3.0.1: + changes: + bugfixes: + - Fix incorrect param pass to to_text. + fragments: + - 225_fix_to_string.yaml + - 308.yaml + - enable_unit_and_sanity_using_github_action.yaml + release_date: "2022-06-03" + 3.1.0: + changes: + bugfixes: + - fixes the nighbors list overwrite issue. + minor_changes: + - Add mac-vrf instance type. + fragments: + - add_mac_vrf_type.yaml + - read_neighbors_list_fix.yaml + release_date: "2022-06-28" + 4.0.0: + changes: + major_changes: + - "Use of connection: local and the provider option are no longer valid on any + modules in this collection." + removed_features: + - Remove following deprecated Junos Modules. + - junos_interface + - junos_l2_interface + - junos_l3_interface + - junos_linkagg + - junos_lldp + - junos_lldp_interface + - junos_static_route + - junos_vlan + fragments: + - ignores-2.15.yaml + - net_remove.yaml + - remove_deprecated_modules.yaml + - remove_provider.yaml + - sanity.yaml + release_date: "2022-10-12" + 4.1.0: + changes: + minor_changes: + - Implement file_size as string. + - Used xmltodict to gather the sub-module chassis list and return it as a dictionary. + fragments: + - junos_facts_chassis_sub_module.yaml + - logging_global_size.yaml + - update_trivial_changes.yaml + release_date: "2022-11-30" + 5.0.0: + changes: + bugfixes: + - enable provider support for junos_scp and junos_package. + - fix diff to result when prepared diff exists. + - fix junos_security_zones facts gathering when we have single interface configured. + - revert diff mode to default. + major_changes: + - change gathered key from junos_acls to acls + fragments: + - bug_fix_for_security_zones_facts.yaml + - fix_trivial_issues.yaml + - junos_acls_gathered_key_fix.yaml + - prepared_diff_fix.yaml + - provider_support_for_legacy_modules.yaml + - reboot_task_tag.yaml + - rollback_diffmode.yaml + - update_bgp_global_fqcn.yaml + - update_reboot_timer.yaml + release_date: "2023-02-28" + 5.1.0: + changes: + bugfixes: + - Fix enabled attribute implementation. + - Fix lldp_global_assertion. + - Fix sanity issues. + - Fix the snmp view and traps configuration. + - fix the implementation of disabling interface. + - module should return with failure when rollback is 0 and device is not reachable. + doc_changes: + - Update bgp_address_family docs with examples. + - Update bgp_global docs with examples. + - junos_interfaces - Updated documentation with examples and task output. + - junos_static_routes - add task output to module documentation examples. (https://github.com/ansible-collections/junipernetworks.junos/pull/402). + minor_changes: + - Adding unlink option to junos package installation. + fragments: + - boolean_normalization.yaml + - ci_codecov.yaml + - codecov_fix.yml + - fix_docs_static_route.yaml + - fix_downstream.yaml + - fix_downstream_testing_issues.yaml + - fix_enabling.yaml + - fix_lldp_global_assertion.yaml + - fix_snmp_traps_and_view.yaml + - gha_workflow_fix.yml + - junos_cofig_rollback_fix.yaml + - lldp_global_test_update.yaml + - package_unlink.yaml + - update_bgp_address_family_docs.yaml + - update_bgp_global_docs.yaml + - update_inft_docs.yaml + - update_timeout.yaml + release_date: "2023-04-28" + 5.2.0: + changes: + deprecated_features: + - "`junos_ospfv2` - add deprecate warning for area_range." + - add deprecate warning for junos_acl_interfaces key for junos facts results. + doc_changes: + - Update examples for junos_ospfv3 + minor_changes: + - "`junos_ospfv2` - Fix the authentication config when password is configured" + - "`junos_ospfv2` - Rename key ospf to ospfv2 in facts." + - "`junos_ospfv2` - add area_ranges attribute which supports list of dict attributes." + - "`junos_ospfv2` - add attributes `allow_route_leaking`, `stub_network` and + `as-external` to overload dict." + - "`junos_ospfv2` - add attributes `no_ignore_out_externals` to spf_options + dict." + - "`junos_ospfv2` - fix to gather reference_bandwidth and rfc1583compatibility." + - add acl_interfaces key for junos_facts output. + fragments: + - add_gha_periodic.yaml + - deprecate_junos_acl_interafaces_facts_key.yaml + - gha_release.yml + - junos_ospfv2_fixes.yaml + - junos_ospfv3_health_check.yaml + - lint.yaml + release_date: "2023-07-05" + 5.3.0: + changes: + bugfixes: + - fix `no_advertise_adjacency_segment` config implementation. + - fix `no_eligible_backup` config implementation. + - fix `no_eligible_remote_backup` config implementation. + - fix `no_interface_state_traps` config implementation. + - fix `no_neighbor_down_notification` config implementation. + - fix `node_link_protection` implementation. + - fix md5 authentication which allows list of keys to be configured. + minor_changes: + - add overridden state opperation support. + fragments: + - bgp_global_tests_fix.yaml + - codecov_pr.yml + - overridden_support.yaml + release_date: "2023-09-06" + 5.3.1: + changes: + bugfixes: + - fix to gather l2_interfaces facts with default port-mode access. + doc_changes: + - Improve docs of prefix-lists RM. + - ios_l2_interfaces - Fixed module documentation and examples. + - ios_l3_interfaces - Fixed module documentation and examples. + fragments: + - default_mode_l2_interfaces.yaml + - fix_prefix_lists_docs.yaml + - lint_fixtures.yaml + - sanity_job_fix.yaml + - update_l2_3_docs.yaml + release_date: "2023-11-27" + 6.0.0: + changes: + major_changes: + - Bumping `requires_ansible` to `>=2.14.0`, since previous ansible-core versions + are EoL now. + release_summary: + Starting from this release, the minimum `ansible-core` version + this collection requires is `2.14.0`. That last known version compatible with + ansible-core<2.14 is `v5.3.1`. + fragments: + - update_l2_interfaces_tests.yaml + release_date: "2023-11-30" + 6.0.1: + changes: + bugfixes: + - Prevents module_defaults from were being incorrectly applied to the platform + action, instead of the concerned module. + fragments: + - module_defaults.yaml + - trivial_lint.yaml + release_date: "2024-01-31" + 6.0.2: + changes: + bugfixes: + - acls + - initialize facts dictionary with empty containers for respective resources + mentioned below + - lldp_global + - lldp_interfaces + - logging_global + - ntp_global + - ospf_interfaces + - ospfv2 + - ospfv3 + - prefix_lists + - routing_instances + - routing_options + - security_policies + - security_policies_global + - security_zones + - snmp_server + - static_routes + - vlans + doc_changes: + - Remove the part of the description which incorrectly describes the behavior + and type of confirm attribute. + - Update example performing `confirm_commit`. + - Update with more examples using the `confirm` option to set a timer. + fragments: + - empty_facts.yaml + - update_junos_config_docs.yaml + release_date: "2024-03-06" + 7.0.0: + changes: + bugfixes: + - Fix the empty facts list placement + major_changes: + - This release removes previously deprecated modules from this collection. Please + refer to the **Removed Features** section for details. + removed_features: + - Remove deprected junos_logging module which is replaced by junos_logging_global + resource module. + fragments: + - fix_upstream_tetst.yaml + - remove_deprecated.yaml + - trivial_tests_updates.yaml + release_date: "2024-03-27" + 8.0.0: + changes: + major_changes: + - Update the netcommon base version 6.1.0 to support cli_restore plugin. + minor_changes: + - Add support for cli_restore functionality. + - Please refer the PR to know more about core changes (https://github.com/ansible-collections/ansible.netcommon/pull/618). + - cli_restore module is part of netcommon. + fragments: + - 218sanity.yml + - add_restore_implementation.yaml + release_date: "2024-04-13" + 9.0.0: + changes: + major_changes: + - Bumping `requires_ansible` to `>=2.15.0`, since previous ansible-core versions + are EoL now. + release_summary: + Starting from this release, the minimum `ansible-core` version + this collection requires is `2.15.0`. The last known version compatible with + ansible-core<2.15 is v8.0.0. + fragments: + - bump_to_215.yaml + release_date: "2024-06-10" + 9.1.0: + changes: + bugfixes: + - Fix the lag_interfaces facts for gigether supported model. + minor_changes: + - Add implementation to gather ether-channels for gig-ether-options. + - Added support for virtual-switch instances. + - Based on ether-option-type create supported commands for config module. + - Implemented bridge-domains configuration management for routing instances. + - Implemented support for setting the Maximum Transmission Unit (MTU) in Layer + 3 (L3) Internet Protocol (IP) interfaces. + - Tested successfully on Junos MX204. + fragments: + - add_support_for_gig_ether_lag.yaml + - fix_lad_interfaces.yaml + - implement_bridge_domains.yaml + - support_l3_mtu.yaml + release_date: "2024-08-05" diff --git a/ansible_collections/junipernetworks/junos/changelogs/config.yaml b/ansible_collections/junipernetworks/junos/changelogs/config.yaml new file mode 100644 index 00000000..25f39e7a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/changelogs/config.yaml @@ -0,0 +1,32 @@ +changelog_filename_template: ../CHANGELOG.rst +changelog_filename_version_depth: 0 +changes_file: changelog.yaml +changes_format: combined +keep_fragments: false +mention_ancestor: true +new_plugins_after_name: removed_features +notesdir: fragments +prelude_section_name: release_summary +prelude_section_title: Release Summary +flatmap: true +sections: + - - major_changes + - Major Changes + - - minor_changes + - Minor Changes + - - breaking_changes + - Breaking Changes / Porting Guide + - - deprecated_features + - Deprecated Features + - - removed_features + - Removed Features (previously deprecated) + - - security_fixes + - Security Fixes + - - bugfixes + - Bugfixes + - - known_issues + - Known Issues + - - doc_changes + - Documentation Changes +title: Junipernetworks Junos Collection +trivial_section_name: trivial diff --git a/ansible_collections/junipernetworks/junos/changelogs/fragments/.keep b/ansible_collections/junipernetworks/junos/changelogs/fragments/.keep new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/junipernetworks/junos/changelogs/fragments/0-readme.yml b/ansible_collections/junipernetworks/junos/changelogs/fragments/0-readme.yml new file mode 100644 index 00000000..6ae0307d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/changelogs/fragments/0-readme.yml @@ -0,0 +1,3 @@ +--- +trivial: + - README.md - Add Communication section with Forum information. diff --git a/ansible_collections/junipernetworks/junos/changelogs/fragments/adds_support.yaml b/ansible_collections/junipernetworks/junos/changelogs/fragments/adds_support.yaml new file mode 100644 index 00000000..06f93f76 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/changelogs/fragments/adds_support.yaml @@ -0,0 +1,3 @@ +--- +doc_changes: + - Includes a new support related section in the README. diff --git a/ansible_collections/junipernetworks/junos/changelogs/fragments/ignore_219.yaml b/ansible_collections/junipernetworks/junos/changelogs/fragments/ignore_219.yaml new file mode 100644 index 00000000..d051c421 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/changelogs/fragments/ignore_219.yaml @@ -0,0 +1,3 @@ +--- +trivial: + - Add ignore-2.19.txt. diff --git a/ansible_collections/junipernetworks/junos/changelogs/fragments/libssh.yaml b/ansible_collections/junipernetworks/junos/changelogs/fragments/libssh.yaml new file mode 100644 index 00000000..5a52afbd --- /dev/null +++ b/ansible_collections/junipernetworks/junos/changelogs/fragments/libssh.yaml @@ -0,0 +1,3 @@ +--- +trivial: + - junos_net_put - Add tests for net_put module using scp & sftp protocol diff --git a/ansible_collections/junipernetworks/junos/codecov.yml b/ansible_collections/junipernetworks/junos/codecov.yml new file mode 100644 index 00000000..c77c91a9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/codecov.yml @@ -0,0 +1,15 @@ +--- +codecov: + require_ci_to_pass: true +comment: + layout: " diff, flags, files" + behavior: default + require_changes: false + require_base: false + require_head: true +coverage: + status: + patch: false + project: + default: + threshold: 0.3% diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_acl_interfaces_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_acl_interfaces_module.rst new file mode 100644 index 00000000..e5e04b21 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_acl_interfaces_module.rst @@ -0,0 +1,508 @@ +.. _junipernetworks.junos.junos_acl_interfaces_module: + + +****************************************** +junipernetworks.junos.junos_acl_interfaces +****************************************** + +**ACL interfaces resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages adding and removing Access Control Lists (ACLs) from interfaces on devices running Juniper JUNOS. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
A dictionary of ACL options for interfaces.
+
+
+ access_groups + +
+ list + / elements=dictionary +
+
+ +
Specifies ACLs attached to the interface.
+
+
+ acls + +
+ list + / elements=dictionary +
+
+ +
Specifies the ACLs for the provided AFI.
+
+
+ direction + +
+ string +
+
+
    Choices: +
  • in
  • +
  • out
  • +
+
+
Specifies the direction of packets that the ACL will be applied on.
+
+
+ name + +
+ string +
+
+ +
Specifies the name of the IPv4/IPv4 ACL for the interface.
+
+
+ afi + +
+ string +
+
+
    Choices: +
  • ipv4
  • +
  • ipv6
  • +
+
+
Specifies the AFI for the ACL(s) to be configured on this interface.
+
+
+ name + +
+ string +
+
+ +
Name/Identifier for the interface.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show interfaces.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • rendered
  • +
  • parsed
  • +
+
+
The state the configuration should be left in.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using deleted + + # Before state: + # ------------- + # + # admin# show interfaces + # ge-1/0/0 { + # description "L3 interface with filter"; + # unit 0 { + # family inet { + # filter { + # input inbound_acl; + # output outbound_acl; + # } + # address 100.64.0.1/10; + # address 100.64.0.2/10; + # } + # family inet6; + # } + + - name: Delete JUNOS L3 interface filter + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: inbound_acl + direction: in + - name: outbound_acl + direction: out + state: deleted + + # After state: + # ------------- + # + # admin# show interfaces + # ge-1/0/0 { + # description "L3 interface with filter"; + # unit 0 { + # family inet { + # address 100.64.0.1/10; + # address 100.64.0.2/10; + # } + # family inet6; + # } + + + # Using merged + + # Before state: + # ------------- + # + # admin# show interfaces + # ge-1/0/0 { + # description "L3 interface without filter"; + # unit 0 { + # family inet { + # address 100.64.0.1/10; + # address 100.64.0.2/10; + # } + # family inet6; + # } + + - name: Merge JUNOS L3 interface filter + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: inbound_acl + direction: in + - name: outbound_acl + direction: out + state: merged + + # After state: + # ------------- + # + # admin# show interfaces + # ge-1/0/0 { + # description "L3 interface with filter"; + # unit 0 { + # family inet { + # filter { + # input inbound_acl; + # output outbound_acl; + # } + # address 100.64.0.1/10; + # address 100.64.0.2/10; + # } + # family inet6; + # } + + + # Using overridden + + # Before state: + # ------------- + # + # admin# show interfaces + # ge-1/0/0 { + # description "L3 interface without filter"; + # unit 0 { + # family inet { + # filter { + # input foo_acl; + # } + # address 100.64.0.1/10; + # address 100.64.0.2/10; + # } + # family inet6; + # } + + - name: Override JUNOS L3 interface filter + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: inbound_acl + direction: in + - name: outbound_acl + direction: out + state: overridden + + # After state: + # ------------- + # + # admin# show interfaces + # ge-1/0/0 { + # description "L3 interface with filter"; + # unit 0 { + # family inet { + # filter { + # input inbound_acl; + # output outbound_acl; + # } + # address 100.64.0.1/10; + # address 100.64.0.2/10; + # } + # family inet6; + # } + + + # Using replaced + + # Before state: + # ------------- + # + # admin# show interfaces + # ge-1/0/0 { + # description "L3 interface without filter"; + # unit 0 { + # family inet { + # filter { + # input foo_acl; + # output outbound_acl; + # } + # address 100.64.0.1/10; + # address 100.64.0.2/10; + # } + # family inet6; + # } + + - name: Replace JUNOS L3 interface filter + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: inbound_acl + direction: in + state: replaced + + # After state: + # ------------- + # + # admin# show interfaces + # ge-1/0/0 { + # description "L3 interface with filter"; + # unit 0 { + # family inet { + # filter { + # input inbound_acl; + # output outbound_acl; + # } + # address 100.64.0.1/10; + # address 100.64.0.2/10; + # } + # family inet6; + # } + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['command 1', 'command 2', 'command 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Daniel Mellado (@dmellado) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_acls_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_acls_module.rst new file mode 100644 index 00000000..ea8584d2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_acls_module.rst @@ -0,0 +1,1277 @@ +.. _junipernetworks.junos.junos_acls_module: + + +******************************** +junipernetworks.junos.junos_acls +******************************** + +**ACLs resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module provides declarative management of acls/filters on Juniper JUNOS devices + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
A dictionary of acls options
+
+
+ acls + +
+ list + / elements=dictionary +
+
+ +
List of Access Control Lists (ACLs).
+
+
+ aces + +
+ list + / elements=dictionary +
+
+ +
List of Access Control Entries (ACEs) for this Access Control List (ACL).
+
+
+ destination + +
+ dictionary +
+
+ +
Specifies the destination for the filter
+
+
+ address + +
+ raw +
+
+ +
Match IP destination address
+
+
+ port_protocol + +
+ dictionary +
+
+ +
Specify the destination port or protocol.
+
+
+ eq + +
+ string +
+
+ +
Match only packets on a given port number.
+
+
+ range + +
+ dictionary +
+
+ +
Match only packets in the range of port numbers
+
+
+ end + +
+ integer +
+
+ +
Specify the end of the port range
+
+
+ start + +
+ integer +
+
+ +
Specify the start of the port range
+
+
+ prefix_list + +
+ list + / elements=dictionary +
+
+ +
Match IP destination prefixes in named list
+
+
+ name + +
+ string +
+
+ +
Name of the list
+
+
+ grant + +
+ string +
+
+
    Choices: +
  • permit
  • +
  • deny
  • +
+
+
Action to take after matching condition (allow, discard/reject)
+
+
+ name + +
+ string + / required +
+
+ +
Filter term name
+
+
+ protocol + +
+ string +
+
+ +
Specify the protocol to match.
+
Refer to vendor documentation for valid values.
+
+
+ protocol_options + +
+ dictionary +
+
+ +
All possible suboptions for the protocol chosen.
+
+
+ icmp + +
+ dictionary +
+
+ +
ICMP protocol options.
+
+
+ dod_host_prohibited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Host prohibited
+
+
+ dod_net_prohibited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Net prohibited
+
+
+ echo + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Echo (ping)
+
+
+ echo_reply + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Echo reply
+
+
+ host_redirect + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Host redirect
+
+
+ host_tos_redirect + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Host redirect for TOS
+
+
+ host_tos_unreachable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Host unreachable for TOS
+
+
+ host_unknown + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Host unknown
+
+
+ host_unreachable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Host unreachable
+
+
+ net_redirect + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Network redirect
+
+
+ net_tos_redirect + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Net redirect for TOS
+
+
+ network_unknown + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Network unknown
+
+
+ port_unreachable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Port unreachable
+
+
+ protocol_unreachable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Protocol unreachable
+
+
+ reassembly_timeout + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Reassembly timeout
+
+
+ redirect + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
All redirects
+
+
+ router_advertisement + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Router discovery advertisements
+
+
+ router_solicitation + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Router discovery solicitations
+
+
+ source_route_failed + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Source route failed
+
+
+ time_exceeded + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
All time exceeded.
+
+
+ ttl_exceeded + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
TTL exceeded
+
+
+ source + +
+ dictionary +
+
+ +
Specifies the source for the filter
+
+
+ address + +
+ raw +
+
+ +
IP source address to use for the filter
+
+
+ port_protocol + +
+ dictionary +
+
+ +
Specify the source port or protocol.
+
+
+ eq + +
+ string +
+
+ +
Match only packets on a given port number.
+
+
+ range + +
+ dictionary +
+
+ +
Match only packets in the range of port numbers
+
+
+ end + +
+ integer +
+
+ +
Specify the end of the port range
+
+
+ start + +
+ integer +
+
+ +
Specify the start of the port range
+
+
+ prefix_list + +
+ list + / elements=dictionary +
+
+ +
IP source prefix list to use for the filter
+
+
+ name + +
+ string +
+
+ +
Name of the list
+
+
+ name + +
+ string + / required +
+
+ +
Name to use for the acl filter
+
+
+ afi + +
+ string + / required +
+
+
    Choices: +
  • ipv4
  • +
  • ipv6
  • +
+
+
Protocol family to use by the acl filter
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show firewall.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • rendered
  • +
  • parsed
  • +
+
+
The state the configuration should be left in
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed + - This module works with connection ``netconf`` + - See `the Junos OS Platform Options `_ + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + + # Before state: + # ------------- + # + # admin# show firewall + + - name: Merge JUNOS acl + junipernetworks.junos.junos_acls: + config: + - afi: ipv4 + acls: + - name: allow_ssh_acl + aces: + - name: ssh_rule + source: + port_protocol: + eq: ssh + protocol: tcp + state: merged + + # After state: + # ------------- + # admin# show firewall + # family inet { + # filter allow_ssh_acl { + # term ssh_rule { + # from { + # protocol tcp; + # source-port ssh; + # } + # } + # } + # } + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ list +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ list +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['command 1', 'command 2', 'command 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Daniel Mellado (@dmellado) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_banner_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_banner_module.rst new file mode 100644 index 00000000..83240b51 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_banner_module.rst @@ -0,0 +1,212 @@ +.. _junipernetworks.junos.junos_banner_module: + + +********************************** +junipernetworks.junos.junos_banner +********************************** + +**Manage multiline banners on Juniper JUNOS devices** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This will configure both login and motd banners on network devices. It allows playbooks to add or remote banner text from the active running configuration. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.5.2) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ active + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes ←
  • +
+
+
Specifies whether or not the configuration is active or deactivated
+
+
+ banner + +
+ string + / required +
+
+
    Choices: +
  • login
  • +
  • motd
  • +
+
+
Specifies which banner that should be configured on the remote device. Value login indicates system login message prior to authenticating, motd is login announcement after successful authentication.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • present ←
  • +
  • absent
  • +
+
+
Specifies whether or not the configuration is present in the current devices active running configuration.
+
+
+ text + +
+ string +
+
+ +
The banner text that should be present in the remote device running configuration. This argument accepts a multiline string, with no empty lines. Requires state=present.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. + - Recommended connection is ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - This module also works with ``local`` connections for legacy playbooks. + - For information on using CLI and netconf see the :ref:`Junos OS Platform Options guide ` + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` + - For more information on using Ansible to manage Juniper network devices see https://www.ansible.com/ansible-juniper. + + + +Examples +-------- + +.. code-block:: yaml + + - name: configure the login banner + junipernetworks.junos.junos_banner: + banner: login + text: | + this is my login banner + that contains a multiline + string + state: present + + - name: remove the motd banner + junipernetworks.junos.junos_banner: + banner: motd + state: absent + + - name: deactivate the motd banner + junipernetworks.junos.junos_banner: + banner: motd + state: present + active: false + + - name: activate the motd banner + junipernetworks.junos.junos_banner: + banner: motd + state: present + active: true + + - name: Configure banner from file + junipernetworks.junos.junos_banner: + banner: motd + text: "{{ lookup('file', './config_partial/raw_banner.cfg') }}" + state: present + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + +
KeyReturnedDescription
+
+ diff.prepared + +
+ string +
+
when configuration is changed and diff option is enabled. +
Configuration difference before and after applying change.
+
+
Sample:
+
[edit system login] + message "this is my login banner";
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ganesh Nalawade (@ganeshrn) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_bgp_address_family_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_bgp_address_family_module.rst new file mode 100644 index 00000000..d0915c0d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_bgp_address_family_module.rst @@ -0,0 +1,7712 @@ +.. _junipernetworks.junos.junos_bgp_address_family_module: + + +********************************************** +junipernetworks.junos.junos_bgp_address_family +********************************************** + +**Manage BGP Address Family attributes of interfaces on Junos devices.** + + +Version added: 1.3.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- Manage BGP Address Family attributes of interfaces on Junos network devices. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
The provided link BGP address family dictionary.
+
+
+ address_family + +
+ list + / elements=dictionary +
+
+ +
Enable address family and enter its config mode.
+
+
+ af_type + +
+ list + / elements=dictionary +
+
+ +
Address family type for ipv4.
+
+
+ accepted_prefix_limit + +
+ dictionary +
+
+ +
Specify limit for maximum number of prefixes accepted from a peer.
+
+
+ forever + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Idle the peer until the user intervenes.
+
+
+ idle_timeout + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set idle timeout node.
+
+
+ idle_timeout_value + +
+ integer +
+
+ +
Specify timeout before attempting to restart peer.
+
+
+ limit_threshold + +
+ integer +
+
+ +
Specify teardown percentage of prefix-limit to start warnings.
+
+
+ maximum + +
+ integer +
+
+ +
Specify maximum number of prefixes accepted from a peer.
+
+
+ teardown + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Clear peer connection on reaching limit.
+
+
+ add_path + +
+ dictionary +
+
+ +
Advertise multiple paths to peer.
+
+
+ receive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Receive multiple paths from peer.
+
+
+ send + +
+ dictionary +
+
+ +
Send multiple paths to peer.
+
+
+ include_backup_path + +
+ integer +
+
+ +
Specify number of backup paths to advertise.
+
+
+ multipath + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Include only multipath contributor routes.
+
+
+ path_count + +
+ integer + / required +
+
+ +
Include only multipath contributor routes.
+
+
+ path_selection_mode + +
+ dictionary +
+
+ +
Configure how to select add-path routes.
+
+
+ all_paths + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise all paths allowed by path count.
+
+
+ equal_cost_paths + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise equal cost paths.
+
+
+ prefix_policy + +
+ string +
+
+ +
Perform add-path only for prefixes that match policy.
+
+
+ aggregate_label + +
+ dictionary +
+
+ +
Aggregate labels of incoming routes with the same FEC.
+
+
+ community + +
+ string +
+
+ +
Community to identify the FEC of incoming routesC.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Aggregate labels of incoming routes with the same FEC
+
+
+ aigp + +
+ dictionary +
+
+ +
Allow sending and receiving of AIGP attribute.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Dn not allow sending and receiving of AIGP attribute.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set AIGP.
+
+
+ damping + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable route flap damping.
+
+
+ defer_initial_multipath_build + +
+ dictionary +
+
+ +
Defer initial multipath build until EOR is received.
+
+
+ maximum_delay + +
+ integer +
+
+ +
Max delay(sec) multipath build after peer is up.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set defer initial multipath build.
+
+
+ delay_route_advertisements + +
+ dictionary +
+
+ +
Delay route updates for this family until FIB-sync.
+
+
+ max_delay_route_age + +
+ integer +
+
+ +
Set max delay advertisement route age.
+
+
+ max_delay_routing_uptime + +
+ integer +
+
+ +
Set max delay advertisement route age.
+
+
+ min_delay_inbound_convergence + +
+ integer +
+
+ +
Set min delayadvertisement after source-peer sent all routes.
+
+
+ min_delay_routing_uptime + +
+ integer +
+
+ +
Set min delay advertisement route age.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set delay route advertisements.
+
+
+ entropy_label + +
+ dictionary +
+
+ +
Use entropy label for entropy label capable BGP LSPs.
+
+
+ import + +
+ string +
+
+ +
Policy to select BGP LSPs to use entropy label.
+
+
+ no_next_hop_validation + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't validate next hop field against route next hop.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set entropy-label attribute.
+
+
+ explicit_null + +
+ dictionary +
+
+ +
Advertise explicit null.
+
+
+ connected_only + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise explicit null only for connected routes.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set explicit-null attribute.
+
+
+ extended_nexthop + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable extended nexthop encoding.
+
+
+ extended_nexthop_color + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Resolve using extended color nexthop.
+
+
+ graceful_restart_forwarding_state_bit + +
+ string +
+
+
    Choices: +
  • from-fib
  • +
  • set
  • +
+
+
Specify BGP graceful restart options.
+
+
+ legacy_redirect_ip_action + +
+ dictionary +
+
+ +
Configure legacy redirect to IP support.
+
+
+ receive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Accept legacy encoded redirect-to-ip action attribute
+
+
+ send + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise Redirect action as legacy redirect attribute.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set the legacy-redirect-ip-action.
+
+
+ local_ipv4_address + +
+ string +
+
+ +
Specify local IPv4 address.
+
+
+ loops + +
+ integer +
+
+ +
Allow local AS in received AS paths.
+
+
+ no_install + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Dont install received routes in forwarding.
+
+
+ no_validate + +
+ string +
+
+ +
Bypass validation procedure for routes that match policy.
+
+
+ output_queue_priority_expedited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Expedited queue; highest priority.
+
+
+ output_queue_priority_priority + +
+ integer +
+
+ +
Output queue priority; higher is better.
+
+
+ per_group_label + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise prefixes with unique labels per group.
+
+
+ per_prefix_label + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allocate a unique label to each advertised prefix.
+
+
+ prefix_limit + +
+ dictionary +
+
+ +
Limit maximum number of prefixes from a peer.
+
+
+ forever + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Idle the peer until the user intervenes.
+
+
+ idle_timeout + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set idle timeout node.
+
+
+ idle_timeout_value + +
+ integer +
+
+ +
Specify timeout before attempting to restart peer.
+
+
+ limit_threshold + +
+ integer +
+
+ +
Percentage of prefix-limit to start warnings.
+
+
+ maximum + +
+ integer +
+
+ +
Specify maximum number of prefixes from a peer.
+
+
+ teardown + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Clear peer connection on reaching limit.
+
+
+ resolve_vpn + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Install received NLRI in inet.3 also.
+
+
+ rib + +
+ string +
+
+
    Choices: +
  • inet.3
  • +
+
+
Select table used by labeled unicast routes.
+
+
+ ribgroup_name + +
+ string +
+
+ +
Name of the routing table group.
+
+
+ route_refresh_priority_expedited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Expedited queue; highest priority.
+
+
+ route_refresh_priority_priority + +
+ integer +
+
+ +
Output queue priority; higher is better.
+
+
+ secondary_independent_resolution + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Resolve FLOW routes in VRF table independent of VPN FLOW route.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set NLRI.
+
+
+ strip_nexthop + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Strip the next-hop from the outgoing flow update.
+
+
+ topology + +
+ list + / elements=dictionary +
+
+ +
Multi topology routing tables.
+
+
+ community + +
+ list + / elements=string +
+
+ +
Community to identify multi topology routes.
+
+
+ name + +
+ string +
+
+ +
Specify topology name.
+
+
+ traffic_statistics + +
+ dictionary +
+
+ +
Collect statistics for BGP label-switched paths
+
+
+ file + +
+ dictionary +
+
+ +
Statistics file options.
+
+
+ filename + +
+ string +
+
+ +
Name of file in which to write trace information.
+
+
+ files + +
+ integer +
+
+ +
Maximum number of trace files.
+
+
+ no_world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ size + +
+ integer +
+
+ +
Maximum trace file size.
+
+
+ world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ interval + +
+ integer +
+
+ +
Time to collect statistics (seconds).
+
+
+ labeled_path + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable ingress labeled path statistics.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set traffic-statistics.
+
+
+ type + +
+ string +
+
+
    Choices: +
  • any
  • +
  • flow
  • +
  • labeled-unicast
  • +
  • multicast
  • +
  • segment-routing-te
  • +
  • unicast
  • +
  • signaling
  • +
  • auto-discovery-mspw
  • +
  • auto-discovery-only
  • +
+
+
Specify type of NLRI.
+
+
+ withdraw_priority_expedited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Expedited queue; highest priority.
+
+
+ withdraw_priority_priority + +
+ integer +
+
+ +
Output queue priority; higher is better.
+
+
+ afi + +
+ string +
+
+
    Choices: +
  • evpn
  • +
  • inet
  • +
  • inet-mdt
  • +
  • inet-mvpn
  • +
  • inet-vpn
  • +
  • inet6
  • +
  • inet6-mvpn
  • +
  • inet6-vpn
  • +
  • iso-vpn
  • +
  • l2vpn
  • +
  • route-target
  • +
  • traffic-engineering
  • +
+
+
address family.
+
+
+ groups + +
+ list + / elements=dictionary +
+
+ +
Specify address family config for groups.
+
+
+ address_family + +
+ list + / elements=dictionary +
+
+ +
Enable address family and enter its config mode.
+
+
+ af_type + +
+ list + / elements=dictionary +
+
+ +
Address family type for ipv4.
+
+
+ accepted_prefix_limit + +
+ dictionary +
+
+ +
Specify limit for maximum number of prefixes accepted from a peer.
+
+
+ forever + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Idle the peer until the user intervenes.
+
+
+ idle_timeout + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set idle timeout node.
+
+
+ idle_timeout_value + +
+ integer +
+
+ +
Specify timeout before attempting to restart peer.
+
+
+ limit_threshold + +
+ integer +
+
+ +
Specify teardown percentage of prefix-limit to start warnings.
+
+
+ maximum + +
+ integer +
+
+ +
Specify maximum number of prefixes accepted from a peer.
+
+
+ teardown + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Clear peer connection on reaching limit.
+
+
+ add_path + +
+ dictionary +
+
+ +
Advertise multiple paths to peer.
+
+
+ receive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Receive multiple paths from peer.
+
+
+ send + +
+ dictionary +
+
+ +
Send multiple paths to peer.
+
+
+ include_backup_path + +
+ integer +
+
+ +
Specify number of backup paths to advertise.
+
+
+ multipath + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Include only multipath contributor routes.
+
+
+ path_count + +
+ integer + / required +
+
+ +
Include only multipath contributor routes.
+
+
+ path_selection_mode + +
+ dictionary +
+
+ +
Configure how to select add-path routes.
+
+
+ all_paths + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise all paths allowed by path count.
+
+
+ equal_cost_paths + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise equal cost paths.
+
+
+ prefix_policy + +
+ string +
+
+ +
Perform add-path only for prefixes that match policy.
+
+
+ aggregate_label + +
+ dictionary +
+
+ +
Aggregate labels of incoming routes with the same FEC.
+
+
+ community + +
+ string +
+
+ +
Community to identify the FEC of incoming routesC.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Aggregate labels of incoming routes with the same FEC
+
+
+ aigp + +
+ dictionary +
+
+ +
Allow sending and receiving of AIGP attribute.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Dn not allow sending and receiving of AIGP attribute.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set AIGP.
+
+
+ damping + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable route flap damping.
+
+
+ defer_initial_multipath_build + +
+ dictionary +
+
+ +
Defer initial multipath build until EOR is received.
+
+
+ maximum_delay + +
+ integer +
+
+ +
Max delay(sec) multipath build after peer is up.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set defer initial multipath build.
+
+
+ delay_route_advertisements + +
+ dictionary +
+
+ +
Delay route updates for this family until FIB-sync.
+
+
+ max_delay_route_age + +
+ integer +
+
+ +
Set max delay advertisement route age.
+
+
+ max_delay_routing_uptime + +
+ integer +
+
+ +
Set max delay advertisement route age.
+
+
+ min_delay_inbound_convergence + +
+ integer +
+
+ +
Set min delayadvertisement after source-peer sent all routes.
+
+
+ min_delay_routing_uptime + +
+ integer +
+
+ +
Set min delay advertisement route age.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set delay route advertisements.
+
+
+ entropy_label + +
+ dictionary +
+
+ +
Use entropy label for entropy label capable BGP LSPs.
+
+
+ import + +
+ string +
+
+ +
Policy to select BGP LSPs to use entropy label.
+
+
+ no_next_hop_validation + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't validate next hop field against route next hop.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set entropy-label attribute.
+
+
+ explicit_null + +
+ dictionary +
+
+ +
Advertise explicit null.
+
+
+ connected_only + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise explicit null only for connected routes.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set explicit-null attribute.
+
+
+ extended_nexthop + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable extended nexthop encoding.
+
+
+ extended_nexthop_color + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Resolve using extended color nexthop.
+
+
+ graceful_restart_forwarding_state_bit + +
+ string +
+
+
    Choices: +
  • from-fib
  • +
  • set
  • +
+
+
Specify BGP graceful restart options.
+
+
+ legacy_redirect_ip_action + +
+ dictionary +
+
+ +
Configure legacy redirect to IP support.
+
+
+ receive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Accept legacy encoded redirect-to-ip action attribute
+
+
+ send + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise Redirect action as legacy redirect attribute.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set the legacy-redirect-ip-action.
+
+
+ local_ipv4_address + +
+ string +
+
+ +
Specify local IPv4 address.
+
+
+ loops + +
+ integer +
+
+ +
Allow local AS in received AS paths.
+
+
+ no_install + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Dont install received routes in forwarding.
+
+
+ no_validate + +
+ string +
+
+ +
Bypass validation procedure for routes that match policy.
+
+
+ output_queue_priority_expedited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Expedited queue; highest priority.
+
+
+ output_queue_priority_priority + +
+ integer +
+
+ +
Output queue priority; higher is better.
+
+
+ per_group_label + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise prefixes with unique labels per group.
+
+
+ per_prefix_label + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allocate a unique label to each advertised prefix.
+
+
+ prefix_limit + +
+ dictionary +
+
+ +
Limit maximum number of prefixes from a peer.
+
+
+ forever + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Idle the peer until the user intervenes.
+
+
+ idle_timeout + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set idle timeout node.
+
+
+ idle_timeout_value + +
+ integer +
+
+ +
Specify timeout before attempting to restart peer.
+
+
+ limit_threshold + +
+ integer +
+
+ +
Percentage of prefix-limit to start warnings.
+
+
+ maximum + +
+ integer +
+
+ +
Specify maximum number of prefixes from a peer.
+
+
+ teardown + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Clear peer connection on reaching limit.
+
+
+ resolve_vpn + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Install received NLRI in inet.3 also.
+
+
+ rib + +
+ string +
+
+
    Choices: +
  • inet.3
  • +
+
+
Select table used by labeled unicast routes.
+
+
+ ribgroup_name + +
+ string +
+
+ +
Name of the routing table group.
+
+
+ route_refresh_priority_expedited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Expedited queue; highest priority.
+
+
+ route_refresh_priority_priority + +
+ integer +
+
+ +
Output queue priority; higher is better.
+
+
+ secondary_independent_resolution + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Resolve FLOW routes in VRF table independent of VPN FLOW route.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set NLRI.
+
+
+ strip_nexthop + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Strip the next-hop from the outgoing flow update.
+
+
+ topology + +
+ list + / elements=dictionary +
+
+ +
Multi topology routing tables.
+
+
+ community + +
+ list + / elements=string +
+
+ +
Community to identify multi topology routes.
+
+
+ name + +
+ string +
+
+ +
Specify topology name.
+
+
+ traffic_statistics + +
+ dictionary +
+
+ +
Collect statistics for BGP label-switched paths
+
+
+ file + +
+ dictionary +
+
+ +
Statistics file options.
+
+
+ filename + +
+ string +
+
+ +
Name of file in which to write trace information.
+
+
+ files + +
+ integer +
+
+ +
Maximum number of trace files.
+
+
+ no_world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ size + +
+ integer +
+
+ +
Maximum trace file size.
+
+
+ world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ interval + +
+ integer +
+
+ +
Time to collect statistics (seconds).
+
+
+ labeled_path + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable ingress labeled path statistics.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set traffic-statistics.
+
+
+ type + +
+ string +
+
+
    Choices: +
  • any
  • +
  • flow
  • +
  • labeled-unicast
  • +
  • multicast
  • +
  • segment-routing-te
  • +
  • unicast
  • +
  • signaling
  • +
  • auto-discovery-mspw
  • +
  • auto-discovery-only
  • +
+
+
Specify type of NLRI.
+
+
+ withdraw_priority_expedited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Expedited queue; highest priority.
+
+
+ withdraw_priority_priority + +
+ integer +
+
+ +
Output queue priority; higher is better.
+
+
+ afi + +
+ string +
+
+
    Choices: +
  • evpn
  • +
  • inet
  • +
  • inet-mdt
  • +
  • inet-mvpn
  • +
  • inet-vpn
  • +
  • inet6
  • +
  • inet6-mvpn
  • +
  • inet6-vpn
  • +
  • iso-vpn
  • +
  • l2vpn
  • +
  • route-target
  • +
  • traffic-engineering
  • +
+
+
address family.
+
+
+ name + +
+ string +
+
+ +
Specify name of the group
+
+
+ neighbors + +
+ list + / elements=dictionary +
+
+ +
Specify address family config per neighbor.
+
+
+ address_family + +
+ list + / elements=dictionary +
+
+ +
Enable address family and enter its config mode.
+
+
+ af_type + +
+ list + / elements=dictionary +
+
+ +
Address family type for ipv4.
+
+
+ accepted_prefix_limit + +
+ dictionary +
+
+ +
Specify limit for maximum number of prefixes accepted from a peer.
+
+
+ forever + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Idle the peer until the user intervenes.
+
+
+ idle_timeout + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set idle timeout node.
+
+
+ idle_timeout_value + +
+ integer +
+
+ +
Specify timeout before attempting to restart peer.
+
+
+ limit_threshold + +
+ integer +
+
+ +
Specify teardown percentage of prefix-limit to start warnings.
+
+
+ maximum + +
+ integer +
+
+ +
Specify maximum number of prefixes accepted from a peer.
+
+
+ teardown + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Clear peer connection on reaching limit.
+
+
+ add_path + +
+ dictionary +
+
+ +
Advertise multiple paths to peer.
+
+
+ receive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Receive multiple paths from peer.
+
+
+ send + +
+ dictionary +
+
+ +
Send multiple paths to peer.
+
+
+ include_backup_path + +
+ integer +
+
+ +
Specify number of backup paths to advertise.
+
+
+ multipath + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Include only multipath contributor routes.
+
+
+ path_count + +
+ integer + / required +
+
+ +
Include only multipath contributor routes.
+
+
+ path_selection_mode + +
+ dictionary +
+
+ +
Configure how to select add-path routes.
+
+
+ all_paths + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise all paths allowed by path count.
+
+
+ equal_cost_paths + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise equal cost paths.
+
+
+ prefix_policy + +
+ string +
+
+ +
Perform add-path only for prefixes that match policy.
+
+
+ aggregate_label + +
+ dictionary +
+
+ +
Aggregate labels of incoming routes with the same FEC.
+
+
+ community + +
+ string +
+
+ +
Community to identify the FEC of incoming routesC.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Aggregate labels of incoming routes with the same FEC
+
+
+ aigp + +
+ dictionary +
+
+ +
Allow sending and receiving of AIGP attribute.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Dn not allow sending and receiving of AIGP attribute.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set AIGP.
+
+
+ damping + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable route flap damping.
+
+
+ defer_initial_multipath_build + +
+ dictionary +
+
+ +
Defer initial multipath build until EOR is received.
+
+
+ maximum_delay + +
+ integer +
+
+ +
Max delay(sec) multipath build after peer is up.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set defer initial multipath build.
+
+
+ delay_route_advertisements + +
+ dictionary +
+
+ +
Delay route updates for this family until FIB-sync.
+
+
+ max_delay_route_age + +
+ integer +
+
+ +
Set max delay advertisement route age.
+
+
+ max_delay_routing_uptime + +
+ integer +
+
+ +
Set max delay advertisement route age.
+
+
+ min_delay_inbound_convergence + +
+ integer +
+
+ +
Set min delayadvertisement after source-peer sent all routes.
+
+
+ min_delay_routing_uptime + +
+ integer +
+
+ +
Set min delay advertisement route age.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set delay route advertisements.
+
+
+ entropy_label + +
+ dictionary +
+
+ +
Use entropy label for entropy label capable BGP LSPs.
+
+
+ import + +
+ string +
+
+ +
Policy to select BGP LSPs to use entropy label.
+
+
+ no_next_hop_validation + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't validate next hop field against route next hop.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set entropy-label attribute.
+
+
+ explicit_null + +
+ dictionary +
+
+ +
Advertise explicit null.
+
+
+ connected_only + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise explicit null only for connected routes.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set explicit-null attribute.
+
+
+ extended_nexthop + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable extended nexthop encoding.
+
+
+ extended_nexthop_color + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Resolve using extended color nexthop.
+
+
+ graceful_restart_forwarding_state_bit + +
+ string +
+
+
    Choices: +
  • from-fib
  • +
  • set
  • +
+
+
Specify BGP graceful restart options.
+
+
+ legacy_redirect_ip_action + +
+ dictionary +
+
+ +
Configure legacy redirect to IP support.
+
+
+ receive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Accept legacy encoded redirect-to-ip action attribute
+
+
+ send + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise Redirect action as legacy redirect attribute.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set the legacy-redirect-ip-action.
+
+
+ local_ipv4_address + +
+ string +
+
+ +
Specify local IPv4 address.
+
+
+ loops + +
+ integer +
+
+ +
Allow local AS in received AS paths.
+
+
+ no_install + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Dont install received routes in forwarding.
+
+
+ no_validate + +
+ string +
+
+ +
Bypass validation procedure for routes that match policy.
+
+
+ output_queue_priority_expedited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Expedited queue; highest priority.
+
+
+ output_queue_priority_priority + +
+ integer +
+
+ +
Output queue priority; higher is better.
+
+
+ per_group_label + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise prefixes with unique labels per group.
+
+
+ per_prefix_label + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allocate a unique label to each advertised prefix.
+
+
+ prefix_limit + +
+ dictionary +
+
+ +
Limit maximum number of prefixes from a peer.
+
+
+ forever + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Idle the peer until the user intervenes.
+
+
+ idle_timeout + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set idle timeout node.
+
+
+ idle_timeout_value + +
+ integer +
+
+ +
Specify timeout before attempting to restart peer.
+
+
+ limit_threshold + +
+ integer +
+
+ +
Percentage of prefix-limit to start warnings.
+
+
+ maximum + +
+ integer +
+
+ +
Specify maximum number of prefixes from a peer.
+
+
+ teardown + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Clear peer connection on reaching limit.
+
+
+ resolve_vpn + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Install received NLRI in inet.3 also.
+
+
+ rib + +
+ string +
+
+
    Choices: +
  • inet.3
  • +
+
+
Select table used by labeled unicast routes.
+
+
+ ribgroup_name + +
+ string +
+
+ +
Name of the routing table group.
+
+
+ route_refresh_priority_expedited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Expedited queue; highest priority.
+
+
+ route_refresh_priority_priority + +
+ integer +
+
+ +
Output queue priority; higher is better.
+
+
+ secondary_independent_resolution + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Resolve FLOW routes in VRF table independent of VPN FLOW route.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set NLRI.
+
+
+ strip_nexthop + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Strip the next-hop from the outgoing flow update.
+
+
+ topology + +
+ list + / elements=dictionary +
+
+ +
Multi topology routing tables.
+
+
+ community + +
+ list + / elements=string +
+
+ +
Community to identify multi topology routes.
+
+
+ name + +
+ string +
+
+ +
Specify topology name.
+
+
+ traffic_statistics + +
+ dictionary +
+
+ +
Collect statistics for BGP label-switched paths
+
+
+ file + +
+ dictionary +
+
+ +
Statistics file options.
+
+
+ filename + +
+ string +
+
+ +
Name of file in which to write trace information.
+
+
+ files + +
+ integer +
+
+ +
Maximum number of trace files.
+
+
+ no_world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ size + +
+ integer +
+
+ +
Maximum trace file size.
+
+
+ world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ interval + +
+ integer +
+
+ +
Time to collect statistics (seconds).
+
+
+ labeled_path + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable ingress labeled path statistics.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set traffic-statistics.
+
+
+ type + +
+ string +
+
+
    Choices: +
  • any
  • +
  • flow
  • +
  • labeled-unicast
  • +
  • multicast
  • +
  • segment-routing-te
  • +
  • unicast
  • +
  • signaling
  • +
  • auto-discovery-mspw
  • +
  • auto-discovery-only
  • +
+
+
Specify type of NLRI.
+
+
+ withdraw_priority_expedited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Expedited queue; highest priority.
+
+
+ withdraw_priority_priority + +
+ integer +
+
+ +
Output queue priority; higher is better.
+
+
+ afi + +
+ string +
+
+
    Choices: +
  • evpn
  • +
  • inet
  • +
  • inet-mdt
  • +
  • inet-mvpn
  • +
  • inet-vpn
  • +
  • inet6
  • +
  • inet6-mvpn
  • +
  • inet6-vpn
  • +
  • iso-vpn
  • +
  • l2vpn
  • +
  • route-target
  • +
  • traffic-engineering
  • +
+
+
address family.
+
+
+ neighbor_address + +
+ string +
+
+ +
Specify neighbor address.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show protocols bgp.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • parsed
  • +
  • gathered
  • +
  • rendered
  • +
+
+
The state the configuration should be left in.
+
State deleted only removes BGP address family attributes that this modules manages and does not negate the BGP neighbor address family completely. Thereby, preserving address-family related configurations under BGP group neighbor context.
+
To delete the address family associated to neighbor use junipernetworks.junos.junos_bgp_neighbor_address_family modules for prior cleanup.
+
Refer to examples for more details.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # admin# show protocols bgp + # + # [edit] + + - name: Merge Junos BGP address family configuration + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'evpn' + af_type: + - type: 'signaling' + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + - afi: 'inet' + af_type: + - type: 'flow' + legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + + - type: 'unicast' + extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: '9.9.9.9' + + - type: 'labeled-unicast' + entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_prefix_label: true + per_group_label: true + prefix_limit: + maximum: 20 + limit_threshold: 99 + forever: true + resolve_vpn: true + rib: 'inet.3' + route_refresh_priority_expedited: true + route_refresh_priority_priority: 3 + + - type: 'any' + accepted_prefix_limit: + maximum: 20 + limit_threshold: 99 + idle_timeout_value: 2000 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: 'from-fib' + state: merged + + # Task Output: + # ------------ + # + # before: {} + # + # commands: + # - + # 2098 + # 2001 + # 2 + # + # 4 + # + # 9.9.9.9 + # + # + # 2099 + # + # 3 + # 2099 + # 2000 + # 2 + # 2032000 + # 32000 + # 23000 + # from-fib + # + # - + # + # after: + # address_family: + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2001 + # limit_threshold: 98 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # type: signaling + # afi: evpn + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2000 + # limit_threshold: 99 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # delay_route_advertisements: + # max_delay_route_age: 20 + # max_delay_routing_uptime: 32000 + # min_delay_inbound_convergence: 32000 + # min_delay_routing_uptime: 23000 + # graceful_restart_forwarding_state_bit: from-fib + # type: any + # - legacy_redirect_ip_action: + # receive: true + # send: true + # loops: 4 + # no_install: true + # output_queue_priority_expedited: true + # secondary_independent_resolution: true + # type: flow + # - entropy_label: + # no_next_hop_validation: true + # explicit_null: + # connected_only: true + # per_group_label: true + # per_prefix_label: true + # prefix_limit: + # forever: true + # limit_threshold: 99 + # maximum: 20 + # resolve_vpn: true + # rib: inet.3 + # route_refresh_priority_priority: 3 + # type: labeled-unicast + # - extended_nexthop: true + # extended_nexthop_color: true + # local_ipv4_address: 9.9.9.9 + # type: unicast + # afi: inet + + # After state + # ----------- + # + # admin# show protocols bgp + # family inet { + # unicast { + # local-ipv4-address 9.9.9.9; + # extended-nexthop; + # extended-nexthop-color; + # } + # flow { + # loops 4; + # no-install; + # output-queue-priority expedited; + # legacy-redirect-ip-action { + # receive; + # send; + # } + # secondary-independent-resolution; + # } + # any { + # accepted-prefix-limit { + # maximum 20; + # teardown 99 idle-timeout 2000; + # } + # damping; + # delay-route-advertisements { + # minimum-delay { + # routing-uptime 23000; + # inbound-convergence 32000; + # } + # maximum-delay { + # route-age 20; + # routing-uptime 32000; + # } + # } + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # graceful-restart { + # forwarding-state-bit from-fib; + # } + # } + # labeled-unicast { + # prefix-limit { + # maximum 20; + # teardown 99 idle-timeout forever; + # } + # route-refresh-priority priority 3; + # per-prefix-label; + # per-group-label; + # rib { + # inet.3; + # } + # explicit-null connected-only; + # resolve-vpn; + # entropy-label { + # no-next-hop-validation; + # } + # } + # } + # family evpn { + # signaling { + # accepted-prefix-limit { + # maximum 20; + # teardown 98 idle-timeout 2001; + # } + # damping; + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # } + # } + + # + # Using replaced + # + # Before state + # ------------ + # + # admin# show protocols bgp + # preference 2; + # hold-time 5; + # advertise-inactive; + # out-delay 10; + # bgp-error-tolerance { + # malformed-route-limit 40000000; + # } + # authentication-algorithm md5; + # advertise-bgp-static { + # policy static-to-bgp; + # } + # family inet { + # unicast { + # local-ipv4-address 9.9.9.9; + # extended-nexthop; + # extended-nexthop-color; + # } + # flow { + # loops 4; + # no-install; + # output-queue-priority expedited; + # legacy-redirect-ip-action { + # receive; + # send; + # } + # secondary-independent-resolution; + # } + # any { + # accepted-prefix-limit { + # maximum 20; + # teardown 99 idle-timeout 2000; + # } + # damping; + # delay-route-advertisements { + # minimum-delay { + # routing-uptime 23000; + # inbound-convergence 32000; + # } + # maximum-delay { + # route-age 20; + # routing-uptime 32000; + # } + # } + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # graceful-restart { + # forwarding-state-bit from-fib; + # } + # } + # labeled-unicast { + # prefix-limit { + # maximum 20; + # teardown 99 idle-timeout forever; + # } + # route-refresh-priority priority 3; + # per-prefix-label; + # per-group-label; + # rib { + # inet.3; + # } + # explicit-null connected-only; + # resolve-vpn; + # entropy-label { + # no-next-hop-validation; + # } + # } + # } + # family evpn { + # signaling { + # accepted-prefix-limit { + # maximum 20; + # teardown 98 idle-timeout 2001; + # } + # damping; + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # } + # } + + - name: Replace existing Junos BGP address family config with provided config + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'evpn' + af_type: + - type: 'signaling' + accepted_prefix_limit: + maximum: 21 + limit_threshold: 99 + idle_timeout_value: 2002 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + damping: true + state: replaced + + # Task Output: + # ------------ + # + # before: + # address_family: + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2001 + # limit_threshold: 98 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # type: signaling + # afi: evpn + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2000 + # limit_threshold: 99 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # delay_route_advertisements: + # max_delay_route_age: 20 + # max_delay_routing_uptime: 32000 + # min_delay_inbound_convergence: 32000 + # min_delay_routing_uptime: 23000 + # graceful_restart_forwarding_state_bit: from-fib + # type: any + # - legacy_redirect_ip_action: + # receive: true + # send: true + # loops: 4 + # no_install: true + # output_queue_priority_expedited: true + # secondary_independent_resolution: true + # type: flow + # - entropy_label: + # no_next_hop_validation: true + # explicit_null: + # connected_only: true + # per_group_label: true + # per_prefix_label: true + # prefix_limit: + # forever: true + # limit_threshold: 99 + # maximum: 20 + # resolve_vpn: true + # rib: inet.3 + # route_refresh_priority_priority: 3 + # type: labeled-unicast + # - extended_nexthop: true + # extended_nexthop_color: true + # local_ipv4_address: 9.9.9.9 + # type: unicast + # afi: inet + # + # commands: + # - + # + # 2199 + # 2002 + # 20 + # 32000 + # 3200023000 + # + # - + # + # after: + # address_family: + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2002 + # limit_threshold: 99 + # maximum: 21 + # damping: true + # delay_route_advertisements: + # max_delay_route_age: 20 + # max_delay_routing_uptime: 32000 + # min_delay_inbound_convergence: 32000 + # min_delay_routing_uptime: 23000 + # type: signaling + # afi: evpn + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2000 + # limit_threshold: 99 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # delay_route_advertisements: + # max_delay_route_age: 20 + # max_delay_routing_uptime: 32000 + # min_delay_inbound_convergence: 32000 + # min_delay_routing_uptime: 23000 + # graceful_restart_forwarding_state_bit: from-fib + # type: any + # - legacy_redirect_ip_action: + # receive: true + # send: true + # loops: 4 + # no_install: true + # output_queue_priority_expedited: true + # secondary_independent_resolution: true + # type: flow + # - entropy_label: + # no_next_hop_validation: true + # explicit_null: + # connected_only: true + # per_group_label: true + # per_prefix_label: true + # prefix_limit: + # forever: true + # limit_threshold: 99 + # maximum: 20 + # resolve_vpn: true + # rib: inet.3 + # route_refresh_priority_priority: 3 + # type: labeled-unicast + # - extended_nexthop: true + # extended_nexthop_color: true + # local_ipv4_address: 9.9.9.9 + # type: unicast + # afi: inet + # + # After state + # ----------- + # + # admin# show protocols bgp + # family inet { + # unicast { + # local-ipv4-address 9.9.9.9; + # extended-nexthop; + # extended-nexthop-color; + # } + # flow { + # loops 4; + # no-install; + # output-queue-priority expedited; + # legacy-redirect-ip-action { + # receive; + # send; + # } + # secondary-independent-resolution; + # } + # any { + # accepted-prefix-limit { + # maximum 20; + # teardown 99 idle-timeout 2000; + # } + # damping; + # delay-route-advertisements { + # minimum-delay { + # routing-uptime 23000; + # inbound-convergence 32000; + # } + # maximum-delay { + # route-age 20; + # routing-uptime 32000; + # } + # } + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # graceful-restart { + # forwarding-state-bit from-fib; + # } + # } + # labeled-unicast { + # prefix-limit { + # maximum 20; + # teardown 99 idle-timeout forever; + # } + # route-refresh-priority priority 3; + # per-prefix-label; + # per-group-label; + # rib { + # inet.3; + # } + # explicit-null connected-only; + # resolve-vpn; + # entropy-label { + # no-next-hop-validation; + # } + # } + # } + # family evpn { + # signaling { + # accepted-prefix-limit { + # maximum 21; + # teardown 99 idle-timeout 2002; + # } + # damping; + # delay-route-advertisements { + # minimum-delay { + # routing-uptime 23000; + # inbound-convergence 32000; + # } + # maximum-delay { + # route-age 20; + # routing-uptime 32000; + # } + # } + # } + # } + + # Using overridden + # + # Before state + # ------------ + # + # admin# show protocols bgp + # family inet { + # unicast { + # local-ipv4-address 9.9.9.9; + # extended-nexthop; + # extended-nexthop-color; + # } + # flow { + # loops 4; + # no-install; + # output-queue-priority expedited; + # legacy-redirect-ip-action { + # receive; + # send; + # } + # secondary-independent-resolution; + # } + # any { + # accepted-prefix-limit { + # maximum 20; + # teardown 99 idle-timeout 2000; + # } + # damping; + # delay-route-advertisements { + # minimum-delay { + # routing-uptime 23000; + # inbound-convergence 32000; + # } + # maximum-delay { + # route-age 20; + # routing-uptime 32000; + # } + # } + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # graceful-restart { + # forwarding-state-bit from-fib; + # } + # } + # labeled-unicast { + # prefix-limit { + # maximum 20; + # teardown 99 idle-timeout forever; + # } + # route-refresh-priority priority 3; + # per-prefix-label; + # per-group-label; + # rib { + # inet.3; + # } + # explicit-null connected-only; + # resolve-vpn; + # entropy-label { + # no-next-hop-validation; + # } + # } + # } + # family evpn { + # signaling { + # accepted-prefix-limit { + # maximum 20; + # teardown 98 idle-timeout 2001; + # } + # damping; + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # } + # } + + - name: Override Junos BGP address family config + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'evpn' + af_type: + - type: 'signaling' + accepted_prefix_limit: + maximum: 21 + limit_threshold: 99 + idle_timeout_value: 2002 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + damping: true + state: overridden + + # Task Output: + # ------------ + # + # before: + # address_family: + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2002 + # limit_threshold: 99 + # maximum: 21 + # damping: true + # delay_route_advertisements: + # max_delay_route_age: 20 + # max_delay_routing_uptime: 32000 + # min_delay_inbound_convergence: 32000 + # min_delay_routing_uptime: 23000 + # type: signaling + # afi: evpn + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2000 + # limit_threshold: 99 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # delay_route_advertisements: + # max_delay_route_age: 20 + # max_delay_routing_uptime: 32000 + # min_delay_inbound_convergence: 32000 + # min_delay_routing_uptime: 23000 + # graceful_restart_forwarding_state_bit: from-fib + # type: any + # - legacy_redirect_ip_action: + # receive: true + # send: true + # loops: 4 + # no_install: true + # output_queue_priority_expedited: true + # secondary_independent_resolution: true + # type: flow + # - entropy_label: + # no_next_hop_validation: true + # explicit_null: + # connected_only: true + # per_group_label: true + # per_prefix_label: true + # prefix_limit: + # forever: true + # limit_threshold: 99 + # maximum: 20 + # resolve_vpn: true + # rib: inet.3 + # route_refresh_priority_priority: 3 + # type: labeled-unicast + # - extended_nexthop: true + # extended_nexthop_color: true + # local_ipv4_address: 9.9.9.9 + # type: unicast + # afi: inet + # + # commands: + # - + # + # 21 + # 992002 + # + # 2032000 + # 32000 + # 23000 + # + # - + # + # After state + # ----------- + # + # admin# show protocols bgp + # family evpn { + # signaling { + # accepted-prefix-limit { + # maximum 21; + # teardown 99 idle-timeout 2002; + # } + # damping; + # delay-route-advertisements { + # minimum-delay { + # routing-uptime 23000; + # inbound-convergence 32000; + # } + # maximum-delay { + # route-age 20; + # routing-uptime 32000; + # } + # } + # } + # } + + # Using deleted + # + # Before state + # ------------ + # + # admin# show protocols bgp + # preference 2; + # hold-time 5; + # advertise-inactive; + # out-delay 10; + # family inet { + # unicast { + # local-ipv4-address 9.9.9.9; + # extended-nexthop; + # extended-nexthop-color; + # } + # flow { + # loops 4; + # no-install; + # output-queue-priority expedited; + # legacy-redirect-ip-action { + # receive; + # send; + # } + # secondary-independent-resolution; + # } + # any { + # accepted-prefix-limit { + # maximum 20; + # teardown 99 idle-timeout 2000; + # } + # damping; + # delay-route-advertisements { + # minimum-delay { + # routing-uptime 23000; + # inbound-convergence 32000; + # } + # maximum-delay { + # route-age 20; + # routing-uptime 32000; + # } + # } + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # graceful-restart { + # forwarding-state-bit from-fib; + # } + # } + # labeled-unicast { + # prefix-limit { + # maximum 20; + # teardown 99 idle-timeout forever; + # } + # route-refresh-priority priority 3; + # per-prefix-label; + # per-group-label; + # rib { + # inet.3; + # } + # explicit-null connected-only; + # resolve-vpn; + # entropy-label { + # no-next-hop-validation; + # } + # } + # } + # family evpn { + # signaling { + # accepted-prefix-limit { + # maximum 20; + # teardown 98 idle-timeout 2001; + # } + # damping; + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # } + # } + + - name: Delete Junos BGP address family config based on the afi + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'inet' + state: deleted + + # Task Output: + # ------------ + # + # before: + # address_family: + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2001 + # limit_threshold: 98 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # type: signaling + # afi: evpn + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2000 + # limit_threshold: 99 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # delay_route_advertisements: + # max_delay_route_age: 20 + # max_delay_routing_uptime: 32000 + # min_delay_inbound_convergence: 32000 + # min_delay_routing_uptime: 23000 + # graceful_restart_forwarding_state_bit: from-fib + # type: any + # - legacy_redirect_ip_action: + # receive: true + # send: true + # loops: 4 + # no_install: true + # output_queue_priority_expedited: true + # secondary_independent_resolution: true + # type: flow + # - entropy_label: + # no_next_hop_validation: true + # explicit_null: + # connected_only: true + # per_group_label: true + # per_prefix_label: true + # prefix_limit: + # forever: true + # limit_threshold: 99 + # maximum: 20 + # resolve_vpn: true + # rib: inet.3 + # route_refresh_priority_priority: 3 + # type: labeled-unicast + # - extended_nexthop: true + # extended_nexthop_color: true + # local_ipv4_address: 9.9.9.9 + # type: unicast + # afi: inet + # + # commands: + # - + # + # - + # + # after: + # address_family: + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2001 + # limit_threshold: 98 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # type: signaling + # afi: evpn + # + # After state + # ----------- + # + # admin# show protocols bgp + # family evpn { + # signaling { + # accepted-prefix-limit { + # maximum 20; + # teardown 98 idle-timeout 2001; + # } + # damping; + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # } + # } + + # Using deleted + # + # Before state + # ------------ + # + # admin# show protocols bgp + # family inet { + # unicast { + # local-ipv4-address 9.9.9.9; + # extended-nexthop; + # extended-nexthop-color; + # } + # flow { + # loops 4; + # no-install; + # output-queue-priority expedited; + # legacy-redirect-ip-action { + # receive; + # send; + # } + # secondary-independent-resolution; + # } + # any { + # accepted-prefix-limit { + # maximum 20; + # teardown 99 idle-timeout 2000; + # } + # damping; + # delay-route-advertisements { + # minimum-delay { + # routing-uptime 23000; + # inbound-convergence 32000; + # } + # maximum-delay { + # route-age 20; + # routing-uptime 32000; + # } + # } + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # graceful-restart { + # forwarding-state-bit from-fib; + # } + # } + # labeled-unicast { + # prefix-limit { + # maximum 20; + # teardown 99 idle-timeout forever; + # } + # route-refresh-priority priority 3; + # per-prefix-label; + # per-group-label; + # rib { + # inet.3; + # } + # explicit-null connected-only; + # resolve-vpn; + # entropy-label { + # no-next-hop-validation; + # } + # } + # } + # family evpn { + # signaling { + # accepted-prefix-limit { + # maximum 20; + # teardown 98 idle-timeout 2001; + # } + # damping; + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # } + # } + + - name: Delete complete Junos BGP address family config + junipernetworks.junos.junos_bgp_address_family: + config: + state: deleted + + # Task Output: + # ------------ + # + # before: + # address_family: + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2001 + # limit_threshold: 98 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # type: signaling + # afi: evpn + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2000 + # limit_threshold: 99 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # delay_route_advertisements: + # max_delay_route_age: 20 + # max_delay_routing_uptime: 32000 + # min_delay_inbound_convergence: 32000 + # min_delay_routing_uptime: 23000 + # graceful_restart_forwarding_state_bit: from-fib + # type: any + # - legacy_redirect_ip_action: + # receive: true + # send: true + # loops: 4 + # no_install: true + # output_queue_priority_expedited: true + # secondary_independent_resolution: true + # type: flow + # - entropy_label: + # no_next_hop_validation: true + # explicit_null: + # connected_only: true + # per_group_label: true + # per_prefix_label: true + # prefix_limit: + # forever: true + # limit_threshold: 99 + # maximum: 20 + # resolve_vpn: true + # rib: inet.3 + # route_refresh_priority_priority: 3 + # type: labeled-unicast + # - extended_nexthop: true + # extended_nexthop_color: true + # local_ipv4_address: 9.9.9.9 + # type: unicast + # afi: inet + # commands: + # - + # + # + # - + # + # after: {} + + # After state + # ----------- + # + # admin# show protocols bgp + # + + # Using gathered + # + # Before state + # ------------ + # + # admin# show protocols bgp + # family inet { + # unicast { + # local-ipv4-address 9.9.9.9; + # extended-nexthop; + # extended-nexthop-color; + # } + # flow { + # loops 4; + # no-install; + # output-queue-priority expedited; + # legacy-redirect-ip-action { + # receive; + # send; + # } + # secondary-independent-resolution; + # } + # any { + # accepted-prefix-limit { + # maximum 20; + # teardown 99 idle-timeout 2000; + # } + # damping; + # delay-route-advertisements { + # minimum-delay { + # routing-uptime 23000; + # inbound-convergence 32000; + # } + # maximum-delay { + # route-age 20; + # routing-uptime 32000; + # } + # } + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # graceful-restart { + # forwarding-state-bit from-fib; + # } + # } + # labeled-unicast { + # prefix-limit { + # maximum 20; + # teardown 99 idle-timeout forever; + # } + # route-refresh-priority priority 3; + # per-prefix-label; + # per-group-label; + # rib { + # inet.3; + # } + # explicit-null connected-only; + # resolve-vpn; + # entropy-label { + # no-next-hop-validation; + # } + # } + # } + # family evpn { + # signaling { + # accepted-prefix-limit { + # maximum 20; + # teardown 98 idle-timeout 2001; + # } + # damping; + # defer-initial-multipath-build { + # maximum-delay 2; + # } + # } + # } + + - name: Gather Junos BGP address family config + junipernetworks.junos.junos_bgp_address_family: + config: + state: gathered + # + # + # Task Output: + # ------------ + # + # gathered: + # address_family: + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2001 + # limit_threshold: 98 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # type: signaling + # afi: evpn + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2000 + # limit_threshold: 99 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # delay_route_advertisements: + # max_delay_route_age: 20 + # max_delay_routing_uptime: 32000 + # min_delay_inbound_convergence: 32000 + # min_delay_routing_uptime: 23000 + # graceful_restart_forwarding_state_bit: from-fib + # type: any + # - legacy_redirect_ip_action: + # receive: true + # send: true + # loops: 4 + # no_install: true + # output_queue_priority_expedited: true + # secondary_independent_resolution: true + # type: flow + # - entropy_label: + # no_next_hop_validation: true + # explicit_null: + # connected_only: true + # per_group_label: true + # per_prefix_label: true + # prefix_limit: + # forever: true + # limit_threshold: 99 + # maximum: 20 + # resolve_vpn: true + # rib: inet.3 + # route_refresh_priority_priority: 3 + # type: labeled-unicast + # - extended_nexthop: true + # extended_nexthop_color: true + # local_ipv4_address: 9.9.9.9 + # type: unicast + # afi: inet + + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # + # 2 + # 5 + # + # 10 + # + # + # + # 9.9.9.9 + # + # + # + # + # + # 4 + # + # + # + # + # + # + # + # + # + # + # + # + # + # 20 + # + # 99 + # + # 2000 + # + # + # + # + # + # + # 23000 + # 32000 + # + # + # 20 + # 32000 + # + # + # + # 2 + # + # + # from-fib + # + # + # + # + # 20 + # + # 99 + # + # + # + # + # + # + # 3 + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # 20 + # + # 98 + # + # 2001 + # + # + # + # + # + # 2 + # + # + # + # + # + # + # + # 0.0.0.100 + # + # 200 + # + # + # so-0/0/0.0 + # 5 + # 3 + # + # + # + # + # + # + # + # 172.16.17.0/24 + # + # + # + # 10.200.16.75 + # + # 65432 + # + # + # + # + + + - name: Parsed the bgp address family running config to get the facts + junipernetworks.junos.junos_bgp_address_family: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # Task Output: + # ------------ + # + # parsed: + # address_family: + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2001 + # limit_threshold: 98 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # type: signaling + # afi: evpn + # - af_type: + # - accepted_prefix_limit: + # idle_timeout_value: 2000 + # limit_threshold: 99 + # maximum: 20 + # damping: true + # defer_initial_multipath_build: + # maximum_delay: 2 + # delay_route_advertisements: + # max_delay_route_age: 20 + # max_delay_routing_uptime: 32000 + # min_delay_inbound_convergence: 32000 + # min_delay_routing_uptime: 23000 + # graceful_restart_forwarding_state_bit: from-fib + # type: any + # - legacy_redirect_ip_action: + # receive: true + # send: true + # loops: 4 + # no_install: true + # output_queue_priority_expedited: true + # secondary_independent_resolution: true + # type: flow + # - entropy_label: + # no_next_hop_validation: true + # explicit_null: + # connected_only: true + # per_group_label: true + # per_prefix_label: true + # prefix_limit: + # forever: true + # limit_threshold: 99 + # maximum: 20 + # resolve_vpn: true + # rib: inet.3 + # route_refresh_priority_priority: 3 + # type: labeled-unicast + # - extended_nexthop: true + # extended_nexthop_color: true + # local_ipv4_address: 9.9.9.9 + # type: unicast + # afi: inet + + # Using rendered + # + - name: Render the commands for provided configuration + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'evpn' + af_type: + - type: 'signaling' + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + - afi: 'inet' + af_type: + - type: 'flow' + legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + + - type: 'unicast' + extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: '9.9.9.9' + + - type: 'labeled-unicast' + entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_prefix_label: true + per_group_label: true + prefix_limit: + maximum: 20 + limit_threshold: 99 + forever: true + resolve_vpn: true + rib: 'inet.3' + route_refresh_priority_expedited: true + route_refresh_priority_priority: 3 + + - type: 'any' + accepted_prefix_limit: + maximum: 20 + limit_threshold: 99 + idle_timeout_value: 2000 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: 'from-fib' + state: rendered + + # Task Output: + # ------------ + # + # rendered: " + # 20 + # 982001 + # + # 2 + # + # 4 + # + # + # 9.9.9.9 + # + # + # 20 + # 99 + # + # 3 + # 20 + # 992000 + # + # 2 + # + # 2032000 + # 32000 + # 23000 + # from-fib + # " + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:bgp><nc:family><nc:evpn><nc:signaling><nc:accepted-prefix-limit> <nc:maximum>21</nc:maximum><nc:teardown><nc:limit-threshold>99</nc:limit-threshold> <nc:idle-timeout><nc:timeout>2002</nc:timeout></nc:idle-timeout> </nc:teardown></nc:accepted-prefix-limit><nc:damping/> <nc:delay-route-advertisements><nc:maximum-delay> <nc:route-age>20</nc:route-age><nc:routing-uptime>32000</nc:routing-uptime> </nc:maximum-delay><nc:minimum-delay><nc:inbound-convergence>32000</nc:inbound-convergence> <nc:routing-uptime>23000</nc:routing-uptime></nc:minimum-delay></nc:delay-route-advertisements> </nc:signaling></nc:evpn></nc:family></nc:bgp></nc:protocols>', 'xml 2', 'xml 3']
+
+
+ gathered + +
+ list +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ list +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ list +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Rohit Thakur (@rohitthakur2590) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_bgp_global_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_bgp_global_module.rst new file mode 100644 index 00000000..e116888b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_bgp_global_module.rst @@ -0,0 +1,11520 @@ +.. _junipernetworks.junos.junos_bgp_global_module: + + +************************************** +junipernetworks.junos.junos_bgp_global +************************************** + +**Manages BGP Global configuration on devices running Juniper JUNOS.** + + +Version added: 1.3.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages global bgp configuration on devices running Juniper JUNOS. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
A list of BGP process configuration.
+
+
+ accept_remote_nexthop + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allow import policy to specify a non-directly connected next-hop.
+
+
+ add_path_display_ipv4_address + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Display add-path path-id in IPv4 address format.
+
+
+ advertise_bgp_static + +
+ dictionary +
+
+ +
Advertise bgp-static routes.
+
+
+ policy + +
+ string +
+
+ +
Specify static route advertisement policy.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Advertise bgp-static routes.
+
+
+ advertise_external + +
+ dictionary +
+
+ +
Advertise best external routes.
+
+
+ conditional + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Route matches active route upto med-comparison rule.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Advertise best external routes.
+
+
+ advertise_from_main_vpn_tables + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise VPN routes from bgp.Xvpn.0 tables in master instance.
+
+
+ advertise_inactive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise inactive routes.
+
+
+ advertise_peer_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise routes received from the same autonomous system.
+
+
+ as_number + +
+ string +
+
+ +
Specify Autonomous system number.
+
+
+ asdot_notation + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable AS-Dot notation to display true 4 byte AS numbers.
+
+
+ authentication_algorithm + +
+ string +
+
+
    Choices: +
  • aes-128-cmac-96
  • +
  • hmac-sha-1-96
  • +
  • md5
  • +
+
+
Specify authentication algorithm name.
+
+
+ authentication_key + +
+ string +
+
+ +
Specify MD5 authentication key.
+
+
+ authentication_key_chain + +
+ string +
+
+ +
Specify authentication key chain name.
+
+
+ bfd_liveness_detection + +
+ dictionary +
+
+ +
Bidirectional Forwarding Detection (BFD) options.
+
+
+ authentication + +
+ dictionary +
+
+ +
Authentication options.
+
+
+ algorithm + +
+ string +
+
+
    Choices: +
  • keyed-md5
  • +
  • keyed-sha-1
  • +
  • meticulous-keyed-md5
  • +
  • meticulous-keyed-sha-1
  • +
  • simple-password
  • +
+
+
Specify algorithm name.
+
+
+ key_chain + +
+ string +
+
+ +
Specify Key chain name.
+
+
+ loose_check + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Verify authentication only if authentication is negotiated.
+
+
+ detection_time + +
+ dictionary +
+
+ +
Specify Detection-time optionss.
+
+
+ threshold + +
+ integer +
+
+ +
Specify high detection-time triggering a trap (milliseconds).
+
+
+ holddown_interval + +
+ integer +
+
+ +
Specify time to hold the session-UP notification to the client.
+
+
+ minimum_interval + +
+ integer +
+
+ +
Specify minimum transmit and receive interval.
+
+
+ minimum_receive_interval + +
+ integer +
+
+ +
Specify minimum receive interval.
+
+
+ multiplier + +
+ integer +
+
+ +
Specify detection time multiplier.
+
+
+ no_adaptation + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable adaptation.
+
+
+ session_mode + +
+ string +
+
+
    Choices: +
  • automatic
  • +
  • multihop
  • +
  • single-hop
  • +
+
+
BFD single-hop or multihop session-mode.
+
+
+ transmit_interval + +
+ dictionary +
+
+ +
Transmit-interval options.
+
+
+ minimum_interval + +
+ integer +
+
+ +
Specify Minimum transmit interval.
+
+
+ threshold + +
+ integer +
+
+ +
Specify high transmit interval triggering a trap.
+
+
+ version + +
+ string +
+
+
    Choices: +
  • 0
  • +
  • 1
  • +
  • automatic
  • +
+
+
Specify BFD protocol version number.
+
+
+ bgp_error_tolerance + +
+ dictionary +
+
+ +
Handle BGP malformed updates softly.
+
+
+ malformed_route_limit + +
+ integer +
+
+ +
Maximum number of malformed routes from a peer.
+
+
+ malformed_update_log_interval + +
+ integer +
+
+ +
Time used when logging malformed update.
+
+
+ no_malformed_route_limit + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify no malformed route limit.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set BGP malformed updates softly.
+
+
+ bmp + +
+ dictionary +
+
+ +
Specific settings to override the routing-options settings.
+
+
+ monitor + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable/Disable monitoring.
+
+
+ route_monitoring + +
+ dictionary +
+
+ +
Control route monitoring settings.
+
+
+ none + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not send route montoring messages.
+
+
+ post_policy + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send post policy route montoring messages.
+
+
+ post_policy_exclude_non_eligible + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send post policy route montoring messages and exclude unresolved routes, etc.
+
+
+ post_policy_exclude_non_feasible + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send pre policy route montoring messages and exclude looped routes, etc.
+
+
+ pre_policy + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send pre policy route montoring messages.
+
+
+ cluster_id + +
+ string +
+
+ +
Specify cluster identifier.
+
+
+ damping + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable route flap damping.
+
+
+ description + +
+ string +
+
+ +
Specify text description.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable BGP.
+
+
+ egress_te + +
+ dictionary +
+
+ +
Use Egress Peering traffic engineering.
+
+
+ backup_path + +
+ string +
+
+ +
The 'egress-te-backup-paths template' to use for this peer.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set the attribute.
+
+
+ egress_te_backup_paths + +
+ dictionary +
+
+ +
Backup-path for Egress-TE peer interface failure.
+
+
+ templates + +
+ list + / elements=dictionary +
+
+ +
Specify Backup-path template.
+
+
+ ip_forward + +
+ dictionary +
+
+ +
Use IP-forward backup path for Egress TE.
+
+
+ rti_name + +
+ string +
+
+ +
Routing-instance to use as IP forward backup-path.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set use IP-forward backup path for Egress TE.
+
+
+ path_name + +
+ string + / required +
+
+ +
Name of Egress-TE backup path.
+
+
+ peers + +
+ list + / elements=string +
+
+ +
Specify address of BGP peer to use as backup next-hop.
+
+
+ remote_nexthop + +
+ string +
+
+ +
Specify address of remote-nexthop to use as backup path.
+
+
+ egress_te_set_segment + +
+ list + / elements=dictionary +
+
+ +
Configure BGP-Peer-Set segment.
+
+
+ egress_te_backup_segment_label + +
+ integer +
+
+ +
BGP-Peer-Set SID label value from static label pool.
+
+
+ label + +
+ integer +
+
+ +
Backup segment label value from static label pool.
+
+
+ name + +
+ string + / required +
+
+ +
The BGP-Peer-Set segment name.
+
+
+ egress_te_sid_stats + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Create BGP-Peer-SID sensor.
+
+
+ enforce_first_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enforce neighbor AS is the first AS in AS-PATH attribute (EBGP).
+
+
+ export + +
+ string +
+
+ +
Specify export policy.
+
+
+ forwarding_context + +
+ string +
+
+ +
Specify routing-instance used for data-forwarding and transport-session.
+
+
+ graceful_restart + +
+ dictionary +
+
+ +
BGP graceful restart options.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable graceful restart.
+
+
+ dont_help_shared_fate_bfd_down + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Honor BFD-Down(C=0) if GR-restart not in progress.
+
+
+ forwarding_state_bit + +
+ dictionary +
+
+ +
Control forwarding-state flag negotiation.
+
+
+ as_rr_client + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
As for a route reflector client.
+
+
+ from_fib + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Always use state of associated FIs.
+
+
+ long_lived + +
+ dictionary +
+
+ +
Long-lived graceful restart options.
+
+
+ advertise_to_non_llgr_neighbor + +
+ dictionary +
+
+ +
Advertise stale routes to non-LLGR neighbors.
+
+
+ omit_no_export + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Advertise stale routes to non-LLGR neighbors.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Advertise stale routes to non-LLGR neighbors.
+
+
+ receiver_disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable receiver (helper) functionality.
+
+
+ restart_time + +
+ integer +
+
+ +
Restart time used when negotiating with a peer.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set BGP graceful restart options.
+
+
+ stale_routes_time + +
+ integer +
+
+ +
Maximum time for which stale routes are kept.
+
+
+ groups + +
+ list + / elements=dictionary +
+
+ +
Specify name of the group.
+
+
+ accept_remote_nexthop + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allow import policy to specify a non-directly connected next-hop.
+
+
+ add_path_display_ipv4_address + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Display add-path path-id in IPv4 address format.
+
+
+ advertise_bgp_static + +
+ dictionary +
+
+ +
Advertise bgp-static routes.
+
+
+ policy + +
+ string +
+
+ +
Specify static route advertisement policy.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Advertise bgp-static routes.
+
+
+ advertise_external + +
+ dictionary +
+
+ +
Advertise best external routes.
+
+
+ conditional + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Route matches active route upto med-comparison rule.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Advertise best external routes.
+
+
+ advertise_inactive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise inactive routes.
+
+
+ advertise_peer_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise routes received from the same autonomous system.
+
+
+ allow + +
+ list + / elements=string +
+
+ +
Configure peer connections for specific networks.
+
+
+ as_override + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Replace neighbor AS number with our AS number
+
+
+ authentication_algorithm + +
+ string +
+
+
    Choices: +
  • aes-128-cmac-96
  • +
  • hmac-sha-1-96
  • +
  • md5
  • +
+
+
Specify authentication algorithm name.
+
+
+ authentication_key + +
+ string +
+
+ +
Specify MD5 authentication key.
+
+
+ authentication_key_chain + +
+ string +
+
+ +
Specify authentication key chain name.
+
+
+ bfd_liveness_detection + +
+ dictionary +
+
+ +
Bidirectional Forwarding Detection (BFD) options.
+
+
+ authentication + +
+ dictionary +
+
+ +
Authentication options.
+
+
+ algorithm + +
+ string +
+
+
    Choices: +
  • keyed-md5
  • +
  • keyed-sha-1
  • +
  • meticulous-keyed-md5
  • +
  • meticulous-keyed-sha-1
  • +
  • simple-password
  • +
+
+
Specify algorithm name.
+
+
+ key_chain + +
+ string +
+
+ +
Specify Key chain name.
+
+
+ loose_check + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Verify authentication only if authentication is negotiated.
+
+
+ detection_time + +
+ dictionary +
+
+ +
Specify Detection-time optionss.
+
+
+ threshold + +
+ integer +
+
+ +
Specify high detection-time triggering a trap (milliseconds).
+
+
+ holddown_interval + +
+ integer +
+
+ +
Specify time to hold the session-UP notification to the client.
+
+
+ minimum_interval + +
+ integer +
+
+ +
Specify minimum transmit and receive interval.
+
+
+ minimum_receive_interval + +
+ integer +
+
+ +
Specify minimum receive interval.
+
+
+ multiplier + +
+ integer +
+
+ +
Specify detection time multiplier.
+
+
+ no_adaptation + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable adaptation.
+
+
+ session_mode + +
+ string +
+
+
    Choices: +
  • automatic
  • +
  • multihop
  • +
  • single-hop
  • +
+
+
BFD single-hop or multihop session-mode.
+
+
+ transmit_interval + +
+ dictionary +
+
+ +
Transmit-interval options.
+
+
+ minimum_interval + +
+ integer +
+
+ +
Specify Minimum transmit interval.
+
+
+ threshold + +
+ integer +
+
+ +
Specify high transmit interval triggering a trap.
+
+
+ version + +
+ string +
+
+
    Choices: +
  • 0
  • +
  • 1
  • +
  • automatic
  • +
+
+
Specify BFD protocol version number.
+
+
+ bgp_error_tolerance + +
+ dictionary +
+
+ +
Handle BGP malformed updates softly.
+
+
+ malformed_route_limit + +
+ integer +
+
+ +
Maximum number of malformed routes from a peer.
+
+
+ malformed_update_log_interval + +
+ integer +
+
+ +
Time used when logging malformed update.
+
+
+ no_malformed_route_limit + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify no malformed route limit.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set BGP malformed updates softly.
+
+
+ bmp + +
+ dictionary +
+
+ +
Specific settings to override the routing-options settings.
+
+
+ monitor + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable/Disable monitoring.
+
+
+ route_monitoring + +
+ dictionary +
+
+ +
Control route monitoring settings.
+
+
+ none + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not send route montoring messages.
+
+
+ post_policy + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send post policy route montoring messages.
+
+
+ post_policy_exclude_non_eligible + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send post policy route montoring messages and exclude unresolved routes, etc.
+
+
+ post_policy_exclude_non_feasible + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send pre policy route montoring messages and exclude looped routes, etc.
+
+
+ pre_policy + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send pre policy route montoring messages.
+
+
+ cluster_id + +
+ string +
+
+ +
Specify cluster identifier.
+
+
+ damping + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable route flap damping.
+
+
+ description + +
+ string +
+
+ +
Specify text description.
+
+
+ egress_te + +
+ dictionary +
+
+ +
Use Egress Peering traffic engineering.
+
+
+ backup_path + +
+ string +
+
+ +
The 'egress-te-backup-paths template' to use for this peer.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set the attribute.
+
+
+ enforce_first_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enforce neighbor AS is the first AS in AS-PATH attribute (EBGP).
+
+
+ export + +
+ string +
+
+ +
Specify export policy.
+
+
+ forwarding_context + +
+ string +
+
+ +
Specify routing-instance used for data-forwarding and transport-session.
+
+
+ graceful_restart + +
+ dictionary +
+
+ +
BGP graceful restart options.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable graceful restart.
+
+
+ dont_help_shared_fate_bfd_down + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Honor BFD-Down(C=0) if GR-restart not in progress.
+
+
+ forwarding_state_bit + +
+ dictionary +
+
+ +
Control forwarding-state flag negotiation.
+
+
+ as_rr_client + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
As for a route reflector client.
+
+
+ from_fib + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Always use state of associated FIs.
+
+
+ long_lived + +
+ dictionary +
+
+ +
Long-lived graceful restart options.
+
+
+ advertise_to_non_llgr_neighbor + +
+ dictionary +
+
+ +
Advertise stale routes to non-LLGR neighbors.
+
+
+ omit_no_export + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Advertise stale routes to non-LLGR neighbors.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Advertise stale routes to non-LLGR neighbors.
+
+
+ receiver_disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable receiver (helper) functionality.
+
+
+ restart_time + +
+ integer +
+
+ +
Restart time used when negotiating with a peer.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set BGP graceful restart options.
+
+
+ stale_routes_time + +
+ integer +
+
+ +
Maximum time for which stale routes are kept.
+
+
+ hold_time + +
+ integer +
+
+ +
Specify hold time used when negotiating with a peer.
+
+
+ idle_after_switch_over + +
+ dictionary +
+
+ +
Stop peer session from coming up after nonstop-routing switch-over.
+
+
+ forever + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Idle the peer until the user intervenes.
+
+
+ timeout + +
+ integer +
+
+ +
Specify timeout value, in seconds, for starting peer after switch over.
+
+
+ import + +
+ list + / elements=string +
+
+ +
Specify import policy.
+
+
+ include_mp_next_hop + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Include NEXT-HOP attribute in multiprotocol updates.
+
+
+ ipsec_sa + +
+ string +
+
+ +
Specify IPSec SA name.
+
+
+ keep + +
+ string +
+
+
    Choices: +
  • all
  • +
  • none
  • +
+
+
Specify how to retain routes in the routing table.
+
+
+ local_address + +
+ string +
+
+ +
Specify Address of local end of BGP session.
+
+
+ local_as + +
+ dictionary +
+
+ +
Local autonomous system number.
+
+
+ alias + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Treat this AS as an alias to the system AS.
+
+
+ as_num + +
+ string + / required +
+
+ +
Autonomous system number in plain number or (asdot notation) format.
+
+
+ loops + +
+ integer +
+
+ +
Maximum number of times this AS can be in an AS path.
+
+
+ no_prepend_global_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Maximum number of times this AS can be in an AS path.
+
+
+ private + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Hide this local AS in paths learned from this peering.
+
+
+ local_interface + +
+ string +
+
+ +
Specify Local interface for IPv6 link local EBGP peering.
+
+
+ local_preference + +
+ string +
+
+ +
Specify value of LOCAL_PREF path attribute.
+
+
+ log_updown + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable log a message for peer state transitions.
+
+
+ metric_out + +
+ dictionary +
+
+ +
Specify route metric sent in MED.
+
+
+ igp + +
+ dictionary +
+
+ +
Track the IGP metric.
+
+
+ delay_med_update + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Delay updating MED when IGP metric increases.
+
+
+ metric_offset + +
+ integer +
+
+ +
Specify metric offset for MED.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set track the IGP metric.
+
+
+ metric_value + +
+ integer +
+
+ +
Specify metric value.
+
+
+ minimum_igp + +
+ dictionary +
+
+ +
Track the minimum IGP metric.
+
+
+ metric_offset + +
+ integer +
+
+ +
Specify metric offset for MED.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set track the minimum IGP metric.
+
+
+ mtu_discovery + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable TCP path MTU discovery.
+
+
+ multihop + +
+ dictionary +
+
+ +
Configure an EBGP multihop session.
+
+
+ no_nexthop_change + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not change next hop to self in advertisements.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set an EBGP multihop session.
+
+
+ ttl + +
+ integer +
+
+ +
TTL value for the session.
+
+
+ multipath + +
+ dictionary +
+
+ +
Allow load sharing among multiple BGP paths.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable Multipath.
+
+
+ multiple_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Use paths received from different ASs.
+
+
+ multiple_as_disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable multipath.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set allow load sharing among multiple BGP paths.
+
+
+ name + +
+ string +
+
+ +
Specify the name of the group
+
+
+ neighbors + +
+ list + / elements=dictionary +
+
+ +
Specify list of neighbors.
+
+
+ accept_remote_nexthop + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allow import policy to specify a non-directly connected next-hop.
+
+
+ add_path_display_ipv4_address + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Display add-path path-id in IPv4 address format.
+
+
+ advertise_bgp_static + +
+ dictionary +
+
+ +
Advertise bgp-static routes.
+
+
+ policy + +
+ string +
+
+ +
Specify static route advertisement policy.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Advertise bgp-static routes.
+
+
+ advertise_external + +
+ dictionary +
+
+ +
Advertise best external routes.
+
+
+ conditional + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Route matches active route upto med-comparison rule.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Advertise best external routes.
+
+
+ advertise_inactive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise inactive routes.
+
+
+ advertise_peer_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise routes received from the same autonomous system.
+
+
+ as_override + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Replace neighbor AS number with our AS number
+
+
+ authentication_algorithm + +
+ string +
+
+
    Choices: +
  • aes-128-cmac-96
  • +
  • hmac-sha-1-96
  • +
  • md5
  • +
+
+
Specify authentication algorithm name.
+
+
+ authentication_key + +
+ string +
+
+ +
Specify MD5 authentication key.
+
+
+ authentication_key_chain + +
+ string +
+
+ +
Specify authentication key chain name.
+
+
+ bfd_liveness_detection + +
+ dictionary +
+
+ +
Bidirectional Forwarding Detection (BFD) options.
+
+
+ authentication + +
+ dictionary +
+
+ +
Authentication options.
+
+
+ algorithm + +
+ string +
+
+
    Choices: +
  • keyed-md5
  • +
  • keyed-sha-1
  • +
  • meticulous-keyed-md5
  • +
  • meticulous-keyed-sha-1
  • +
  • simple-password
  • +
+
+
Specify algorithm name.
+
+
+ key_chain + +
+ string +
+
+ +
Specify Key chain name.
+
+
+ loose_check + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Verify authentication only if authentication is negotiated.
+
+
+ detection_time + +
+ dictionary +
+
+ +
Specify Detection-time optionss.
+
+
+ threshold + +
+ integer +
+
+ +
Specify high detection-time triggering a trap (milliseconds).
+
+
+ holddown_interval + +
+ integer +
+
+ +
Specify time to hold the session-UP notification to the client.
+
+
+ minimum_interval + +
+ integer +
+
+ +
Specify minimum transmit and receive interval.
+
+
+ minimum_receive_interval + +
+ integer +
+
+ +
Specify minimum receive interval.
+
+
+ multiplier + +
+ integer +
+
+ +
Specify detection time multiplier.
+
+
+ no_adaptation + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable adaptation.
+
+
+ session_mode + +
+ string +
+
+
    Choices: +
  • automatic
  • +
  • multihop
  • +
  • single-hop
  • +
+
+
BFD single-hop or multihop session-mode.
+
+
+ transmit_interval + +
+ dictionary +
+
+ +
Transmit-interval options.
+
+
+ minimum_interval + +
+ integer +
+
+ +
Specify Minimum transmit interval.
+
+
+ threshold + +
+ integer +
+
+ +
Specify high transmit interval triggering a trap.
+
+
+ version + +
+ string +
+
+
    Choices: +
  • 0
  • +
  • 1
  • +
  • automatic
  • +
+
+
Specify BFD protocol version number.
+
+
+ bgp_error_tolerance + +
+ dictionary +
+
+ +
Handle BGP malformed updates softly.
+
+
+ malformed_route_limit + +
+ integer +
+
+ +
Maximum number of malformed routes from a peer.
+
+
+ malformed_update_log_interval + +
+ integer +
+
+ +
Time used when logging malformed update.
+
+
+ no_malformed_route_limit + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify no malformed route limit.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set BGP malformed updates softly.
+
+
+ bmp + +
+ dictionary +
+
+ +
Specific settings to override the routing-options settings.
+
+
+ monitor + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable/Disable monitoring.
+
+
+ route_monitoring + +
+ dictionary +
+
+ +
Control route monitoring settings.
+
+
+ none + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not send route montoring messages.
+
+
+ post_policy + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send post policy route montoring messages.
+
+
+ post_policy_exclude_non_eligible + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send post policy route montoring messages and exclude unresolved routes, etc.
+
+
+ post_policy_exclude_non_feasible + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send pre policy route montoring messages and exclude looped routes, etc.
+
+
+ pre_policy + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send pre policy route montoring messages.
+
+
+ cluster_id + +
+ string +
+
+ +
Specify cluster identifier.
+
+
+ damping + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable route flap damping.
+
+
+ description + +
+ string +
+
+ +
Specify neighbor description.
+
+
+ egress_te + +
+ dictionary +
+
+ +
Use Egress Peering traffic engineering.
+
+
+ backup_path + +
+ string +
+
+ +
The 'egress-te-backup-paths template' to use for this peer.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set the attribute.
+
+
+ enforce_first_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enforce neighbor AS is the first AS in AS-PATH attribute (EBGP).
+
+
+ export + +
+ string +
+
+ +
Specify export policy.
+
+
+ forwarding_context + +
+ string +
+
+ +
Specify routing-instance used for data-forwarding and transport-session.
+
+
+ graceful_restart + +
+ dictionary +
+
+ +
BGP graceful restart options.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable graceful restart.
+
+
+ dont_help_shared_fate_bfd_down + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Honor BFD-Down(C=0) if GR-restart not in progress.
+
+
+ forwarding_state_bit + +
+ dictionary +
+
+ +
Control forwarding-state flag negotiation.
+
+
+ as_rr_client + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
As for a route reflector client.
+
+
+ from_fib + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Always use state of associated FIs.
+
+
+ long_lived + +
+ dictionary +
+
+ +
Long-lived graceful restart options.
+
+
+ advertise_to_non_llgr_neighbor + +
+ dictionary +
+
+ +
Advertise stale routes to non-LLGR neighbors.
+
+
+ omit_no_export + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Advertise stale routes to non-LLGR neighbors.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Advertise stale routes to non-LLGR neighbors.
+
+
+ receiver_disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable receiver (helper) functionality.
+
+
+ restart_time + +
+ integer +
+
+ +
Restart time used when negotiating with a peer.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set BGP graceful restart options.
+
+
+ stale_routes_time + +
+ integer +
+
+ +
Maximum time for which stale routes are kept.
+
+
+ hold_time + +
+ integer +
+
+ +
Specify hold time used when negotiating with a peer.
+
+
+ idle_after_switch_over + +
+ dictionary +
+
+ +
Stop peer session from coming up after nonstop-routing switch-over.
+
+
+ forever + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Idle the peer until the user intervenes.
+
+
+ timeout + +
+ integer +
+
+ +
Specify timeout value, in seconds, for starting peer after switch over.
+
+
+ import + +
+ list + / elements=string +
+
+ +
Specify import policy.
+
+
+ include_mp_next_hop + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Include NEXT-HOP attribute in multiprotocol updates.
+
+
+ ipsec_sa + +
+ string +
+
+ +
Specify IPSec SA name.
+
+
+ keep + +
+ string +
+
+
    Choices: +
  • all
  • +
  • none
  • +
+
+
Specify how to retain routes in the routing table.
+
+
+ local_address + +
+ string +
+
+ +
Specify Address of local end of BGP session.
+
+
+ local_as + +
+ dictionary +
+
+ +
Local autonomous system number.
+
+
+ alias + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Treat this AS as an alias to the system AS.
+
+
+ as_num + +
+ string + / required +
+
+ +
Autonomous system number in plain number or (asdot notation) format.
+
+
+ loops + +
+ integer +
+
+ +
Maximum number of times this AS can be in an AS path.
+
+
+ no_prepend_global_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Maximum number of times this AS can be in an AS path.
+
+
+ private + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Hide this local AS in paths learned from this peering.
+
+
+ local_interface + +
+ string +
+
+ +
Specify Local interface for IPv6 link local EBGP peering.
+
+
+ local_preference + +
+ string +
+
+ +
Specify value of LOCAL_PREF path attribute.
+
+
+ log_updown + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable log a message for peer state transitions.
+
+
+ metric_out + +
+ dictionary +
+
+ +
Specify route metric sent in MED.
+
+
+ igp + +
+ dictionary +
+
+ +
Track the IGP metric.
+
+
+ delay_med_update + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Delay updating MED when IGP metric increases.
+
+
+ metric_offset + +
+ integer +
+
+ +
Specify metric offset for MED.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set track the IGP metric.
+
+
+ metric_value + +
+ integer +
+
+ +
Specify metric value.
+
+
+ minimum_igp + +
+ dictionary +
+
+ +
Track the minimum IGP metric.
+
+
+ metric_offset + +
+ integer +
+
+ +
Specify metric offset for MED.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set track the minimum IGP metric.
+
+
+ mtu_discovery + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable TCP path MTU discovery.
+
+
+ multihop + +
+ dictionary +
+
+ +
Configure an EBGP multihop session.
+
+
+ no_nexthop_change + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not change next hop to self in advertisements.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set an EBGP multihop session.
+
+
+ ttl + +
+ integer +
+
+ +
TTL value for the session.
+
+
+ multipath + +
+ dictionary +
+
+ +
Allow load sharing among multiple BGP paths.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable Multipath.
+
+
+ multiple_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Use paths received from different ASs.
+
+
+ multiple_as_disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable multipath.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set allow load sharing among multiple BGP paths.
+
+
+ neighbor_address + +
+ string +
+
+ +
Specify neighbor address.
+
+
+ no_advertise_peer_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allows to not advertise routes received from the same autonomous system.
+
+
+ no_aggregator_id + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set router ID in aggregator path attribute to 0.
+
+
+ no_client_reflect + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable intracluster route redistribution.
+
+
+ out_delay + +
+ integer +
+
+ +
Specify how long before exporting routes from routing table.
+
+
+ outbound_route_filter + +
+ dictionary +
+
+ +
Dynamically negotiated cooperative route filtering.
+
+
+ bgp_orf_cisco_mode + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Using BGP ORF capability code 130 and Prefix ORF type 128.
+
+
+ prefix_based + +
+ dictionary +
+
+ +
Prefix-based outbound route filtering.
+
+
+ accept + +
+ dictionary +
+
+ +
Honor Prefix-based ORFs from remote peers.
+
+
+ inet + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Honor IPv4 prefix filters.
+
+
+ inet6 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Honor IPv6 prefix filters.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set honor Prefix-based ORFs from remote peers.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set prefix-based outbound route filtering.
+
+
+ passive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify to not send open messages to a peer.
+
+
+ peer_as + +
+ string +
+
+ +
Specify Autonomous system number in plain number or 'higher 16bits'.'Lower 16 bits' format.
+
+
+ preference + +
+ string +
+
+ +
Specify preference value.
+
+
+ remove_private + +
+ dictionary +
+
+ +
Remove well-known private AS numbers.
+
+
+ all + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Remove all private AS numbers and do not stop at the first public AS number.
+
+
+ all_replace + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify private AS replacement.
+
+
+ all_replace_nearest + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Use closest public AS number to replace a private AS number.
+
+
+ no_peer_loop_check + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Remove peer loop-check.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Remove well-known private AS numbers.
+
+
+ rfc6514_compliant_safi129 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify Compliance with RFC6514 SAFI129 format.
+
+
+ route_server_client + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable route server client behavior.
+
+
+ tcp_aggressive_transmission + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable aggressive transmission of pure TCP ACKs and retransmissions.
+
+
+ tcp_mss + +
+ integer +
+
+ +
Specify maximum TCP segment size.
+
+
+ traceoptions + +
+ dictionary +
+
+ +
Configure trace options for BGP.
+
+
+ file + +
+ dictionary +
+
+ +
Specify trace file options.
+
+
+ filename + +
+ string + / required +
+
+ +
Specify name of file in which to write trace information.
+
+
+ files + +
+ integer +
+
+ +
Specify maximum number of trace files.
+
+
+ no_world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ size + +
+ integer +
+
+ +
Specify maximum trace file size.
+
+
+ world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allow any user to read the log file.
+
+
+ flag + +
+ list + / elements=dictionary +
+
+ +
Specify tracing parameters.
+
+
+ detail + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace detailed information.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable this trace flag.
+
+
+ filter + +
+ dictionary +
+
+ +
Filter to apply to this flag.
+
+
+ match_on_prefix + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify filter based on prefix.
+
+
+ policy + +
+ string +
+
+ +
Specify filter policy.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set filter to apply to this flag.
+
+
+ name + +
+ string + / required +
+
+
    Choices: +
  • 4byte-as
  • +
  • add-path
  • +
  • all
  • +
  • bfd
  • +
  • damping
  • +
  • egress-te
  • +
  • general
  • +
  • graceful-restart
  • +
  • keepalive
  • +
  • normal
  • +
  • nsr-synchronization
  • +
  • open
  • +
  • packets
  • +
  • policy
  • +
  • refresh
  • +
  • route
  • +
  • state
  • +
  • task
  • +
  • thread-io
  • +
  • thread-update-io
  • +
  • timer
  • +
  • update
  • +
+
+
specify event name
+
+
+ receive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace received packets.
+
+
+ send + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace transmitted packets.
+
+
+ ttl + +
+ integer +
+
+ +
Specify TTL value for the single-hop peer.
+
+
+ unconfigured_peer_graceful_restart + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify BGP unconfigured peer graceful restart options.
+
+
+ vpn_apply_export + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Apply BGP export policy when exporting VPN routes.
+
+
+ no_advertise_peer_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allows to not advertise routes received from the same autonomous system.
+
+
+ no_aggregator_id + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set router ID in aggregator path attribute to 0.
+
+
+ no_client_reflect + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable intracluster route redistribution.
+
+
+ optimal_route_reflection + +
+ dictionary +
+
+ +
Enable optimal route reflection for this client group.
+
+
+ igp_backup + +
+ string +
+
+ +
Backup node identifier for this client group.
+
+
+ igp_primary + +
+ string +
+
+ +
Primary node identifier for this client group.
+
+
+ out_delay + +
+ integer +
+
+ +
Specify how long before exporting routes from routing table.
+
+
+ outbound_route_filter + +
+ dictionary +
+
+ +
Dynamically negotiated cooperative route filtering.
+
+
+ bgp_orf_cisco_mode + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Using BGP ORF capability code 130 and Prefix ORF type 128.
+
+
+ prefix_based + +
+ dictionary +
+
+ +
Prefix-based outbound route filtering.
+
+
+ accept + +
+ dictionary +
+
+ +
Honor Prefix-based ORFs from remote peers.
+
+
+ inet + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Honor IPv4 prefix filters.
+
+
+ inet6 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Honor IPv6 prefix filters.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set honor Prefix-based ORFs from remote peers.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set prefix-based outbound route filtering.
+
+
+ passive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify to not send open messages to a peer.
+
+
+ peer_as + +
+ string +
+
+ +
Specify Autonomous system number in plain number or 'higher 16bits'.'Lower 16 bits' format.
+
+
+ preference + +
+ string +
+
+ +
Specify preference value.
+
+
+ remove_private + +
+ dictionary +
+
+ +
Remove well-known private AS numbers.
+
+
+ all + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Remove all private AS numbers and do not stop at the first public AS number.
+
+
+ all_replace + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify private AS replacement.
+
+
+ all_replace_nearest + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Use closest public AS number to replace a private AS number.
+
+
+ no_peer_loop_check + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Remove peer loop-check.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Remove well-known private AS numbers.
+
+
+ rfc6514_compliant_safi129 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify Compliance with RFC6514 SAFI129 format.
+
+
+ route_server_client + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable route server client behavior.
+
+
+ tcp_aggressive_transmission + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable aggressive transmission of pure TCP ACKs and retransmissions.
+
+
+ tcp_mss + +
+ integer +
+
+ +
Specify maximum TCP segment size.
+
+
+ traceoptions + +
+ dictionary +
+
+ +
Configure trace options for BGP.
+
+
+ file + +
+ dictionary +
+
+ +
Specify trace file options.
+
+
+ filename + +
+ string + / required +
+
+ +
Specify name of file in which to write trace information.
+
+
+ files + +
+ integer +
+
+ +
Specify maximum number of trace files.
+
+
+ no_world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ size + +
+ integer +
+
+ +
Specify maximum trace file size.
+
+
+ world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allow any user to read the log file.
+
+
+ flag + +
+ list + / elements=dictionary +
+
+ +
Specify tracing parameters.
+
+
+ detail + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace detailed information.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable this trace flag.
+
+
+ filter + +
+ dictionary +
+
+ +
Filter to apply to this flag.
+
+
+ match_on_prefix + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify filter based on prefix.
+
+
+ policy + +
+ string +
+
+ +
Specify filter policy.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set filter to apply to this flag.
+
+
+ name + +
+ string + / required +
+
+
    Choices: +
  • 4byte-as
  • +
  • add-path
  • +
  • all
  • +
  • bfd
  • +
  • damping
  • +
  • egress-te
  • +
  • general
  • +
  • graceful-restart
  • +
  • keepalive
  • +
  • normal
  • +
  • nsr-synchronization
  • +
  • open
  • +
  • packets
  • +
  • policy
  • +
  • refresh
  • +
  • route
  • +
  • state
  • +
  • task
  • +
  • thread-io
  • +
  • thread-update-io
  • +
  • timer
  • +
  • update
  • +
+
+
specify event name
+
+
+ receive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace received packets.
+
+
+ send + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace transmitted packets.
+
+
+ ttl + +
+ integer +
+
+ +
Specify TTL value for the single-hop peer.
+
+
+ type + +
+ string +
+
+
    Choices: +
  • external
  • +
  • internal
  • +
+
+
Specify BGP group type.
+
+
+ unconfigured_peer_graceful_restart + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify BGP unconfigured peer graceful restart options.
+
+
+ vpn_apply_export + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Apply BGP export policy when exporting VPN routes.
+
+
+ hold_time + +
+ integer +
+
+ +
Specify hold time used when negotiating with a peer.
+
+
+ holddown_all_stale_labels + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Hold all BGP stale-labels, facilating make-before-break for new label advertisements.
+
+
+ idle_after_switch_over + +
+ dictionary +
+
+ +
Stop peer session from coming up after nonstop-routing switch-over.
+
+
+ forever + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Idle the peer until the user intervenes.
+
+
+ timeout + +
+ integer +
+
+ +
Specify timeout value, in seconds, for starting peer after switch over.
+
+
+ import + +
+ list + / elements=string +
+
+ +
Specify import policy.
+
+
+ include_mp_next_hop + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Include NEXT-HOP attribute in multiprotocol updates.
+
+
+ ipsec_sa + +
+ string +
+
+ +
Specify IPSec SA name.
+
+
+ keep + +
+ string +
+
+
    Choices: +
  • all
  • +
  • none
  • +
+
+
Specify how to retain routes in the routing table.
+
+
+ local_address + +
+ string +
+
+ +
Specify Address of local end of BGP session.
+
+
+ local_as + +
+ dictionary +
+
+ +
Local autonomous system number.
+
+
+ alias + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Treat this AS as an alias to the system AS.
+
+
+ as_num + +
+ string + / required +
+
+ +
Autonomous system number in plain number or (asdot notation) format.
+
+
+ loops + +
+ integer +
+
+ +
Maximum number of times this AS can be in an AS path.
+
+
+ no_prepend_global_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Maximum number of times this AS can be in an AS path.
+
+
+ private + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Hide this local AS in paths learned from this peering.
+
+
+ local_interface + +
+ string +
+
+ +
Specify Local interface for IPv6 link local EBGP peering.
+
+
+ local_preference + +
+ string +
+
+ +
Specify value of LOCAL_PREF path attribute.
+
+
+ log_updown + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable log a message for peer state transitions.
+
+
+ loops + +
+ integer +
+
+ +
Specify maximum number of times this AS can be in an AS path.
+
+
+ metric_out + +
+ dictionary +
+
+ +
Specify route metric sent in MED.
+
+
+ igp + +
+ dictionary +
+
+ +
Track the IGP metric.
+
+
+ delay_med_update + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Delay updating MED when IGP metric increases.
+
+
+ metric_offset + +
+ integer +
+
+ +
Specify metric offset for MED.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set track the IGP metric.
+
+
+ metric_value + +
+ integer +
+
+ +
Specify metric value.
+
+
+ minimum_igp + +
+ dictionary +
+
+ +
Track the minimum IGP metric.
+
+
+ metric_offset + +
+ integer +
+
+ +
Specify metric offset for MED.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set track the minimum IGP metric.
+
+
+ mtu_discovery + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable TCP path MTU discovery.
+
+
+ multihop + +
+ dictionary +
+
+ +
Configure an EBGP multihop session.
+
+
+ no_nexthop_change + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not change next hop to self in advertisements.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set an EBGP multihop session.
+
+
+ ttl + +
+ integer +
+
+ +
TTL value for the session.
+
+
+ multipath + +
+ dictionary +
+
+ +
Allow load sharing among multiple BGP paths.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable Multipath.
+
+
+ multiple_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Use paths received from different ASs.
+
+
+ multiple_as_disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable multipath.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set allow load sharing among multiple BGP paths.
+
+
+ multipath_build_priority + +
+ string +
+
+
    Choices: +
  • low
  • +
  • medium
  • +
+
+
Configure the multipath build priority.
+
+
+ no_advertise_peer_as + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allows to not advertise routes received from the same autonomous system.
+
+
+ no_aggregator_id + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set router ID in aggregator path attribute to 0.
+
+
+ no_client_reflect + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable intracluster route redistribution.
+
+
+ no_precision_timers + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify not to use precision timers for scheduling keepalives.
+
+
+ out_delay + +
+ integer +
+
+ +
Specify how long before exporting routes from routing table.
+
+
+ outbound_route_filter + +
+ dictionary +
+
+ +
Dynamically negotiated cooperative route filtering.
+
+
+ bgp_orf_cisco_mode + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Using BGP ORF capability code 130 and Prefix ORF type 128.
+
+
+ prefix_based + +
+ dictionary +
+
+ +
Prefix-based outbound route filtering.
+
+
+ accept + +
+ dictionary +
+
+ +
Honor Prefix-based ORFs from remote peers.
+
+
+ inet + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Honor IPv4 prefix filters.
+
+
+ inet6 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Honor IPv6 prefix filters.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set honor Prefix-based ORFs from remote peers.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set prefix-based outbound route filtering.
+
+
+ output_queue_priority + +
+ dictionary +
+
+ +
BGP output queue priority scheduler for updates.
+
+
+ defaults + +
+ dictionary +
+
+ +
Map policy's priority class and BGP output-queue.
+
+
+ high + +
+ dictionary +
+
+ +
Assign the 'high' priority class to this output-queue.
+
+
+ expedited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Expedited queue; highest priority.
+
+
+ priority + +
+ integer +
+
+ +
Specify output queue priorit.
+
+
+ low + +
+ dictionary +
+
+ +
Assign the 'low' priority class to this output-queue.
+
+
+ expedited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Expedited queue; highest priority.
+
+
+ priority + +
+ integer +
+
+ +
Specify output queue priorit.
+
+
+ medium + +
+ dictionary +
+
+ +
Assign the 'medium' priority class to this output-queue.
+
+
+ expedited + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Expedited queue; highest priority.
+
+
+ priority + +
+ integer +
+
+ +
Specify output queue priorit.
+
+
+ expedited_update_tokens + +
+ integer +
+
+ +
Expedited queue; highest priority for number of tokens.
+
+
+ priority_update_tokens + +
+ list + / elements=dictionary +
+
+ +
Output queue priority; higher is better.
+
+
+ priority + +
+ integer + / required +
+
+ +
Specify the priority.
+
+
+ update_tokens + +
+ integer + / required +
+
+ +
Specify update_tokens.
+
+
+ passive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify to not send open messages to a peer.
+
+
+ path_selection + +
+ dictionary +
+
+ +
Configure path selection strategy.
+
+
+ always_compare_med + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Compare MED on paths from different AS.
+
+
+ as_path_ignore + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Ignore AS path comparison during path selection.
+
+
+ cisco_non_deterministic + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Use Cisco IOS nondeterministic path selection algorithm.
+
+
+ external_router_id + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Compare router ID on BGP externals.
+
+
+ l2vpn_use_bgp_rules + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Use standard BGP rules during L2VPN path selection.
+
+
+ med_plus_igp + +
+ dictionary +
+
+ +
Add IGP cost to next-hop to MED before comparing MED values.
+
+
+ igp_multiplier + +
+ integer +
+
+ +
Specify multiplier for IGP cost to next-hop.
+
+
+ med_multiplier + +
+ integer +
+
+ +
Specify Multiplier for MED.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set med-plus-igp attribute.
+
+
+ peer_as + +
+ string +
+
+ +
Specify Autonomous system number in plain number or 'higher 16bits'.'Lower 16 bits' format.
+
+
+ precision_timers + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Use precision timers for scheduling keepalives.
+
+
+ preference + +
+ string +
+
+ +
Specify preference value.
+
+
+ remove_private + +
+ dictionary +
+
+ +
Remove well-known private AS numbers.
+
+
+ all + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Remove all private AS numbers and do not stop at the first public AS number.
+
+
+ all_replace + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify private AS replacement.
+
+
+ all_replace_nearest + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Use closest public AS number to replace a private AS number.
+
+
+ no_peer_loop_check + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Remove peer loop-check.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Remove well-known private AS numbers.
+
+
+ rfc6514_compliant_safi129 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify Compliance with RFC6514 SAFI129 format.
+
+
+ route_server_client + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable route server client behavior.
+
+
+ send_addpath_optimization + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable BGP addpath advertisement optimization.
+
+
+ snmp_options + +
+ dictionary +
+
+ +
Customize SNMP behaviors specifically for BGP MIBs.
+
+
+ backward_traps_only_from_established + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Limit traps for backward transitions to only those moving from Established state.
+
+
+ emit_inet_address_length_in_oid + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Emit Length in OID for InetAddress MIB type.
+
+
+ sr_preference_override + +
+ string +
+
+ +
Replace received segment routing traffic engineering preference value with override value.
+
+
+ stale_labels_holddown_period + +
+ integer +
+
+ +
Specify duration (sec) MPLS labels allocated by BGP are kept after they go stale.
+
+
+ tcp_aggressive_transmission + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable aggressive transmission of pure TCP ACKs and retransmissions.
+
+
+ tcp_mss + +
+ integer +
+
+ +
Specify maximum TCP segment size.
+
+
+ traceoptions + +
+ dictionary +
+
+ +
Configure trace options for BGP.
+
+
+ file + +
+ dictionary +
+
+ +
Specify trace file options.
+
+
+ filename + +
+ string + / required +
+
+ +
Specify name of file in which to write trace information.
+
+
+ files + +
+ integer +
+
+ +
Specify maximum number of trace files.
+
+
+ no_world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ size + +
+ integer +
+
+ +
Specify maximum trace file size.
+
+
+ world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allow any user to read the log file.
+
+
+ flag + +
+ list + / elements=dictionary +
+
+ +
Specify tracing parameters.
+
+
+ detail + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace detailed information.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable this trace flag.
+
+
+ filter + +
+ dictionary +
+
+ +
Filter to apply to this flag.
+
+
+ match_on_prefix + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify filter based on prefix.
+
+
+ policy + +
+ string +
+
+ +
Specify filter policy.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set filter to apply to this flag.
+
+
+ name + +
+ string + / required +
+
+
    Choices: +
  • 4byte-as
  • +
  • add-path
  • +
  • all
  • +
  • bfd
  • +
  • damping
  • +
  • egress-te
  • +
  • general
  • +
  • graceful-restart
  • +
  • keepalive
  • +
  • normal
  • +
  • nsr-synchronization
  • +
  • open
  • +
  • packets
  • +
  • policy
  • +
  • refresh
  • +
  • route
  • +
  • state
  • +
  • task
  • +
  • thread-io
  • +
  • thread-update-io
  • +
  • timer
  • +
  • update
  • +
+
+
specify event name
+
+
+ receive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace received packets.
+
+
+ send + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace transmitted packets.
+
+
+ traffic_statistics_labeled_path + +
+ dictionary +
+
+ +
Collect periodic ingress labeled statistics for BGP label-switched paths.
+
+
+ file + +
+ dictionary +
+
+ +
Specify statistics file options.
+
+
+ filename + +
+ string +
+
+ +
Specify name of file in which to write trace information.
+
+
+ files + +
+ integer +
+
+ +
Specify maximum number of trace files.
+
+
+ no_world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ size + +
+ integer +
+
+ +
Specify maximum trace file size.
+
+
+ world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allow any user to read the log file.
+
+
+ interval + +
+ integer +
+
+ +
Specify time interval to collect statistics.
+
+
+ ttl + +
+ integer +
+
+ +
Specify TTL value for the single-hop peer.
+
+
+ unconfigured_peer_graceful_restart + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify BGP unconfigured peer graceful restart options.
+
+
+ vpn_apply_export + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Apply BGP export policy when exporting VPN routes.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show protocols bgp.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • purged
  • +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • parsed
  • +
  • rendered
  • +
+
+
The state the configuration should be left in.
+
State purged removes all (routing-options autonomous-system, bgp global, bgp groups, bgp neighbors, bgp family and bgp group and neighbor family) the BGP configurations from the target device. Use caution with this state.
+
State deleted only removes BGP attributes that this modules manages and does not negate the BGP process completely. Thereby, preserving address-family related configurations under BGP context.
+
Running states deleted and replaced will result in an error if there are address-family configuration lines present under a neighbor.Please use the junipernetworks.junos.junos_bgp_address_family modules for prior cleanup.
+
Refer to examples for more details.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state: + # ------------- + # + # vsrx# show bgp summary + # BGP is not running + + # vsrx# show routing-options autonomous-system + + - name: Merge provided bgp config with device configuration + junipernetworks.junos.junos_bgp_global: + config: + as_number: "65534" + loops: 3 + asdot_notation: true + accept_remote_nexthop: true + add_path_display_ipv4_address: true + advertise_from_main_vpn_tables: true + advertise_inactive: true + authentication_algorithm: "md5" + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + egress_te_sid_stats: true + hold_time: 5 + holddown_all_stale_labels: true + include_mp_next_hop: true + log_updown: true + no_advertise_peer_as: true + no_aggregator_id: true + no_client_reflect: true + out_delay: 10 + precision_timers: true + preference: 2 + state: merged + + # Task Output: + # ------------ + # before: {} + # + # commands: + # - + # + # - + # 655343 + # + # after: + # accept_remote_nexthop: true + # add_path_display_ipv4_address: true + # advertise_from_main_vpn_tables: true + # advertise_inactive: true + # as_number: '65534' + # asdot_notation: true + # authentication_algorithm: md5 + # bgp_error_tolerance: + # malformed_route_limit: 20000000 + # bmp: + # monitor: true + # damping: true + # description: This is configured with Junos_bgp resource module + # egress_te_sid_stats: true + # hold_time: 5 + # holddown_all_stale_labels: true + # include_mp_next_hop: true + # log_updown: true + # loops: 3 + # no_advertise_peer_as: true + # no_aggregator_id: true + # no_client_reflect: true + # out_delay: 10 + # precision_timers: true + # preference: '2' + + # After state: + # ------------ + # + # vsrx# show routing-options autonomous-system + # 65534 loops 3 asdot-notation; + + # vsrx# show protocols bgp + # precision-timers; + # advertise-from-main-vpn-tables; + # holddown-all-stale-labels; + # description "This is configured with Junos_bgp resource module"; + # accept-remote-nexthop; + # preference 2; + # hold-time 5; + # advertise-inactive; + # no-advertise-peer-as; + # no-aggregator-id; + # out-delay 10; + # log-updown; + # damping; + # bgp-error-tolerance { + # malformed-route-limit 20000000; + # } + # authentication-algorithm md5; + # no-client-reflect; + # include-mp-next-hop; + # bmp { + # monitor enable; + # } + # add-path-display-ipv4-address; + # egress-te-sid-stats; + + # Using replaced + # + # Before state: + # ------------- + # + # vsrx# show routing-options autonomous-system + # [edit] + # vsrx# show protocols bgp + # precision-timers; + # advertise-from-main-vpn-tables; + # holddown-all-stale-labels; + # description "This is configured with Junos_bgp resource module"; + # accept-remote-nexthop; + # preference 2; + # hold-time 5; + # advertise-inactive; + # no-advertise-peer-as; + # no-aggregator-id; + # out-delay 10; + # log-updown; + # damping; + # bgp-error-tolerance { + # malformed-route-limit 20000000; + # } + # authentication-algorithm md5; + # no-client-reflect; + # include-mp-next-hop; + # bmp { + # monitor enable; + # } + # add-path-display-ipv4-address; + # egress-te-sid-stats; + + - name: Replace running config with provided config + junipernetworks.junos.junos_bgp_global: + config: + advertise_inactive: true + authentication_algorithm: "md5" + bfd_liveness_detection: + minimum_receive_interval: 8 + multiplier: 30 + no_adaptation: true + transmit_interval: + minimum_interval: 4 + version: "automatic" + bgp_error_tolerance: + malformed_route_limit: 40000000 + description: "Replace running bgp config" + egress_te_sid_stats: true + hold_time: 5 + out_delay: 10 + preference: "2" + state: replaced + + # Task Output: + # ------------ + # + # before: + # accept_remote_nexthop: true + # add_path_display_ipv4_address: true + # advertise_from_main_vpn_tables: true + # advertise_inactive: true + # as_number: '65534' + # asdot_notation: true + # authentication_algorithm: md5 + # bgp_error_tolerance: + # malformed_route_limit: 20000000 + # bmp: + # monitor: true + # damping: true + # description: This is configured with Junos_bgp resource module + # egress_te_sid_stats: true + # hold_time: 5 + # holddown_all_stale_labels: true + # include_mp_next_hop: true + # log_updown: true + # loops: 3 + # no_advertise_peer_as: true + # no_aggregator_id: true + # no_client_reflect: true + # out_delay: 10 + # precision_timers: true + # preference: '2' + + # commands: + # - + # + # + # md5Replace running bgp conf> + # - + + # + # after: + # advertise_inactive: true + # authentication_algorithm: md5 + # bfd_liveness_detection: + # minimum_receive_interval: 8 + # multiplier: 30 + # no_adaptation: true + # transmit_interval: + # minimum_interval: 4 + # version: automatic + # bgp_error_tolerance: + # malformed_route_limit: 40000000 + # description: Replace running bgp config + # egress_te_sid_stats: true + # hold_time: 5 + # out_delay: 10 + # preference: '2' + + # After state: + # ------------ + # + # varx# show protocols bgp + # description "Replace running bgp config"; + # preference 2; + # hold-time 5; + # advertise-inactive; + # out-delay 10; + # bgp-error-tolerance { + # malformed-route-limit 40000000; + # } + # authentication-algorithm md5; + # bfd-liveness-detection { + # version automatic; + # minimum-receive-interval 8; + # multiplier 30; + # no-adaptation; + # transmit-interval { + # minimum-interval 4; + # } + # } + # egress-te-sid-stats; + + # vsrx# show routing-options autonomous-system + + # Using overridden + # "(NOTE: This will work same as replaced operation)" + # + # Before state: + # ------------- + # + # vsrx# show routing-options autonomous-system + # [edit] + # vsrx# show protocols bgp + # precision-timers; + # advertise-from-main-vpn-tables; + # holddown-all-stale-labels; + # description "This is configured with Junos_bgp resource module"; + # accept-remote-nexthop; + # preference 2; + # hold-time 5; + # advertise-inactive; + # no-advertise-peer-as; + # no-aggregator-id; + # out-delay 10; + # log-updown; + # damping; + # bgp-error-tolerance { + # malformed-route-limit 20000000; + # } + # authentication-algorithm md5; + # no-client-reflect; + # include-mp-next-hop; + # bmp { + # monitor enable; + # } + # add-path-display-ipv4-address; + # egress-te-sid-stats; + + - name: Override running config with provided config + junipernetworks.junos.junos_bgp_global: + config: + advertise_inactive: true + authentication_algorithm: "md5" + bfd_liveness_detection: + minimum_receive_interval: 8 + multiplier: 30 + no_adaptation: true + transmit_interval: + minimum_interval: 4 + version: "automatic" + bgp_error_tolerance: + malformed_route_limit: 40000000 + description: "Replace running bgp config" + egress_te_sid_stats: true + hold_time: 5 + out_delay: 10 + preference: "2" + state: overridden + + # Task Output: + # ------------ + # + # before: + # accept_remote_nexthop: true + # add_path_display_ipv4_address: true + # advertise_from_main_vpn_tables: true + # advertise_inactive: true + # as_number: '65534' + # asdot_notation: true + # authentication_algorithm: md5 + # bgp_error_tolerance: + # malformed_route_limit: 20000000 + # bmp: + # monitor: true + # damping: true + # description: This is configured with Junos_bgp resource module + # egress_te_sid_stats: true + # hold_time: 5 + # holddown_all_stale_labels: true + # include_mp_next_hop: true + # log_updown: true + # loops: 3 + # no_advertise_peer_as: true + # no_aggregator_id: true + # no_client_reflect: true + # out_delay: 10 + # precision_timers: true + # preference: '2' + + # commands: + # - + # + # + # md5Replace running bgp conf> + # - + + # + # after: + # advertise_inactive: true + # authentication_algorithm: md5 + # bfd_liveness_detection: + # minimum_receive_interval: 8 + # multiplier: 30 + # no_adaptation: true + # transmit_interval: + # minimum_interval: 4 + # version: automatic + # bgp_error_tolerance: + # malformed_route_limit: 40000000 + # description: Replace running bgp config + # egress_te_sid_stats: true + # hold_time: 5 + # out_delay: 10 + # preference: '2' + + # After state: + # ------------ + # + # varx# show protocols bgp + # description "Replace running bgp config"; + # preference 2; + # hold-time 5; + # advertise-inactive; + # out-delay 10; + # bgp-error-tolerance { + # malformed-route-limit 40000000; + # } + # authentication-algorithm md5; + # bfd-liveness-detection { + # version automatic; + # minimum-receive-interval 8; + # multiplier 30; + # no-adaptation; + # transmit-interval { + # minimum-interval 4; + # } + # } + # egress-te-sid-stats; + + # vsrx# show routing-options autonomous-system + + # Using deleted + # "(NOTE: This WILL delete the bgp global attributes)" + # Before state + # ------------ + # + # vsrx# show protocols bgp + # description "Replace running bgp config"; + # preference 2; + # hold-time 5; + # advertise-inactive; + # out-delay 10; + # bgp-error-tolerance { + # malformed-route-limit 40000000; + # } + # authentication-algorithm md5; + # bfd-liveness-detection { + # version automatic; + # minimum-receive-interval 8; + # multiplier 30; + # no-adaptation; + # transmit-interval { + # minimum-interval 4; + # } + # } + # egress-te-sid-stats; + + - name: Delete bgp section of running config + junipernetworks.junos.junos_bgp_global: + config: + state: deleted + + # Task Output: + # ------------ + + # before: + # advertise_inactive: true + # authentication_algorithm: md5 + # bfd_liveness_detection: + # minimum_receive_interval: 8 + # multiplier: 30 + # no_adaptation: true + # transmit_interval: + # minimum_interval: 4 + # version: automatic + # bgp_error_tolerance: + # malformed_route_limit: 40000000 + # description: Replace running bgp config + # egress_te_sid_stats: true + # hold_time: 5 + # out_delay: 10 + # preference: '2' + + # commands: + # - + # + # + # - + + # after: {} + + # After state: + # ------------ + # vsrx# show protocols bgp + + # vsrx# show routing-options autonomous-system + + # Using gathered + # + # Before state: + # ------------- + # + # vsrx# show protocols bgp + # precision-timers; + # advertise-from-main-vpn-tables; + # holddown-all-stale-labels; + # description "This is configured with Junos_bgp resource module"; + # accept-remote-nexthop; + # preference 2; + # hold-time 5; + # advertise-inactive; + # no-advertise-peer-as; + # no-aggregator-id; + # out-delay 10; + # log-updown; + # damping; + # bgp-error-tolerance { + # malformed-route-limit 20000000; + # } + # authentication-algorithm md5; + # no-client-reflect; + # include-mp-next-hop; + # bmp { + # monitor enable; + # } + # add-path-display-ipv4-address; + # egress-te-sid-stats; + + - name: Gather BGP facts from running config + junipernetworks.junos.junos_bgp_global: + config: + state: gathered + + # Task Output: + # ------------ + + # gathered: + # accept_remote_nexthop: true + # add_path_display_ipv4_address: true + # advertise_from_main_vpn_tables: true + # advertise_inactive: true + # as_number: '65534' + # asdot_notation: true + # authentication_algorithm: md5 + # bgp_error_tolerance: + # malformed_route_limit: 20000000 + # bmp: + # monitor: true + # damping: true + # description: This is configured with Junos_bgp resource module + # egress_te_sid_stats: true + # hold_time: 5 + # holddown_all_stale_labels: true + # include_mp_next_hop: true + # log_updown: true + # loops: 3 + # no_advertise_peer_as: true + # no_aggregator_id: true + # no_client_reflect: true + # out_delay: 10 + # precision_timers: true + # preference: '2' + + # Using purged + # "(NOTE: This WILL delete the configured global BGP, and BGP address family config)" + + # Before state: + # ------------- + # + # vsrx# show protocols bgp + # precision-timers; + # advertise-from-main-vpn-tables; + # holddown-all-stale-labels; + # description "This is configured with Junos_bgp resource module"; + # accept-remote-nexthop; + # preference 2; + # hold-time 5; + # advertise-inactive; + # no-advertise-peer-as; + # no-aggregator-id; + # out-delay 10; + # log-updown; + # damping; + # bgp-error-tolerance { + # malformed-route-limit 20000000; + # } + # authentication-algorithm md5; + # no-client-reflect; + # include-mp-next-hop; + # bmp { + # monitor enable; + # } + # add-path-display-ipv4-address; + # egress-te-sid-stats; + + - name: Purge BGP config from running config + junipernetworks.junos.junos_bgp_global: + config: + state: purged + + # Task Output: + # ------------ + + # before: + # accept_remote_nexthop: true + # add_path_display_ipv4_address: true + # advertise_from_main_vpn_tables: true + # advertise_inactive: true + # as_number: '65534' + # asdot_notation: true + # authentication_algorithm: md5 + # bgp_error_tolerance: + # malformed_route_limit: 20000000 + # bmp: + # monitor: true + # damping: true + # description: This is configured with Junos_bgp resource module + # egress_te_sid_stats: true + # hold_time: 5 + # holddown_all_stale_labels: true + # include_mp_next_hop: true + # log_updown: true + # loops: 3 + # no_advertise_peer_as: true + # no_aggregator_id: true + # no_client_reflect: true + # out_delay: 10 + # precision_timers: true + # preference: '2' + + # commands: + # - + # - + # + + # after: {} + + # After state: + # ------------ + # vsrx# show protocols bgp + + # vsrx# show routing-options autonomous-system + + # Using rendered + + - name: Render the commands for provided configuration + junipernetworks.junos.junos_bgp_global: + config: + as_number: "65534" + loops: 3 + asdot_notation: true + accept_remote_nexthop: true + add_path_display_ipv4_address: true + advertise_from_main_vpn_tables: true + advertise_inactive: true + authentication_algorithm: "md5" + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + egress_te_sid_stats: true + hold_time: 5 + holddown_all_stale_labels: true + include_mp_next_hop: true + log_updown: true + no_advertise_peer_as: true + no_aggregator_id: true + no_client_reflect: true + out_delay: 10 + precision_timers: true + preference: 2 + state: rendered + + # Task Output: + # ------------ + + # rendered: + # + # + # + + # + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # + # + # + # + # This is configured with Junos_bgp resource module + # + # 2 + # 5 + # + # + # + # 10 + # + # + # + # 20000000 + # + # md5 + # + # + # + # + # disable + # + # + # + # + # + # static-to-bgp + # + # + # + # automatic + # 4 + # 10 + # + # + # 2 + # + # + # 300000 + # + # + # + # + # internal + # 8 + # + # + # external + # 9 + # + # + # inboun + # internal + # + # + # ibgp + # internal + # 10.2.2.2 + # static-to-bgp + # + # 10.1.1.1 + # + # + # + # + # + # 0.0.0.100 + # + # 200 + # + # + # so-0/0/0.0 + # 5 + # 3 + # + # + # + # + # + # + # + # 172.16.17.0/24 + # + # + # + # 10.200.16.75 + # + # 65432 + # + # + # + # + + + - name: Parsed the device configuration to get ansible facts + junipernetworks.junos.junos_bgp_global: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + + # Task Output: + # ------------ + + # parsed: + # accept_remote_nexthop: true + # add_path_display_ipv4_address: true + # advertise_bgp_static: + # policy: static-to-bgp + # advertise_from_main_vpn_tables: true + # advertise_inactive: true + # as_number: '65432' + # authentication_algorithm: md5 + # bfd_liveness_detection: + # detection_time: + # threshold: 300000 + # minimum_receive_interval: 4 + # multiplier: 10 + # no_adaptation: true + # transmit_interval: + # minimum_interval: 2 + # version: automatic + # bgp_error_tolerance: + # malformed_route_limit: 20000000 + # bmp: + # monitor: false + # route_monitoring: + # none: true + # damping: true + # description: This is configured with Junos_bgp resource module + # egress_te_sid_stats: true + # groups: + # - name: internal + # out_delay: 8 + # - name: external + # out_delay: 9 + # - name: inboun + # type: internal + # - export: static-to-bgp + # local_address: 10.2.2.2 + # name: ibgp + # neighbors: + # - neighbor_address: 10.1.1.1 + # type: internal + # hold_time: 5 + # holddown_all_stale_labels: true + # include_mp_next_hop: true + # log_updown: true + # no_advertise_peer_as: true + # no_aggregator_id: true + # no_client_reflect: true + # out_delay: 10 + # precision_timers: true + # preference: '2' + # remove_private: + # set: true + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
[' <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:bgp> <nc:damping/> <nc:egress-te-sid-stats/> <nc:authentication-algorithm>md5</nc:authentication-algorithm> <nc:description>This is configured with Junos_bgp resource module</nc:description> <nc:hold-time>5</nc:hold-time> <nc:bfd-liveness-detection> <nc:transmit-interval> <nc:minimum-interval>2</nc:minimum-interval> </nc:transmit-interval> <nc:minimum-receive-interval>4</nc:minimum-receive-interval> <nc:multiplier>10</nc:multiplier> <nc:no-adaptation/> <nc:version>automatic</nc:version> </nc:bfd-liveness-detection> <nc:bgp-error-tolerance> <nc:malformed-route-limit>20000000</nc:malformed-route-limit> </nc:bgp-error-tolerance> <nc:bmp> <nc:monitor>enable</nc:monitor> </nc:bmp> </nc:bgp> </nc:protocols>', 'xml 2', 'xml 3']
+
+
+ gathered + +
+ list +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ list +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ list +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Rohit Thakur (@rohitthakur2590) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_cliconf.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_cliconf.rst new file mode 100644 index 00000000..73b08f66 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_cliconf.rst @@ -0,0 +1,80 @@ +.. _junipernetworks.junos.junos_cliconf: + + +*************************** +junipernetworks.junos.junos +*************************** + +**Use junos cliconf to run command on Juniper Junos OS platform** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This junos plugin provides low level abstraction apis for sending and receiving CLI commands from Juniper Junos OS network devices. + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + +
ParameterChoices/DefaultsConfigurationComments
+
+ config_commands + +
+ list + / elements=string +
+
added in 2.0.0
+
+ Default:
[]
+
+
var: ansible_junos_config_commands
+
+
Specifies a list of commands that can make configuration changes to the target device.
+
When `ansible_network_single_user_mode` is enabled, if a command sent to the device is present in this list, the existing cache is invalidated.
+
+
+ + + + + + + + +Status +------ + + +Authors +~~~~~~~ + +- Ansible Networking Team (@ansible-network) + + +.. hint:: + Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up. diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_command_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_command_module.rst new file mode 100644 index 00000000..f7aad42d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_command_module.rst @@ -0,0 +1,319 @@ +.. _junipernetworks.junos.junos_command_module: + + +*********************************** +junipernetworks.junos.junos_command +*********************************** + +**Run arbitrary commands on an Juniper JUNOS device** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- Sends an arbitrary set of commands to an JUNOS 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. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- jxmlease +- ncclient (>=v0.5.2) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ commands + +
+ list + / elements=string +
+
+ +
The commands to send to the remote junos device. The resulting output from the command is returned. If the wait_for argument is provided, the module is not returned until the condition is satisfied or the number of retries has been exceeded.
+
+
+ display + +
+ string +
+
+
    Choices: +
  • text
  • +
  • json
  • +
  • xml
  • +
  • set
  • +
+
+
Encoding scheme to use when serializing output from the device. This handles how to properly understand the output and apply the conditionals path to the result set. For rpcs argument default display is xml and for commands argument default display is text. Value set is applicable only for fetching configuration from device.
+

aliases: format, output
+
+
+ interval + +
+ integer +
+
+ Default:
1
+
+
Configures the interval in seconds to wait between retries of the command. If the command does not pass the specified conditional, the interval indicates how to long to wait before trying the command again.
+
+
+ match + +
+ string +
+
+
    Choices: +
  • any
  • +
  • all ←
  • +
+
+
The match argument is used in conjunction with the wait_for argument to specify the match policy. Valid values are all or any. If the value is set to all then all conditionals in the wait_for must be satisfied. If the value is set to any then only one of the values must be satisfied.
+
+
+ retries + +
+ integer +
+
+ Default:
10
+
+
Specifies the number of retries a command should be tried before it is considered failed. The command is run on the target device every retry and evaluated against the wait_for conditionals.
+
+
+ rpcs + +
+ list + / elements=string +
+
+ +
The rpcs argument accepts a list of RPCs to be executed over a netconf session and the results from the RPC execution is return to the playbook via the modules results dictionary.
+
+
+ wait_for + +
+ list + / elements=string +
+
+ +
Specifies what to evaluate from the output of the command and what conditionals to apply. This argument will cause the task to wait for a particular conditional to be true before moving forward. If the conditional is not true by the configured retries, the task fails. See examples.
+

aliases: waitfor
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. + - Recommended connection is ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - This module also works with ``network_cli`` connections and with ``local`` connections for legacy playbooks. + - For information on using CLI and netconf see the :ref:`Junos OS Platform Options guide ` + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` + - For more information on using Ansible to manage Juniper network devices see https://www.ansible.com/ansible-juniper. + + + +Examples +-------- + +.. code-block:: yaml + + - name: run show version on remote devices + junipernetworks.junos.junos_command: + commands: show version + + - name: run show version and check to see if output contains Juniper + junipernetworks.junos.junos_command: + commands: show version + wait_for: result[0] contains Juniper + + - name: run multiple commands on remote nodes + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces + + - name: run multiple commands and evaluate the output + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces + wait_for: + - result[0] contains Juniper + - result[1] contains Loopback0 + + - name: run commands and specify the output format + junipernetworks.junos.junos_command: + commands: show version + display: json + + - name: run rpc on the remote device + junipernetworks.junos.junos_command: + commands: show configuration + display: set + + - name: run rpc on the remote device + junipernetworks.junos.junos_command: + rpcs: get-software-information + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ failed_conditions + +
+ list +
+
failed +
The list of conditionals that have failed
+
+
Sample:
+
['...', '...']
+
+
+ output + +
+ list +
+
If the display is in xml format. +
The set of transformed xml to json format from the commands responses
+
+
Sample:
+
['...', '...']
+
+
+ stdout + +
+ list +
+
always apart from low level errors (such as action plugin) +
The set of responses from the commands
+
+
Sample:
+
['...', '...']
+
+
+ stdout_lines + +
+ list +
+
always apart from low level errors (such as action plugin) +
The value of stdout split into a list
+
+
Sample:
+
[['...', '...'], ['...'], ['...']]
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Peter Sprygada (@privateip) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_config_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_config_module.rst new file mode 100644 index 00000000..61051583 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_config_module.rst @@ -0,0 +1,533 @@ +.. _junipernetworks.junos.junos_config_module: + + +********************************** +junipernetworks.junos.junos_config +********************************** + +**Manage configuration on devices running Juniper JUNOS** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module provides an implementation for working with the active configuration running on Juniper JUNOS devices. It provides a set of arguments for loading configuration, performing rollback operations and zeroing the active configuration on the device. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.5.2) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ backup + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
This argument will cause the module to create a full backup of the current running-config from the remote device before any changes are made. If the backup_options value is not given, the backup file is written to the 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.
+
+
+ backup_options + +
+ dictionary +
+
+ +
This is a dict object containing configurable options related to backup file path. The value of this option is read only when backup is set to true, if backup is set to false this option will be silently ignored.
+
+
+ backup_format + +
+ string +
+
+
    Choices: +
  • xml
  • +
  • set ←
  • +
  • text
  • +
  • json
  • +
+
+
This argument specifies the format of the configuration the backup file will be stored as. If the argument is not specified, the module will use the 'set' format.
+
+
+ dir_path + +
+ path +
+
+ +
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 filename or default filename as described in filename options description. If the path value is not given in that case a backup directory will be created in the current working directory and backup configuration will be copied in filename within backup directory.
+
+
+ filename + +
+ string +
+
+ +
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 <hostname>_config.<current-date>@<current-time>
+
+
+ check_commit + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
This argument will check correctness of syntax; do not apply changes.
+
Note that this argument can be used to confirm verified configuration done via commit confirmed operation
+
+
+ comment + +
+ string +
+
+ Default:
"configured by junos_config"
+
+
The comment argument specifies a text string to be used when committing the configuration. If the confirm argument is set to False, this argument is silently ignored.
+
+
+ confirm + +
+ integer +
+
+ Default:
0
+
+
The confirm argument will configure a time out value in minutes for the commit to be confirmed before it is automatically rolled back. If the value for this argument is set to 0, the commit is confirmed immediately which is also the default behaviour.
+
+
+ confirm_commit + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
This argument will execute commit operation on remote device. It can be used to confirm a previous commit.
+
+
+ lines + +
+ list + / elements=string +
+
+ +
This argument takes a list of set or delete configuration lines to push into the remote device. Each line must start with either set or delete. This argument is mutually exclusive with the src argument.
+

aliases: commands
+
+
+ replace + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
The replace argument will instruct the remote device to replace the current configuration hierarchy with the one specified in the corresponding hierarchy of the source configuration loaded from this module.
+
Note this argument should be considered deprecated. To achieve the equivalent, set the update argument to replace. This argument will be removed in a future release. The replace and update argument is mutually exclusive.
+
+
+ rollback + +
+ integer +
+
+ +
The rollback argument instructs the module to rollback the current configuration to the identifier specified in the argument. If the specified rollback identifier does not exist on the remote device, the module will fail. To rollback to the most recent commit, set the rollback argument to 0.
+
+
+ src + +
+ path +
+
+ +
The src argument provides a path to the configuration file to load into the remote system. The path can either be a full system path to the configuration file if the value starts with / or relative to the root of the implemented role or playbook. This argument is mutually exclusive with the lines argument.
+
+
+ src_format + +
+ string +
+
+
    Choices: +
  • xml
  • +
  • set
  • +
  • text
  • +
  • json
  • +
+
+
The src_format argument specifies the format of the configuration found int src. If the src_format argument is not provided, the module will attempt to determine the format of the configuration file specified in src.
+
+
+ update + +
+ string +
+
+
    Choices: +
  • merge ←
  • +
  • override
  • +
  • replace
  • +
  • update
  • +
+
+
This argument will decide how to load the configuration data particularly when the candidate configuration and loaded configuration contain conflicting statements. Following are accepted values. merge combines the data in the loaded configuration with the candidate configuration. If statements in the loaded configuration conflict with statements in the candidate configuration, the loaded statements replace the candidate ones. override discards the entire candidate configuration and replaces it with the loaded configuration. replace substitutes each hierarchy level in the loaded configuration for the corresponding level. update is similar to the override option. The new configuration completely replaces the existing configuration. The difference comes when the configuration is later committed. This option performs a 'diff' between the new candidate configuration and the existing committed configuration. It then only notifies system processes responsible for the changed portions of the configuration, and only marks the actual configuration changes as 'changed'.
+
+
+ zeroize + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
The zeroize argument is used to completely sanitize the remote device configuration back to initial defaults. This argument will effectively remove all current configuration statements on the remote device.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Abbreviated commands are NOT idempotent, see `Network FAQ <../network/user_guide/faq.html>`_ + - Loading JSON-formatted configuration *json* is supported starting in Junos OS Release 16.1 onwards. + - Update ``override`` not currently compatible with ``set`` notation. + - Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. + - Recommended connection is ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - This module also works with ``local`` connections for legacy playbooks. + - For information on using CLI and netconf see the :ref:`Junos OS Platform Options guide ` + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` + - For more information on using Ansible to manage Juniper network devices see https://www.ansible.com/ansible-juniper. + + + +Examples +-------- + +.. code-block:: yaml + + - name: load configure file into device + junipernetworks.junos.junos_config: + src: srx.cfg + comment: update config + + - name: load configure lines into device + junipernetworks.junos.junos_config: + lines: + - set interfaces ge-0/0/1 unit 0 description "Test interface" + - set vlans vlan01 description "Test vlan" + comment: update config + + - name: Set routed VLAN interface (RVI) IPv4 address + junipernetworks.junos.junos_config: + lines: + - set vlans vlan01 vlan-id 1 + - set interfaces irb unit 10 family inet address 10.0.0.1/24 + - set vlans vlan01 l3-interface irb.10 + + - name: Check correctness of commit configuration + junipernetworks.junos.junos_config: + check_commit: true + + - name: rollback the configuration to id 10 + junipernetworks.junos.junos_config: + rollback: 10 + + - name: zero out the current configuration + junipernetworks.junos.junos_config: + zeroize: true + + - name: Set VLAN access and trunking + junipernetworks.junos.junos_config: + lines: + - set vlans vlan02 vlan-id 6 + - set interfaces ge-0/0/6.0 family ethernet-switching interface-mode access vlan + members vlan02 + - set interfaces ge-0/0/6.0 family ethernet-switching interface-mode trunk vlan + members vlan02 + + - name: confirm a previous commit + junipernetworks.junos.junos_config: + confirm_commit: true + + - name: for idempotency, use full-form commands + junipernetworks.junos.junos_config: + lines: + - set interfaces ge-0/0/1 unit 0 description "Test interface" + + - name: configurable backup path + junipernetworks.junos.junos_config: + src: srx.cfg + backup: true + backup_options: + filename: backup.cfg + dir_path: /home/user + + - name: Set description with timer to confirm commit + junipernetworks.junos.junos_config: + lines: + - set interfaces fxp0 description "wait for a commit confirmation for 3 minutes; otherwise, it will be rolled back." + confirm: 3 + + - name: Perform confirm commit + junipernetworks.junos.junos_config: + confirm_commit: true + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ backup_path + +
+ string +
+
when backup is true +
The full path to the backup file
+
+
Sample:
+
/playbooks/ansible/backup/config.2016-07-16@22:28:34
+
+
+ date + +
+ string +
+
when backup is true +
The date extracted from the backup file name
+
+
Sample:
+
2016-07-16
+
+
+ filename + +
+ string +
+
when backup is true and filename is not specified in backup options +
The name of the backup file
+
+
Sample:
+
junos01_config.2016-07-16@22:28:34
+
+
+ shortname + +
+ string +
+
when backup is true and filename is not specified in backup options +
The full path to the backup file excluding the timestamp
+
+
Sample:
+
/playbooks/ansible/backup/junos01_config
+
+
+ time + +
+ string +
+
when backup is true +
The time extracted from the backup file name
+
+
Sample:
+
22:28:34
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Peter Sprygada (@privateip) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_facts_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_facts_module.rst new file mode 100644 index 00000000..13509652 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_facts_module.rst @@ -0,0 +1,162 @@ +.. _junipernetworks.junos.junos_facts_module: + + +********************************* +junipernetworks.junos.junos_facts +********************************* + +**Collect facts from remote devices running Juniper Junos** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- Collects fact information from a remote device running the Junos operating system. By default, the module will collect basic fact information from the device to be included with the hostvars. Additional fact information can be collected based on the configured set of arguments. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.5.2) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ available_network_resources + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
When 'True' a list of network resources for which resource modules are available will be provided.
+
+
+ config_format + +
+ string +
+
+
    Choices: +
  • xml
  • +
  • text ←
  • +
  • set
  • +
  • json
  • +
+
+
The config_format argument specifies the format of the configuration when serializing output from the device. This argument is applicable only when config value is present in gather_subset. The config_format should be supported by the junos version running on device. This value is not applicable while fetching old style facts that is when ofacts value is present in value if gather_subset value. This option is valid only for gather_subset values.
+
+
+ gather_network_resources + +
+ list + / elements=string +
+
+ +
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 ! to specify that a specific subset should not be collected. Valid subsets are 'all', 'interfaces', 'lacp', 'lacp_interfaces', 'lag_interfaces', 'l2_interfaces', 'l3_interfaces', 'lldp_global', 'lldp_interfaces', 'vlans'.
+
+
+ gather_subset + +
+ list + / elements=string +
+
+ Default:
["min"]
+
+
When supplied, this argument will restrict the facts collected to a given subset. Possible values for this argument include all, hardware, config, interfaces and min. Can specify a list of values to include a larger subset. Values can also be used with an initial ! to specify that a specific subset should not be collected. To maintain backward compatibility old style facts can be retrieved by explicitly adding ofacts to value, this requires junos-eznc to be installed as a prerequisite. Valid value of gather_subset are default, hardware, config, interfaces, ofacts. If ofacts is present in the list it fetches the old style facts (fact keys without 'ansible_' prefix) and it requires junos-eznc library to be installed.
+
+
+ + +Notes +----- + +.. note:: + - Ensure *config_format* used to retrieve configuration from device is supported by junos version running on device. + - With *config_format = json*, configuration in the results will be a dictionary(and not a JSON string) + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. + - Recommended connection is ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - This module also works with ``local`` connections for legacy playbooks. + - For information on using CLI and netconf see the :ref:`Junos OS Platform Options guide ` + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` + - For more information on using Ansible to manage Juniper network devices see https://www.ansible.com/ansible-juniper. + + + +Examples +-------- + +.. code-block:: yaml + + - name: collect default set of facts + junipernetworks.junos.junos_facts: + + - name: collect default set of facts and configuration + junipernetworks.junos.junos_facts: + gather_subset: config + + - name: Gather legacy and resource facts + junipernetworks.junos.junos_facts: + gather_subset: all + gather_network_resources: all + + + + +Status +------ + + +Authors +~~~~~~~ + +- Nathaniel Case (@Qalthos) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_hostname_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_hostname_module.rst new file mode 100644 index 00000000..8b3e2c51 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_hostname_module.rst @@ -0,0 +1,419 @@ +.. _junipernetworks.junos.junos_hostname_module: + + +************************************ +junipernetworks.junos.junos_hostname +************************************ + +**Manage Hostname server configuration on Junos devices.** + + +Version added: 2.9.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages hostname configuration on devices running Junos. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
A dictionary of system Hostname configuration.
+
+
+ hostname + +
+ string +
+
+ +
Specify the hostname.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show system hostname.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • deleted
  • +
  • overridden
  • +
  • parsed
  • +
  • gathered
  • +
  • rendered
  • +
+
+
The state the configuration should be left in.
+
The states rendered, gathered and parsed does not perform any change on the device.
+
The state rendered will transform the configuration in config option to platform specific CLI commands which will be returned in the rendered key within the result. For state rendered active connection to remote host is not required.
+
The states merged, replaced and overridden have identical behaviour for this module.
+
The state 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 gathered key within the result.
+
The state parsed reads the configuration from running_config option and transforms it into JSON format as per the resource module parameters and the value is returned in the parsed key within the result. The value of running_config option should be the same format as the output of command show system hostname executed on device. For state parsed active connection to remote host is not required.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. + - See `the Junos OS Platform Options `_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # vagrant@vsrx# show system hostname + # + # [edit] + - name: Merge provided HOSTNAME configuration into running configuration. + junipernetworks.junos.junos_hostname: + config: + hostname: 'vsrx-18.4R1' + state: merged + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "hostname": "vsrx-18.4R1" + # }, + # "before": {}, + # "changed": true, + # "commands": [ + # " + # "vsrx-18.4R1" + # ] + # After state + # ----------- + # + # vagrant@vsrx-18.4R1# show system host-name + # host-name vsrx-18.4R1; + # + # Using replaced + # + # Before state + # ------------ + # + # vagrant@vsrx-18.4R1# show system host-name + # host-name vsrx-18.4R1; + # + # [edit] + - name: Replaced target config with provided config. + junipernetworks.junos.junos_hostname: + config: + hostname: 'vsrx-12' + state: replaced + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "hostname": "vsrx-12" + # }, + # "before": { + # "hostname": "vsrx-18.4R1" + # }, + # "changed": true, + # "commands": [ + # " + # "vsrx-12" + # ] + # After state + # ----------- + # + # vagrant@vsrx-18.4R1# show system host-name + # host-name vsrx-12; + # + # Using overridden + # + # Before state + # ------------ + # + # vagrant@vsrx-18.4R1# show system host-name + # host-name vsrx-18.4R1; + # + # [edit] + - name: Replaced target config with provided config. + junipernetworks.junos.junos_hostname: + config: + hostname: 'vsrx-12' + state: overridden + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "hostname": "vsrx-12" + # }, + # "before": { + # "hostname": "vsrx-18.4R1" + # }, + # "changed": true, + # "commands": [ + # " + # "vsrx-12" + # ] + # After state + # ----------- + # + # vagrant@vsrx-18.4R1# show system host-name + # host-name vsrx-12; + # + # Using deleted + # + # Before state + # ------------ + # + # vagrant@vsrx-18.4R1# show system host-name + # host-name vsrx-12; + # + - name: Delete running HOSTNAME global configuration + junipernetworks.junos.junos_hostname: + config: + state: deleted + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": {}, + # "before": { + # "hostname": "vsrx-12" + # }, + # "changed": true, + # "commands": [ + # " + # " + # ] + # After state + # ----------- + # + # vagrant@vsrx# show system ntp + # + # [edit] + # Using gathered + # + # Before state + # ------------ + # + # vagrant@vsrx-18.4R1# show system host-name + # host-name vsrx-12; + # + - name: Gather running HOSTNAME global configuration + junipernetworks.junos.junos_hostname: + state: gathered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "gathered": { + # "hostname": "vsrx-12", + # }, + # "changed": false, + # Using rendered + # + # Before state + # ------------ + # + - name: Render xml for provided facts. + junipernetworks.junos.junos_hostname: + config: + boot_server: '78.46.194.186' + state: rendered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "rendered": [ + # "" + # "78.46.194.186" + # ] + # + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # vsrx-18.4R1 + # + # + # + # + - name: Parse HOSTNAME running config + junipernetworks.junos.junos_hostname: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # + # "parsed": { + # "hostname": "vsrx-18.4R1" + # } + # + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['"<nc:host-name>78.46.194.186</nc:host-name></nc:system>"']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Rohit Thakur (@rohitthakur2590) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_interfaces_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_interfaces_module.rst new file mode 100644 index 00000000..0a5d41ae --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_interfaces_module.rst @@ -0,0 +1,1175 @@ +.. _junipernetworks.junos.junos_interfaces_module: + + +************************************** +junipernetworks.junos.junos_interfaces +************************************** + +**Junos Interfaces resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages the interfaces on Juniper Junos OS network devices. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
The provided configuration
+
+
+ description + +
+ string +
+
+ +
Interface description.
+
+
+ duplex + +
+ string +
+
+
    Choices: +
  • automatic
  • +
  • full-duplex
  • +
  • half-duplex
  • +
+
+
Interface link status. Applicable for Ethernet interfaces only, either in half duplex, full duplex or in automatic state which negotiates the duplex automatically.
+
+
+ enabled + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes ←
  • +
+
+
Administrative state of the interface.
+
Set the value to true to administratively enabled the interface or false to disable it.
+
+
+ hold_time + +
+ dictionary +
+
+ +
The hold time for given interface name.
+
+
+ down + +
+ integer +
+
+ +
The link down hold time in milliseconds.
+
+
+ up + +
+ integer +
+
+ +
The link up hold time in milliseconds.
+
+
+ mtu + +
+ integer +
+
+ +
MTU for a specific interface.
+
Applicable for Ethernet interfaces only.
+
+
+ name + +
+ string + / required +
+
+ +
Full name of interface, e.g. ge-0/0/0.
+
+
+ speed + +
+ string +
+
+ +
Interface link speed. Applicable for Ethernet interfaces only.
+
+
+ units + +
+ list + / elements=dictionary +
+
+ +
Specify Logical interfaces units.
+
+
+ description + +
+ string +
+
+ +
Specify logical interface description.
+
+
+ name + +
+ integer +
+
+ +
Specify interface unit number.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show interfaces.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • parsed
  • +
  • rendered
  • +
+
+
The state of the configuration after module completion
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 18.4R1. + - This module works with connection ``netconf``. See https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html + - The module examples uses callback plugin (stdout_callback = yaml) to generate task output in yaml format. + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + + # Before state: + # ------------- + # + # user@junos01# show interfaces + # ge-0/0/1 { + # description "test interface"; + # speed 1g; + # } + # fe-0/0/2 { + # vlan-tagging; + # unit 10 { + # vlan-id 10; + # } + # unit 11 { + # vlan-id 11; + # } + # } + # ge-0/0/3 { + # description "Configured by Ansible-3"; + # } + # fxp0 { + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + # lo0 { + # unit 0 { + # family inet { + # address 192.0.2.1/32; + # } + # } + # } + + - name: Merge provided configuration with device configuration (default operation + is merge) + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/1 + description: Configured by Ansible-1 + enabled: true + units: + - name: 0 + description: "This is logical intf unit0" + mtu: 1800 + - name: ge-0/0/2 + description: Configured by Ansible-2 + enabled: false + state: merged + + # Task Output + # ----------- + # + # before: + # - description: test interface + # enabled: true + # name: ge-0/0/1 + # speed: 1g + # - enabled: true + # name: fe-0/0/2 + # - description: Configured by Ansible-3 + # enabled: true + # name: ge-0/0/3 + # - enabled: true + # name: fxp0 + # - enabled: true + # name: lo0 + # commands: + # - ge-0/0/1 + # Configured by Ansible-118000 + # This is logical intf unit0ge-0/0/2 + # Configured by Ansible-2 + # after: + # - description: Configured by Ansible-1 + # enabled: true + # mtu: 1800 + # name: ge-0/0/1 + # speed: 1g + # units: + # - description: This is logical intf unit0 + # name: 0 + # - enabled: true + # name: fe-0/0/2 + # - description: Configured by Ansible-2 + # enabled: false + # name: ge-0/0/2 + # - description: Configured by Ansible-3 + # enabled: true + # name: ge-0/0/3 + # - enabled: true + # name: fxp0 + # - enabled: true + # name: lo0 + + # After state: + # ------------ + # + # user@junos01# show interfaces + # ge-0/0/1 { + # description "Configured by Ansible-1"; + # speed 1g; + # mtu 1800; + # unit 0 { + # description "This is logical intf unit0"; + # } + # } + # fe-0/0/2 { + # vlan-tagging; + # unit 10 { + # vlan-id 10; + # } + # unit 11 { + # vlan-id 11; + # } + # } + # ge-0/0/2 { + # description "Configured by Ansible-2"; + # disable; + # } + # ge-0/0/3 { + # description "Configured by Ansible-3"; + # } + # fxp0 { + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + # lo0 { + # unit 0 { + # family inet { + # address 192.0.2.1/32; + # } + # } + # } + + # Using deleted + + # Before state: + # ------------- + # + # ge-0/0/1 { + # description "Configured by Ansible-1"; + # speed 1g; + # mtu 1800; + # unit 0 { + # description "This is logical intf unit0"; + # } + # } + # fe-0/0/2 { + # vlan-tagging; + # unit 10 { + # vlan-id 10; + # } + # unit 11 { + # vlan-id 11; + # } + # } + # ge-0/0/2 { + # description "Configured by Ansible-2"; + # disable; + # } + # ge-0/0/3 { + # description "Configured by Ansible-3"; + # } + # fxp0 { + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + # lo0 { + # unit 0 { + # family inet { + # address 192.0.2.1/32; + # } + # } + # } + + - name: "Delete given options for the interface (Note: This won't delete the interface itself if any other values are configured for interface)" + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/1 + description: Configured by Ansible-1 + speed: 1g + mtu: 1800 + - name: ge-0/0/2 + description: Configured by Ansible -2 + state: deleted + + # Task Output + # ----------- + # + # before: + # - description: Configured by Ansible-1 + # enabled: true + # mtu: 1800 + # name: ge-0/0/1 + # speed: 1g + # units: + # - description: This is logical intf unit0 + # name: 0 + # - enabled: true + # name: fe-0/0/2 + # - description: Configured by Ansible-2 + # enabled: false + # name: ge-0/0/2 + # - description: Configured by Ansible-3 + # enabled: true + # name: ge-0/0/3 + # - enabled: true + # name: fxp0 + # - enabled: true + # name: lo0 + # commands: + # - + # ge-0/0/1 + # + # + # 0ge-0/0/2 + # + # + # + # after: + # - enabled: true + # name: ge-0/0/1 + # - enabled: true + # name: fe-0/0/2 + # - description: Configured by Ansible-3 + # enabled: true + # name: ge-0/0/3 + # - enabled: true + # name: fxp0 + # - enabled: true + # name: lo0 + + # After state: + # ------------ + # + # user@junos01# show interfaces + # ge-0/0/1 { + # unit 0; + # } + # fe-0/0/2 { + # vlan-tagging; + # unit 10 { + # vlan-id 10; + # } + # unit 11 { + # vlan-id 11; + # } + # } + # ge-0/0/3 { + # description "Configured by Ansible-3"; + # } + # fxp0 { + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + # lo0 { + # unit 0 { + # family inet { + # address 192.0.2.1/32; + # } + # } + # } + + # Using overridden + + # Before state: + # ------------- + # + # user@junos01# show interfaces + # ge-0/0/1 { + # unit 0; + # } + # fe-0/0/2 { + # vlan-tagging; + # unit 10 { + # vlan-id 10; + # } + # unit 11 { + # vlan-id 11; + # } + # } + # ge-0/0/3 { + # description "Configured by Ansible-3"; + # } + # fxp0 { + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + # lo0 { + # unit 0 { + # family inet { + # address 192.0.2.1/32; + # } + # } + # } + + - name: Override device configuration of all interfaces with provided configuration + junipernetworks.junos.junos_interfaces: + config: + - enabled: true + name: ge-0/0/1 + - name: fe-0/0/2 + description: Configured by Ansible-2 + enabled: false + mtu: 2800 + - description: Updated by Ansible-3 + enabled: true + name: ge-0/0/3 + - enabled: true + name: fxp0 + - enabled: true + name: lo0 + state: overridden + + # Task Output + # ----------- + # + # before: + # - enabled: true + # name: ge-0/0/1 + # - enabled: true + # name: fe-0/0/2 + # - description: Configured by Ansible-3 + # enabled: true + # name: ge-0/0/3 + # - enabled: true + # name: fxp0 + # - enabled: true + # name: lo0 + # commands: + # - + # ge-0/0/1 + # + # + # fe-0/0/2 + # + # + # ge-0/0/3 + # + # + # fxp0 + # + # + # lo0 + # + # + # ge-0/0/1 + # fe-0/0/2 + # Configured by Ansible-2 + # 2800 + # ge-0/0/3Updated by Ansible-3 + # fxp0 + # lo0 + # after: + # - enabled: true + # name: ge-0/0/1 + # - description: Configured by Ansible-2 + # enabled: false + # mtu: 2800 + # name: fe-0/0/2 + # - description: Updated by Ansible-3 + # enabled: true + # name: ge-0/0/3 + # - enabled: true + # name: fxp0 + # - enabled: true + # name: lo0 + + # After state: + # ------------ + # + # user@junos01# show interfaces + # ge-0/0/1 { + # unit 0; + # } + # fe-0/0/2 { + # description "Configured by Ansible-2"; + # disable; + # vlan-tagging; + # mtu 2800; + # unit 10 { + # vlan-id 10; + # } + # unit 11 { + # vlan-id 11; + # } + # } + # ge-0/0/3 { + # description "Updated by Ansible-3"; + # } + # fxp0 { + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + # lo0 { + # unit 0 { + # family inet { + # address 192.0.2.1/32; + # } + # } + # } + + + # Using replaced + + # Before state: + # ------------- + # + # user@junos01# show interfaces + # ge-0/0/1 { + # unit 0; + # } + # fe-0/0/2 { + # description "Configured by Ansible-2"; + # disable; + # vlan-tagging; + # mtu 2800; + # unit 10 { + # vlan-id 10; + # } + # unit 11 { + # vlan-id 11; + # } + # } + # ge-0/0/3 { + # description "Updated by Ansible-3"; + # } + # fxp0 { + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + # lo0 { + # unit 0 { + # family inet { + # address 192.0.2.1/32; + # } + # } + # } + + - name: Replace device configuration of listed interfaces with provided configuration + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/2 + description: Configured by Ansible-2 + enabled: false + mtu: 2800 + - name: ge-0/0/3 + description: Configured by Ansible-3 + state: replaced + + # Task Output + # ----------- + # + # before: + # - enabled: true + # name: ge-0/0/1 + # - description: Configured by Ansible-2 + # enabled: false + # mtu: 2800 + # name: fe-0/0/2 + # - description: Updated by Ansible-3 + # enabled: true + # name: ge-0/0/3 + # - enabled: true + # name: fxp0 + # - enabled: true + # name: lo0 + # commands: + # - + # ge-0/0/2 + # + # + # ge-0/0/3 + # + # ge-0/0/2 + # Configured by Ansible-22800 + # ge-0/0/3Configured by Ansible-3 + # after: + # - enabled: true + # name: ge-0/0/1 + # - description: Configured by Ansible-2 + # enabled: false + # mtu: 2800 + # name: fe-0/0/2 + # - description: Configured by Ansible-2 + # enabled: false + # mtu: 2800 + # name: ge-0/0/2 + # - description: Configured by Ansible-3 + # enabled: true + # name: ge-0/0/3 + # - enabled: true + # name: fxp0 + # - enabled: true + # name: lo0 + + # After state: + # ------------ + # + # user@junos01# show interfaces + # ge-0/0/1 { + # unit 0; + # } + # fe-0/0/2 { + # description "Configured by Ansible-2"; + # disable; + # vlan-tagging; + # mtu 2800; + # unit 10 { + # vlan-id 10; + # } + # unit 11 { + # vlan-id 11; + # } + # } + # ge-0/0/2 { + # description "Configured by Ansible-2"; + # disable; + # mtu 2800; + # } + # ge-0/0/3 { + # description "Configured by Ansible-3"; + # } + # fxp0 { + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + # lo0 { + # unit 0 { + # family inet { + # address 192.0.2.1/32; + # } + # } + # } + + # Using gathered + + # Before state: + # ------------ + # + # vagrant@vsrx# show interfaces + # ge-0/0/1 { + # unit 0; + # } + # fe-0/0/2 { + # description "Configured by Ansible-2"; + # disable; + # vlan-tagging; + # mtu 2800; + # unit 10 { + # vlan-id 10; + # } + # unit 11 { + # vlan-id 11; + # } + # } + # ge-0/0/2 { + # description "Configured by Ansible-2"; + # disable; + # mtu 2800; + # } + # ge-0/0/3 { + # description "Configured by Ansible-3"; + # } + # fxp0 { + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + # lo0 { + # unit 0 { + # family inet { + # address 192.0.2.1/32; + # } + # } + # } + + - name: Gather junos interfaces as in given arguments + junipernetworks.junos.junos_interfaces: + state: gathered + + # Task Output + # ----------- + # + # gathered: + # - enabled: true + # name: ge-0/0/1 + # - description: Configured by Ansible-2 + # enabled: false + # mtu: 2800 + # name: fe-0/0/2 + # - description: Configured by Ansible-2 + # enabled: false + # mtu: 2800 + # name: ge-0/0/2 + # - description: Configured by Ansible-3 + # enabled: true + # name: ge-0/0/3 + # - enabled: true + # name: fxp0 + # - enabled: true + # name: lo0 + + # Using parsed + + # parsed.cfg + # ------------ + # + # + # + # + # + # + # ge-0/0/1 + # Configured by Ansible + # + # 100m + # 1024 + # + # 2000 + # 2200 + # + # full-duplex + # + # 0 + # + # + # access + # + # vlan100 + # + # + # + # + # + # + # + # + + # - name: Convert interfaces config to structured data without connecting to the appliance + # junipernetworks.junos.junos_interfaces: + # running_config: "{{ lookup('file', './parsed.cfg') }}" + # state: parsed + + # Task Output + # ----------- + # + # parsed: + # - description: Configured by Ansible + # duplex: full-duplex + # enabled: false + # hold_time: + # down: 2200 + # up: 2000 + # mtu: 1024 + # name: ge-0/0/1 + # speed: 100m + + # Using rendered + + - name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/2 + description: Configured by Ansible + mtu: 2048 + speed: 20m + hold_time: + up: 3200 + down: 3200 + state: rendered + + # Task Output + # ----------- + # + # rendered: + # + # ge-0/0/2 + # Configured by Ansible + # 20m + # 2048 + # + # 3200 + # 3200 + # + # + # " + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ list +
+
when changed +
The configuration as structured data after module completion.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ list +
+
always +
The configuration as structured data prior to module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ gathered + +
+ list +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ list +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ list +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">']
+
+
+ xml + +
+ list +
+
always +
The set of xml rpc payload pushed to the remote device.
+
+
Sample:
+
['<?xml version="1.0" encoding="UTF-8"?> <rpc-reply message-id="urn:uuid:0cadb4e8-5bba-47f4-986e-72906227007f"> <configuration changed-seconds="1590139550" changed-localtime="2020-05-22 09:25:50 UTC"> <interfaces> <interface> <name>ge-0/0/1</name> <description>Configured by Ansible</description> <disable/> <speed>100m</speed> <mtu>1024</mtu> <hold-time> <up>2000</up> <down>2200</down> </hold-time> <link-mode>full-duplex</link-mode> <unit> <name>0</name> <family> <ethernet-switching> <interface-mode>access</interface-mode> <vlan> <members>vlan100</members> </vlan> </ethernet-switching> </family> </unit> </interface> </interfaces> </configuration> </rpc-reply>', 'xml 2', 'xml 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ganesh Nalawade (@ganeshrn) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_l2_interfaces_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_l2_interfaces_module.rst new file mode 100644 index 00000000..b6f422db --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_l2_interfaces_module.rst @@ -0,0 +1,1213 @@ +.. _junipernetworks.junos.junos_l2_interfaces_module: + + +***************************************** +junipernetworks.junos.junos_l2_interfaces +***************************************** + +**L2 interfaces resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module provides declarative management of a Layer-2 interface on Juniper JUNOS devices. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
A dictionary of Layer-2 interface options
+
+
+ access + +
+ dictionary +
+
+ +
Configure the interface as a Layer 2 access mode.
+
+
+ vlan + +
+ string +
+
+ +
Configure the access VLAN ID.
+
+
+ enhanced_layer + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
True if your device has Enhanced Layer 2 Software (ELS). If the l2 configuration is under interface-mode the value is True else if the l2 configuration is under port-mode value is False
+
+
+ name + +
+ string + / required +
+
+ +
Full name of interface, e.g. ge-0/0/1.
+
+
+ trunk + +
+ dictionary +
+
+ +
Configure the interface as a Layer 2 trunk mode.
+
+
+ allowed_vlans + +
+ list + / elements=string +
+
+ +
List of VLANs to be configured in trunk port. It's used as the VLAN range to ADD or REMOVE from the trunk.
+
+
+ native_vlan + +
+ string +
+
+ +
Native VLAN to be configured in trunk port. It is used as the trunk native VLAN ID.
+
+
+ unit + +
+ integer +
+
+ +
Logical interface number. Value of unit should be of type integer.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show interfaces.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • parsed
  • +
  • rendered
  • +
+
+
The state of the configuration after module completion
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 18.4R1. + - This module works with connection ``netconf``. See https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html + - The module examples uses callback plugin (stdout_callback = yaml) to generate task output in yaml format. + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + + # Before state: + # ------------- + # + # ansible@junos01# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/3 { + # unit 0 { + # family ethernet-switching { + # interface-mode access; + # } + # } + # } + # ge-0/0/4 { + # unit 0 { + # family ethernet-switching { + # interface-mode access; + # } + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + - name: Merge provided configuration with device configuration + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/3 + access: + vlan: v101 + - name: ge-0/0/4 + trunk: + allowed_vlans: + - vlan30 + native_vlan: 50 + state: merged + + # Task Output + # ----------- + # + # before: + # - enhanced_layer: true + # name: ge-0/0/3 + # unit: 0 + # - enhanced_layer: true + # name: ge-0/0/4 + # unit: 0 + # commands: + # - + # + # ge-0/0/3 + # + # 0 + # + # + # access + # + # v101 + # + # + # + # + # + # + # ge-0/0/4 + # + # 0 + # + # + # trunk + # + # vlan30 + # + # + # + # + # 50 + # + # + # after: + # - access: + # vlan: v101 + # enhanced_layer: true + # name: ge-0/0/3 + # unit: 0 + # - enhanced_layer: true + # name: ge-0/0/4 + # trunk: + # allowed_vlans: + # - vlan30 + # native_vlan: '50' + # unit: 0 + + # After state: + # ------------ + # + # user@junos01# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/3 { + # unit 0 { + # family ethernet-switching { + # interface-mode access; + # vlan { + # members v101; + # } + # } + # } + # } + # ge-0/0/4 { + # native-vlan-id 50; + # unit 0 { + # family ethernet-switching { + # interface-mode trunk; + # vlan { + # members vlan30; + # } + # } + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + + # Using overridden + + # Before state: + # ------------- + # ansible@junos01# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/3 { + # unit 0 { + # family ethernet-switching { + # interface-mode access; + # vlan { + # members v101; + # } + # } + # } + # } + # ge-0/0/4 { + # native-vlan-id 50; + # unit 0 { + # family ethernet-switching { + # interface-mode trunk; + # vlan { + # members vlan30; + # } + # } + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + - name: Override provided configuration with device configuration + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/4 + trunk: + allowed_vlans: + - v101 + native_vlan: 30 + state: overridden + + # Task Output + # ----------- + # + # before: + # - access: + # vlan: v101 + # enhanced_layer: true + # name: ge-0/0/3 + # unit: 0 + # - enhanced_layer: true + # name: ge-0/0/4 + # trunk: + # allowed_vlans: + # - vlan30 + # native_vlan: '50' + # unit: 0 + # commands: + # - + # + # ge-0/0/4 + # + # 0 + # + # + # + # + # + # + # + # + # + # + # ge-0/0/4 + # + # 0 + # + # + # trunk + # + # v101 + # + # + # + # + # 30 + # + # + # ge-0/0/3 + # + # 0 + # + # + # + # + # + # + # + # + # + # + # after: + # - enhanced_layer: true + # name: ge-0/0/4 + # trunk: + # allowed_vlans: + # - v101 + # native_vlan: '30' + # unit: 0 + + # After state: + # ------------ + # user@junos01# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/3 { + # unit 0 { + # family ethernet-switching; + # } + # } + # ge-0/0/4 { + # native-vlan-id 30; + # unit 0 { + # family ethernet-switching { + # interface-mode trunk; + # vlan { + # members v101; + # } + # } + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + # Using replaced + + # Before state: + # ------------- + # + # ansible@junos01# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/3 { + # unit 0 { + # family ethernet-switching; + # } + # } + # ge-0/0/4 { + # native-vlan-id 30; + # unit 0 { + # family ethernet-switching { + # interface-mode trunk; + # vlan { + # members v101; + # } + # } + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + - name: Replace provided configuration with device configuration + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/3 + access: + vlan: v101 + - name: ge-0/0/4 + trunk: + allowed_vlans: + - vlan30 + native_vlan: 50 + state: replaced + + # Task Output + # ----------- + # + # before: + # - enhanced_layer: true + # name: ge-0/0/4 + # trunk: + # allowed_vlans: + # - v101 + # native_vlan: '30' + # unit: 0 + # commands: + # - + # + # ge-0/0/4 + # + # 0 + # + # + # + # + # + # + # + # + # + # + # ge-0/0/3 + # + # 0 + # + # + # access + # + # v101 + # + # + # + # + # + # + # ge-0/0/4 + # + # 0 + # + # + # trunk + # + # vlan30 + # + # + # + # + # 50 + # + # + # after: + # - access: + # vlan: v101 + # enhanced_layer: true + # name: ge-0/0/3 + # unit: 0 + # - enhanced_layer: true + # name: ge-0/0/4 + # trunk: + # allowed_vlans: + # - vlan30 + # native_vlan: '50' + # unit: 0 + + # After state: + # ------------ + # + # user@junos01# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/3 { + # unit 0 { + # family ethernet-switching { + # interface-mode access; + # vlan { + # members v101; + # } + # } + # } + # } + # ge-0/0/4 { + # native-vlan-id 50; + # unit 0 { + # family ethernet-switching { + # interface-mode trunk; + # vlan { + # members vlan30; + # } + # } + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + # Using deleted + + # Before state: + # ------------- + # + # ansible@junos01# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/3 { + # unit 0 { + # family ethernet-switching { + # interface-mode access; + # vlan { + # members v101; + # } + # } + # } + # } + # ge-0/0/4 { + # native-vlan-id 50; + # unit 0 { + # family ethernet-switching { + # interface-mode trunk; + # vlan { + # members vlan30; + # } + # } + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + - name: "Delete L2 attributes of given interfaces (Note: This won't delete the + interface itself)." + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + state: deleted + + # Task Output + # ----------- + # + # before: + # - access: + # vlan: v101 + # enhanced_layer: true + # name: ge-0/0/3 + # unit: 0 + # - enhanced_layer: true + # name: ge-0/0/4 + # trunk: + # allowed_vlans: + # - vlan30 + # native_vlan: '50' + # unit: 0 + # commands: + # - + # + # ge-0/0/3 + # + # 0 + # + # + # + # + # + # + # + # + # + # + # after: + # - enhanced_layer: true + # name: ge-0/0/4 + # trunk: + # allowed_vlans: + # - vlan30 + # native_vlan: '50' + # unit: 0 + + # After state: + # ------------ + # + # ansible@junos01# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/3 { + # unit 0 { + # family ethernet-switching; + # } + # } + # ge-0/0/4 { + # native-vlan-id 50; + # unit 0 { + # family ethernet-switching { + # interface-mode trunk; + # vlan { + # members vlan30; + # } + # } + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + # Using gathered + + # Before state: + # ------------- + # + # user@junos01# show interfaces + # ge-0/0/1 { + # description "Configured by Ansible"; + # disable; + # speed 100m; + # mtu 1024; + # hold-time up 2000 down 2200; + # link-mode full-duplex; + # unit 0 { + # family ethernet-switching { + # interface-mode access; + # vlan { + # members vlan100; + # } + # } + # } + # } + # ge-0/0/2 { + # description "Configured by Ansible"; + # native-vlan-id 400; + # speed 10m; + # mtu 2048; + # hold-time up 3000 down 3200; + # unit 0 { + # family ethernet-switching { + # interface-mode trunk; + # vlan { + # members [ vlan200 vlan300 ]; + # } + # } + # } + # } + # em1 { + # description TEST; + # } + # fxp0 { + # description ANSIBLE; + # speed 1g; + # link-mode automatic; + # unit 0 { + # family inet { + # address 10.8.38.38/24; + # } + # } + # } + + - name: Gather junos layer 2 interfaces facts + junipernetworks.junos.junos_l2_interfaces: + state: gathered + + # Task Output + # ----------- + # + # gathered: + # - access: + # vlan: vlan100 + # enhanced_layer: true + # name: ge-0/0/1 + # unit: 0 + # - enhanced_layer: true + # name: ge-0/0/2 + # trunk: + # allowed_vlans: + # - vlan200 + # - vlan300 + # native_vlan: '400' + # unit: 0 + + # Using parsed + + # parsed.cfg + # ------------ + # + # + # + # + # + # + # ge-0/0/1 + # Configured by Ansible + # + # 100m + # 1024 + # + # 2000 + # 2200 + # + # full-duplex + # + # 0 + # + # + # access + # + # vlan100 + # + # + # + # + # + # + # + # + + - name: Convert interfaces config to argspec without connecting to the appliance + junipernetworks.junos.junos_l2_interfaces: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + + # Task Output + # ----------- + # + # parsed: + # - access: + # vlan: vlan100 + # enhanced_layer: true + # name: ge-0/0/1 + # unit: 0 + # - enhanced_layer: true + # name: ge-0/0/2 + # trunk: + # allowed_vlans: + # - vlan200 + # - vlan300 + # native_vlan: '400' + # unit: 0 + + # Using rendered + + - name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/1 + access: + vlan: vlan100 + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan200 + - vlan300 + native_vlan: '400' + state: rendered + + # Task Output + # ----------- + # + # "rendered": " + # + # ge-0/0/1 + # + # 0 + # + # + # access + # + # vlan100 + # + # + # + # + # + # + # ge-0/0/2 + # + # 0 + # + # + # trunk + # + # vlan200 + # vlan300 + # + # + # + # + # 400 + # + # " + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ list +
+
when changed +
The configuration as structured data after module completion.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ list +
+
always +
The configuration as structured data prior to module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:interfaces xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:interface> <nc:name>ge-0/0/1</nc:name> <nc:unit> <nc:name>0</nc:name> <nc:family> <nc:ethernet-switching> <nc:interface-mode>access</nc:interface-mode> <nc:vlan> <nc:members>vlan100</nc:members> </nc:vlan> </nc:ethernet-switching> </nc:family> </nc:unit> </nc:interface> <nc:interface> <nc:name>ge-0/0/2</nc:name> <nc:unit> <nc:name>0</nc:name> <nc:family> <nc:ethernet-switching> <nc:interface-mode>trunk</nc:interface-mode> <nc:vlan> <nc:members>vlan200</nc:members> <nc:members>vlan300</nc:members> </nc:vlan> </nc:ethernet-switching> </nc:family> </nc:unit> <nc:native-vlan-id>400</nc:native-vlan-id> </nc:interface> </nc:interfaces>', 'xml 2', 'xml 3']
+
+
+ gathered + +
+ list +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ list +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ list +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ganesh Nalawade (@ganeshrn) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_l3_interfaces_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_l3_interfaces_module.rst new file mode 100644 index 00000000..2048506f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_l3_interfaces_module.rst @@ -0,0 +1,1175 @@ +.. _junipernetworks.junos.junos_l3_interfaces_module: + + +***************************************** +junipernetworks.junos.junos_l3_interfaces +***************************************** + +**L3 interfaces resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module provides declarative management of a Layer 3 interface on Juniper JUNOS devices + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
A dictionary of Layer 3 interface options
+
+
+ ipv4 + +
+ list + / elements=dictionary +
+
+ +
IPv4 addresses to be set for the Layer 3 logical interface mentioned in name option. The address format is <ipv4 address>/<mask>. The mask is number in range 0-32 for example, 192.0.2.1/24, or dhcp to query DHCP for an IP address
+
+
+ address + +
+ string +
+
+ +
IPv4 address to be set for the specific interface
+
+
+ ipv6 + +
+ list + / elements=dictionary +
+
+ +
IPv6 addresses to be set for the Layer 3 logical interface mentioned in name option. The address format is <ipv6 address>/<mask>, the mask is number in range 0-128 for example, 2001:db8:2201:1::1/64 or auto-config to use SLAAC
+
+
+ address + +
+ string +
+
+ +
IPv6 address to be set for the specific interface
+
+
+ mtu + +
+ integer +
+
+ +
Protocol family maximum transmission unit.
+
+
+ name + +
+ string + / required +
+
+ +
Full name of interface, e.g. ge-0/0/1
+
+
+ unit + +
+ integer +
+
+ Default:
0
+
+
Logical interface number. Value of unit should be of type integer
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show interfaces.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • rendered
  • +
  • parsed
  • +
+
+
The state of the configuration after module completion
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - Tested against JunOS v18.4R1 + - This module works with connection ``netconf``. See https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html + - The module examples uses callback plugin (stdout_callback = yaml) to generate task output in yaml format. + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + + # Before state + # ------------ + # + # admin# show interfaces + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + + - name: Merge provided configuration with device configuration + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-0/0/1 + ipv4: + - address: 192.168.1.10/24 + ipv6: + - address: 8d8d:8d01::1/64 + - name: ge-0/0/2 + ipv4: + - address: dhcp + state: merged + + # Task Output + # ----------- + # + # before: + # - ipv4: + # - address: dhcp + # name: fxp0 + # unit: '0' + # commands: + # - + # + # ge-0/0/1 + # + # 0 + # + # + # + # 192.168.1.10/24 + # + # + # + # + # + # + # 8d8d:8d01::1/64 + # + # + # + # + # + # + # ge-0/0/2 + # + # 0 + # + # + # + # + # + # + # + # + # after: + # - ipv4: + # - address: 192.168.1.10/24 + # ipv6: + # - address: 8d8d:8d01::1/64 + # name: ge-0/0/1 + # unit: '0' + # - ipv4: + # - address: dhcp + # name: ge-0/0/2 + # unit: '0' + # - ipv4: + # - address: dhcp + # name: fxp0 + # unit: '0' + + # After state: + # ------------ + # + # admin# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet { + # address 192.168.1.10/24; + # } + # family inet6 { + # address 8d8d:8d01::1/64; + # } + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + + # Using overridden + + # Before state + # ------------ + # + # admin# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet { + # address 192.168.1.10/24; + # } + # family inet6 { + # address 8d8d:8d01::1/64; + # } + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # } + # } + + - name: Override provided configuration with device configuration + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-0/0/1 + ipv4: + - address: 192.168.1.10/24 + - ipv4: + - address: dhcp + name: fxp0 + unit: '0' + state: overridden + + # Task Output + # ----------- + # + # before: + # - ipv4: + # - address: 192.168.1.10/24 + # ipv6: + # - address: 8d8d:8d01::1/64 + # name: ge-0/0/1 + # unit: '0' + # - ipv4: + # - address: dhcp + # name: ge-0/0/2 + # unit: '0' + # - ipv4: + # - address: dhcp + # name: fxp0 + # unit: '0' + # commands: + # - + # + # ge-0/0/1 + # + # 0 + # + # + # + # + # + # + # + # + # + # + # + # ge-0/0/2 + # + # 0 + # + # + # + # + # + # + # + # + # + # + # + # fxp0 + # + # 0 + # + # + # + # + # + # + # + # + # + # + # + # ge-0/0/1 + # + # 0 + # + # + # + # 192.168.1.10/24 + # + # + # + # + # + # + # fxp0 + # + # 0 + # + # + # + # + # + # + # + # + # after: + # - ipv4: + # - address: 192.168.1.10/24 + # name: ge-0/0/1 + # unit: '0' + # - name: ge-0/0/2 + # unit: '0' + # - ipv4: + # - address: dhcp + # name: fxp0 + # unit: '0' + + # After state: + # ------------ + # + # admin# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet { + # address 192.168.1.10/24; + # } + # family inet6; + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + # Using replaced + + # Before state + # ------------ + # + # admin# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet { + # address 192.168.1.10/24; + # } + # family inet6; + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + - name: Replace provided configuration with device configuration + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-0/0/1 + ipv4: + - address: 192.168.1.10/24 + ipv6: + - address: 8d8d:8d01::1/64 + - name: ge-0/0/2 + ipv4: + - address: dhcp + state: replaced + + # Task Output + # ----------- + # + # before: + # - ipv4: + # - address: 192.168.1.10/24 + # name: ge-0/0/1 + # unit: '0' + # - name: ge-0/0/2 + # unit: '0' + # - ipv4: + # - address: dhcp + # name: fxp0 + # unit: '0' + # commands: + # - + # + # ge-0/0/1 + # + # 0 + # + # + # + # + # + # + # + # + # + # + # + # ge-0/0/2 + # + # 0 + # + # + # + # + # + # + # + # + # + # ge-0/0/1 + # + # 0 + # + # + # + # 192.168.1.10/24 + # + # + # + # + # + # + # 8d8d:8d01::1/64 + # + # + # + # + # + # + # ge-0/0/2 + # + # 0 + # + # + # + # + # + # + # + # + # after: + # - ipv4: + # - address: 192.168.1.10/24 + # ipv6: + # - address: 8d8d:8d01::1/64 + # name: ge-0/0/1 + # unit: '0' + # - ipv4: + # - address: dhcp + # name: ge-0/0/2 + # unit: '0' + # - ipv4: + # - address: dhcp + # name: fxp0 + # unit: '0' + + # After state: + # ------------ + # + # admin# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet { + # address 192.168.1.10/24; + # } + # family inet6 { + # address 8d8d:8d01::1/64; + # } + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + # Using deleted + + # Before state: + # ------------- + # + # admin# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet { + # address 192.168.1.10/24; + # } + # family inet6 { + # address 8d8d:8d01::1/64; + # } + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + - name: Delete L3 logical interface + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + state: deleted + + # Task Output + # ----------- + # + # before: + # - ipv4: + # - address: 192.168.1.10/24 + # ipv6: + # - address: 8d8d:8d01::1/64 + # name: ge-0/0/1 + # unit: '0' + # - ipv4: + # - address: dhcp + # name: ge-0/0/2 + # unit: '0' + # - ipv4: + # - address: dhcp + # name: fxp0 + # unit: '0' + # commands: + # - + # + # ge-0/0/1 + # + # 0 + # + # + # + # + # + # + # + # + # + # + # + # ge-0/0/2 + # + # 0 + # + # + # + # + # + # + # + # + # + # + # + # after: + # - name: ge-0/0/1 + # unit: '0' + # - name: ge-0/0/2 + # unit: '0' + # - ipv4: + # - address: dhcp + # name: fxp0 + # unit: '0' + + # After state: + # ------------ + # + # admin# show interfaces + # ge-0/0/1 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # ge-0/0/2 { + # unit 0 { + # family inet; + # family inet6; + # } + # } + # fxp0 { + # enable; + # unit 0 { + # family inet { + # dhcp; + # } + # family inet6; + # } + # } + + # Using gathered + + # Before state: + # ------------ + # + # user@junos01# show interfaces + # ge-0/0/1 { + # description "Configured by Ansible"; + # disable; + # speed 100m; + # mtu 1024; + # hold-time up 2000 down 2200; + # link-mode full-duplex; + # unit 0 { + # family ethernet-switching { + # interface-mode access; + # vlan { + # members vlan100; + # } + # } + # } + # } + # ge-0/0/2 { + # description "Configured by Ansible"; + # native-vlan-id 400; + # speed 10m; + # mtu 2048; + # hold-time up 3000 down 3200; + # unit 0 { + # family ethernet-switching { + # interface-mode trunk; + # vlan { + # members [ vlan200 vlan300 ]; + # } + # } + # } + # } + # ge-1/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.1/24; + # address 10.200.16.20/24; + # } + # family inet6; + # } + # } + # ge-2/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.2/24; + # address 10.200.16.21/24; + # } + # family inet6; + # } + # } + # ge-3/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.3/24; + # address 10.200.16.22/24; + # } + # family inet6; + # } + # } + # em1 { + # description TEST; + # } + # fxp0 { + # description ANSIBLE; + # speed 1g; + # link-mode automatic; + # unit 0 { + # family inet { + # address 10.8.38.38/24; + # } + # } + # } + + - name: Gather layer3 interfaces facts + junipernetworks.junos.junos_l3_interfaces: + state: gathered + + # Task Output + # ----------- + # + # gathered: + # - ipv4: + # - address: 192.168.100.1/24 + # - address: 10.200.16.20/24 + # name: ge-1/0/0 + # unit: '0' + # - ipv4: + # - address: 192.168.100.2/24 + # - address: 10.200.16.21/24 + # name: ge-2/0/0 + # unit: '0' + # - ipv4: + # - address: 192.168.100.3/24 + # - address: 10.200.16.22/24 + # name: ge-3/0/0 + # unit: '0' + # - ipv4: + # - address: 10.8.38.38/24 + # name: fxp0 + # unit: '0' + + # Using parsed + + # parsed.cfg + # ------------ + # + # + # + # + # + # + # ge-1/0/0 + # + # 0 + # + # + #
+ # 192.168.100.1/24 + #
+ #
+ # 10.200.16.20/24 + #
+ #
+ # + #
+ #
+ #
+ # + # ge-2/0/0 + # + # 0 + # + # + #
+ # 192.168.100.2/24 + #
+ #
+ # 10.200.16.21/24 + #
+ #
+ # + #
+ #
+ #
+ #
+ #
+ #
+ + # - name: Convert interfaces config to argspec without connecting to the appliance + # junipernetworks.junos.junos_l3_interfaces: + # running_config: "{{ lookup('file', './parsed.cfg') }}" + # state: parsed + + # Task Output + # ----------- + # + # parsed: + # - ipv4: + # - address: 192.168.100.1/24 + # - address: 10.200.16.20/24 + # name: ge-1/0/0 + # unit: '0' + # - ipv4: + # - address: 192.168.100.2/24 + # - address: 10.200.16.21/24 + # name: ge-2/0/0 + # unit: '0' + + # Using rendered + + - name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-1/0/0 + ipv4: + - address: 192.168.100.1/24 + - address: 10.200.16.20/24 + unit: 0 + - name: ge-2/0/0 + ipv4: + - address: 192.168.100.2/24 + - address: 10.200.16.21/24 + unit: 0 + state: rendered + + # Task Output + # ----------- + # + # "rendered": " + # + # ge-1/0/0 + # + # 0 + # + # + # + # 192.168.100.1/24 + # + # + # 10.200.16.20/24 + # + # + # + # + # + # + # ge-2/0/0 + # + # 0 + # + # + # + # 192.168.100.2/24 + # + # + # 10.200.16.21/24 + # + # + # + # + # + # " + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ list +
+
when changed +
The configuration as structured data after module completion.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ list +
+
always +
The configuration as structured data prior to module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:interfaces xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:interface> <nc:name>ge-1/0/0</nc:name> <nc:unit> <nc:name>0</nc:name> <nc:family> <nc:inet> <nc:address> <nc:name>192.168.100.1/24</nc:name> </nc:address> <nc:address> <nc:name>10.200.16.20/24</nc:name> </nc:address> </nc:inet> </nc:family> </nc:unit> </nc:interfaces>', 'xml 2', 'xml 3']
+
+
+ gathered + +
+ list +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ list +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ list +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Daniel Mellado (@dmellado) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lacp_interfaces_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lacp_interfaces_module.rst new file mode 100644 index 00000000..3e411522 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lacp_interfaces_module.rst @@ -0,0 +1,1100 @@ +.. _junipernetworks.junos.junos_lacp_interfaces_module: + + +******************************************* +junipernetworks.junos.junos_lacp_interfaces +******************************************* + +**LACP interfaces resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages Link Aggregation Control Protocol (LACP) attributes of interfaces on Juniper JUNOS devices. + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
The list of dictionaries of LACP interfaces options.
+
+
+ force_up + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
This is a boolean argument to control if the port should be up in absence of received link Aggregation Control Protocol Data Unit (LACPDUS). This value is applicable for member interfaces only.
+
+
+ name + +
+ string +
+
+ +
Name Identifier of the interface or link aggregation group.
+
+
+ period + +
+ string +
+
+
    Choices: +
  • fast
  • +
  • slow
  • +
+
+
Timer interval for periodic transmission of LACP packets. If the value is set to fast the packets are received every second and if the value is slow the packets are received every 30 seconds. This value is applicable for aggregate interface only.
+
+
+ port_priority + +
+ integer +
+
+ +
Priority of the member port. This value is applicable for member interfaces only.
+
Refer to vendor documentation for valid values.
+
+
+ sync_reset + +
+ string +
+
+
    Choices: +
  • disable
  • +
  • enable
  • +
+
+
The argument notifies minimum-link failure out of sync to peer. If the value is disable it disables minimum-link failure handling at LACP level and if value is enable it enables minimum-link failure handling at LACP level. This value is applicable for aggregate interface only.
+
+
+ system + +
+ dictionary +
+
+ +
This dict object contains configurable options related to LACP system parameters for the link aggregation group. This value is applicable for aggregate interface only.
+
+
+ mac + +
+ dictionary +
+
+ +
Specifies the system ID to use in LACP negotiations for the bundle, encoded as a MAC address.
+
+
+ address + +
+ string +
+
+ +
The system ID to use in LACP negotiations.
+
+
+ priority + +
+ integer +
+
+ +
Specifies the system priority to use in LACP negotiations for the bundle.
+
Refer to vendor documentation for valid values.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show interface.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • parsed
  • +
  • rendered
  • +
+
+
The state of the configuration after module completion.
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # Before state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/2 { + # ether-options { + # 802.3ad ae4; + # } + # } + # ge-0/0/3 { + # ether-options { + # 802.3ad ae0; + # } + # } + # ae0 { + # description "lag interface merged"; + # aggregated-ether-options { + # lacp { + # passive; + # } + # } + # } + # ae4 { + # description "test aggregate interface"; + # aggregated-ether-options { + # lacp { + # passive; + # link-protection; + # } + # } + # } + + - name: Merge provided configuration with device configuration + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + - name: ge-0/0/3 + port_priority: 100 + force_up: true + state: merged + + # After state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/2 { + # ether-options { + # 802.3ad ae4; + # } + # } + # ge-0/0/3 { + # ether-options { + # 802.3ad { + # lacp { + # force-up; + # port-priority 100; + # } + # ae0; + # } + # } + # } + # ae0 { + # description "lag interface merged"; + # aggregated-ether-options { + # lacp { + # passive; + # periodic fast; + # sync-reset enable; + # system-priority 100; + # system-id 00:00:00:00:00:02; + # } + # } + # } + # ae4 { + # description "test aggregate interface"; + # aggregated-ether-options { + # lacp { + # passive; + # link-protection; + # } + # } + # } + + # Using replaced + # Before state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/2 { + # ether-options { + # 802.3ad ae4; + # } + # } + # ge-0/0/3 { + # ether-options { + # 802.3ad { + # lacp { + # force-up; + # port-priority 100; + # } + # ae0; + # } + # } + # } + # ae0 { + # description "lag interface merged"; + # aggregated-ether-options { + # lacp { + # passive; + # periodic fast; + # sync-reset enable; + # system-priority 100; + # system-id 00:00:00:00:00:02; + # } + # } + # } + # ae4 { + # description "test aggregate interface"; + # aggregated-ether-options { + # lacp { + # passive; + # link-protection; + # } + # } + # } + + - name: Replace device LACP interfaces configuration with provided configuration + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + period: slow + state: replaced + + # After state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/2 { + # ether-options { + # 802.3ad ae4; + # } + # } + # ge-0/0/3 { + # ether-options { + # 802.3ad { + # lacp { + # force-up; + # port-priority 100; + # } + # ae0; + # } + # } + # } + # ae0 { + # description "lag interface merged"; + # aggregated-ether-options { + # lacp { + # passive; + # periodic slow; + # } + # } + # } + # ae4 { + # description "test aggregate interface"; + # aggregated-ether-options { + # lacp { + # passive; + # link-protection; + # } + # } + # } + + # Using overridden + # Before state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/2 { + # ether-options { + # 802.3ad ae4; + # } + # } + # ge-0/0/3 { + # ether-options { + # 802.3ad { + # lacp { + # force-up; + # port-priority 100; + # } + # ae0; + # } + # } + # } + # ae0 { + # description "lag interface merged"; + # aggregated-ether-options { + # lacp { + # passive; + # periodic slow; + # } + # } + # } + # ae4 { + # description "test aggregate interface"; + # aggregated-ether-options { + # lacp { + # passive; + # link-protection; + # } + # } + # } + + - name: Overrides all device LACP interfaces configuration with provided configuration + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + system: + priority: 300 + mac: + address: 00:00:00:00:00:03 + - name: ge-0/0/2 + port_priority: 200 + force_up: false + state: overridden + + # After state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/2 { + # ether-options { + # 802.3ad { + # lacp { + # port-priority 200; + # } + # ae4; + # } + # } + # } + # ge-0/0/3 { + # ether-options { + # 802.3ad { + # lacp { + # force-up; + # port-priority 100; + # } + # ae0; + # } + # } + # } + # ae0 { + # description "lag interface merged"; + # aggregated-ether-options { + # lacp { + # passive; + # system-priority 300; + # system-id 00:00:00:00:00:03; + # } + # } + # } + # ae4 { + # description "test aggregate interface"; + # aggregated-ether-options { + # lacp { + # passive; + # link-protection; + # } + # } + # } + + # Using deleted + # Before state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/2 { + # ether-options { + # 802.3ad { + # lacp { + # port-priority 200; + # } + # ae4; + # } + # } + # } + # ge-0/0/3 { + # ether-options { + # 802.3ad { + # lacp { + # force-up; + # port-priority 100; + # } + # ae0; + # } + # } + # } + # ae0 { + # description "lag interface merged"; + # aggregated-ether-options { + # lacp { + # passive; + # system-priority 300; + # system-id 00:00:00:00:00:03; + # } + # } + # } + # ae4 { + # description "test aggregate interface"; + # aggregated-ether-options { + # lacp { + # passive; + # link-protection; + # } + # } + # } + + - name: "Delete LACP interfaces attributes of given interfaces (Note: This won't delete the interface itself)" + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + - name: ge-0/0/3 + - name: ge-0/0/2 + state: deleted + + # After state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/2 { + # ether-options { + # 802.3ad ae4; + # } + # } + # ge-0/0/3 { + # ether-options { + # 802.3ad ae0; + # } + # } + # ae0 { + # description "lag interface merged"; + # aggregated-ether-options { + # lacp { + # passive; + # } + # } + # } + # ae4 { + # description "test aggregate interface"; + # aggregated-ether-options { + # lacp { + # passive; + # link-protection; + # } + # } + # } + # Using gathered + # Before state: + # ------------ + # + # user@junos01# show interfaces + # ansible@cm123456tr21# show interfaces + # ge-0/0/1 { + # ether-options { + # 802.3ad { + # lacp { + # force-up; + # port-priority 100; + # } + # ae1; + # } + # } + # } + # ge-0/0/2 { + # ether-options { + # 802.3ad ae1; + # } + # } + # ge-0/0/3 { + # ether-options { + # 802.3ad ae2; + # } + # } + # ge-0/0/4 { + # ether-options { + # 802.3ad ae2; + # } + # } + # ge-1/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.1/24; + # address 10.200.16.20/24; + # } + # family inet6; + # } + # } + # ge-2/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.2/24; + # address 10.200.16.21/24; + # } + # family inet6; + # } + # } + # ge-3/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.3/24; + # address 10.200.16.22/24; + # } + # family inet6; + # } + # } + # ae1 { + # description "Configured by Ansible"; + # aggregated-ether-options { + # lacp { + # periodic fast; + # sync-reset enable; + # system-priority 100; + # system-id 00:00:00:00:00:02; + # } + # } + # } + # ae2 { + # description "Configured by Ansible"; + # } + # em1 { + # description TEST; + # } + # fxp0 { + # description ANSIBLE; + # speed 1g; + # link-mode automatic; + # unit 0 { + # family inet { + # address 10.8.38.38/24; + # } + # } + # } + - name: Gather junos lacp interfaces as in given arguments + junipernetworks.junos.junos_lacp_interfaces: + state: gathered + # Task Output (redacted) + # ----------------------- + # + # "gathered": [ + # { + # "force_up": true, + # "name": "ge-0/0/1", + # "port_priority": 100 + # }, + # { + # "name": "ae1", + # "period": "fast", + # "sync_reset": "enable", + # "system": { + # "mac": { + # "address": "00:00:00:00:00:02" + # }, + # "priority": 100 + # } + # } + # ] + # After state: + # ------------ + # + # ansible@cm123456tr21# show interfaces + # ge-0/0/1 { + # ether-options { + # 802.3ad { + # lacp { + # force-up; + # port-priority 100; + # } + # ae1; + # } + # } + # } + # ge-0/0/2 { + # ether-options { + # 802.3ad ae1; + # } + # } + # ge-0/0/3 { + # ether-options { + # 802.3ad ae2; + # } + # } + # ge-0/0/4 { + # ether-options { + # 802.3ad ae2; + # } + # } + # ge-1/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.1/24; + # address 10.200.16.20/24; + # } + # family inet6; + # } + # } + # ge-2/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.2/24; + # address 10.200.16.21/24; + # } + # family inet6; + # } + # } + # ge-3/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.3/24; + # address 10.200.16.22/24; + # } + # family inet6; + # } + # } + # ae1 { + # description "Configured by Ansible"; + # aggregated-ether-options { + # lacp { + # periodic fast; + # sync-reset enable; + # system-priority 100; + # system-id 00:00:00:00:00:02; + # } + # } + # } + # ae2 { + # description "Configured by Ansible"; + # } + # em1 { + # description TEST; + # } + # fxp0 { + # description ANSIBLE; + # speed 1g; + # link-mode automatic; + # unit 0 { + # family inet { + # address 10.8.38.38/24; + # } + # } + # } + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # + # + # + # ge-0/0/1 + # + # + # + # + # 100 + # + # ae1 + # + # + # + # + # ge-0/0/2 + # + # + # ae1 + # + # + # + # + # ge-0/0/3 + # + # + # ae2 + # + # + # + # + # ge-0/0/4 + # + # + # ae2 + # + # + # + # + # ge-1/0/0 + # + # 0 + # + # + #
+ # 192.168.100.1/24 + #
+ #
+ # 10.200.16.20/24 + #
+ #
+ # + # + #
+ #
+ #
+ # + # ge-2/0/0 + # + # 0 + # + # + #
+ # 192.168.100.2/24 + #
+ #
+ # 10.200.16.21/24 + #
+ #
+ # + # + #
+ #
+ #
+ # + # ge-3/0/0 + # + # 0 + # + # + #
+ # 192.168.100.3/24 + #
+ #
+ # 10.200.16.22/24 + #
+ #
+ # + # + #
+ #
+ #
+ # + # ae1 + # Configured by Ansible + # + # + # fast + # enable + # 100 + # 00:00:00:00:00:02 + # + # + # + # + # ae2 + # Configured by Ansible + # + # + # em1 + # TEST + # + # + # fxp0 + # ANSIBLE + # 1g + # automatic + # + # 0 + # + # + #
+ # 10.8.38.38/24 + #
+ #
+ #
+ #
+ #
+ #
+ #
+ #
+ # - name: Convert interfaces config to argspec without connecting to the appliance + # junipernetworks.junos.junos_lacp_interfaces: + # running_config: "{{ lookup('file', './parsed.cfg') }}" + # state: parsed + # Task Output (redacted) + # ----------------------- + # "parsed": [ + # { + # "force_up": true, + # "name": "ge-0/0/1", + # "port_priority": 100 + # }, + # { + # "name": "ae1", + # "period": "fast", + # "sync_reset": "enable", + # "system": { + # "mac": { + # "address": "00:00:00:00:00:02" + # }, + # "priority": 100 + # } + # } + # ] + # Using rendered + - name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + + - name: ge-0/0/1 + port_priority: 100 + force_up: true + state: rendered + # Task Output (redacted) + # ----------------------- + # "rendered": " + # + # ae1 + # + # + # fast + # enable + # 00:00:00:00:00:02 + # 100 + # + # + # + # + # ge-0/0/1 + # + # + # + # 100 + # + # + # + # + # + # " + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ list +
+
when changed +
The configuration as structured data after module completion.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ list +
+
always +
The configuration as structured data prior to module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:interfaces xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:interface> <nc:name>ae1</nc:name> <nc:aggregated-ether-options> <nc:lacp> <nc:periodic>fast</nc:periodic> <nc:sync-reset>enable</nc:sync-reset> <nc:system-id>00:00:00:00:00:02</nc:system-id> <nc:system-priority>100</nc:system-priority> </nc:lacp> </nc:aggregated-ether-options> </nc:interface> <nc:interface> <nc:name>ge-0/0/1</nc:name> <nc:ether-options> <nc:ieee-802.3ad> <nc:lacp> <nc:port-priority>100</nc:port-priority> <nc:force-up/> </nc:lacp> </nc:ieee-802.3ad> </nc:ether-options> </nc:interface> </nc:interfaces>', 'xml 2', 'xml 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ganesh Nalawade (@ganeshrn) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lacp_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lacp_module.rst new file mode 100644 index 00000000..d805b73a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lacp_module.rst @@ -0,0 +1,375 @@ +.. _junipernetworks.junos.junos_lacp_module: + + +******************************** +junipernetworks.junos.junos_lacp +******************************** + +**Global Link Aggregation Control Protocol (LACP) Junos resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module provides declarative management of global LACP on Juniper Junos network devices. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
A dictionary of LACP global options
+
+
+ link_protection + +
+ string +
+
+
    Choices: +
  • revertive
  • +
  • non-revertive
  • +
+
+
Enable LACP link-protection for the system. If the value is set to non-revertive it will not revert links when a better priority link comes up. By default the link will be reverted.
+
+
+ system_priority + +
+ integer +
+
+ +
LACP priority for the system.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show chassis aggregated-devices ethernet lacp.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • deleted
  • +
  • gathered
  • +
  • rendered
  • +
  • parsed
  • +
+
+
The state of the configuration after module completion
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 18.1R1. + - This module works with connection ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + + + +Examples +-------- + +.. code-block:: yaml + + # Using deleted + + # Before state: + # ------------- + # user@junos01# show chassis aggregated-devices ethernet lacp + # system-priority 63; + # link-protection { + # non-revertive; + # } + + - name: Delete global LACP attributes + junipernetworks.junos.junos_lacp: + state: deleted + + # After state: + # ------------ + # user@junos01# show chassis aggregated-devices ethernet lacp + # + + + # Using merged + + # Before state: + # ------------- + # user@junos01# show chassis aggregated-devices ethernet lacp + # + + - name: Merge global LACP attributes + junipernetworks.junos.junos_lacp: + config: + system_priority: 63 + link_protection: revertive + state: merged + + # After state: + # ------------ + # user@junos01# show chassis aggregated-devices ethernet lacp + # system-priority 63; + # link-protection { + # non-revertive; + # } + + + # Using replaced + + # Before state: + # ------------- + # user@junos01# show chassis aggregated-devices ethernet lacp + # system-priority 63; + # link-protection { + # non-revertive; + # } + + - name: Replace global LACP attributes + junipernetworks.junos.junos_lacp: + config: + system_priority: 30 + link_protection: non-revertive + state: replaced + + # After state: + # ------------ + # user@junos01# show chassis aggregated-devices ethernet lacp + # system-priority 30; + # link-protection; + # + # Using gathered + # Before state: + # ------------ + # + # ansible@cm123456tr21# show chassis aggregated-devices ethernet lacp + # system-priority 63; + # link-protection; + + - name: Gather junos lacp as in given arguments + junipernetworks.junos.junos_lacp: + state: gathered + # Task Output (redacted) + # ----------------------- + # + # "gathered": { + # "link_protection": "revertive", + # "system_priority": 63 + # } + # After state: + # ------------ + # + # ansible@cm123456tr21# show chassis aggregated-devices ethernet lacp + # system-priority 63; + # link-protection; + # Using rendered + - name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_lacp: + config: + system_priority: 63 + link_protection: revertive + state: rendered + # Task Output (redacted) + # ----------------------- + # "rendered": " + # + # + # + # 63 + # + # + # + # + # + # + # + # + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # + # + # + # + # + # 63 + # + # + # + # + # + # + # + # + # - name: Convert lacp config to argspec without connecting to the appliance + # junipernetworks.junos.junos_lacp: + # running_config: "{{ lookup('file', './parsed.cfg') }}" + # state: parsed + # Task Output (redacted) + # ----------------------- + # "parsed": { + # "link_protection": "revertive", + # "system_priority": 63 + # } + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The configuration as structured data after module completion.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration as structured data prior to module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ xml + +
+ list +
+
always +
The set of xml rpc payload pushed to the remote device.
+
+
Sample:
+
['<nc:chassis xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:aggregated-devices> <nc:ethernet> <nc:lacp> <nc:system-priority>63</nc:system-priority> <nc:link-protection> <nc:non-revertive delete="delete"/> </nc:link-protection> </nc:lacp> </nc:ethernet> </nc:aggregated-devices> </nc:chassis>', 'xml 2', 'xml 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ganesh Nalawade (@ganeshrn) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lag_interfaces_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lag_interfaces_module.rst new file mode 100644 index 00000000..777407ba --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lag_interfaces_module.rst @@ -0,0 +1,987 @@ +.. _junipernetworks.junos.junos_lag_interfaces_module: + + +****************************************** +junipernetworks.junos.junos_lag_interfaces +****************************************** + +**Link Aggregation Juniper JUNOS resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages properties of Link Aggregation Group on Juniper JUNOS devices. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
A list of link aggregation group configurations.
+
+
+ link_protection + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
This boolean option indicates if link protection should be enabled for the LAG interface. If value is True link protection is enabled on LAG and if value is False link protection is disabled.
+
+
+ members + +
+ list + / elements=dictionary +
+
+ +
List of member interfaces of the link aggregation group. The value can be single interface or list of interfaces.
+
+
+ ether_option_type + +
+ string +
+
+
    Choices: +
  • ether ←
  • +
  • gigether
  • +
+
+
Specify the type of ethernet interface.
+
+
+ link_type + +
+ string +
+
+
    Choices: +
  • primary
  • +
  • backup
  • +
+
+
The value of this options configures the member link as either primary or backup. Value primary configures primary interface for link-protection mode and backup configures backup interface for link-protection mode.
+
+
+ member + +
+ string +
+
+ +
Name of the member interface.
+
+
+ mode + +
+ string +
+
+
    Choices: +
  • active
  • +
  • passive
  • +
+
+
LAG mode. A value of passive will enable LACP in passive mode that is it will respond to LACP packets and active configures the link to initiate transmission of LACP packets.
+
+
+ name + +
+ string + / required +
+
+ +
Name of the link aggregation group (LAG).
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show interfaces.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • rendered
  • +
  • parsed
  • +
+
+
The state of the configuration after module completion
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 18.4R1. + - This module works with connection ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + + # Before state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/1 { + # description "Ansible configured interface 1"; + # ether-options { + # 802.3ad ae0; + # } + # } + # ge-0/0/2 { + # description "Ansible configured interface 2"; + # ether-options { + # 802.3ad ae0; + # } + # } + # ae0 { + # description "lag interface"; + # } + # ae1 { + # description "lag interface 1"; + # } + + - name: "Delete LAG attributes of given interfaces (Note: This won't delete the interface itself)" + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae0 + - name: ae1 + state: deleted + + # After state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/1 { + # description "Ansible configured interface 1"; + # } + # ge-0/0/2 { + # description "Ansible configured interface 2"; + # } + + + # Using merged + + # Before state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/1 { + # description "Ansible configured interface 1"; + # } + # ge-0/0/2 { + # description "Ansible configured interface 2"; + # } + + - name: Merge provided configuration with device configuration + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae0 + members: + - member: ge-0/0/1 + link_type: primary + - member: ge-0/0/2 + link_type: backup + state: merged + + # After state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/1 { + # description "Ansible configured interface 1"; + # ether-options { + # 802.3ad { + # ae0; + # primary; + # } + # } + # } + # ge-0/0/2 { + # description "Ansible configured interface 2"; + # ether-options { + # 802.3ad { + # ae0; + # backup; + # } + # } + # } + + + # Using merged + + # Before state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/1 { + # description "Ansible configured interface 1"; + # ether-options { + # 802.3ad ae0; + # } + # } + # ge-0/0/2 { + # description "Ansible configured interface 2"; + # ether-options { + # 802.3ad ae0; + # } + # } + # ae0 { + # description "lag interface"; + # } + # ae3 { + # description "lag interface 3"; + # } + + - name: Overrides all device LAG configuration with provided configuration + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae0 + members: + - member: ge-0/0/2 + - name: ae1 + members: + - member: ge-0/0/1 + mode: passive + state: overridden + + # After state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/1 { + # description "Ansible configured interface 1"; + # ether-options { + # 802.3ad ae1; + # } + # } + # ge-0/0/2 { + # description "Ansible configured interface 2"; + # ether-options { + # 802.3ad ae0; + # } + # } + # ae0 { + # description "lag interface"; + # } + # ae1 { + # aggregated-ether-options { + # lacp { + # active; + # } + # } + # } + + + # Using merged + + # Before state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/1 { + # description "Ansible configured interface 1"; + # } + # ge-0/0/2 { + # description "Ansible configured interface 2"; + # } + # ge-0/0/3 { + # description "Ansible configured interface 3"; + # } + + - name: Replace device LAG configuration with provided configuration + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae0 + members: + - member: ge-0/0/1 + mode: active + state: replaced + + # After state: + # ------------- + # user@junos01# show interfaces + # ge-0/0/1 { + # description "Ansible configured interface 1"; + # ether-options { + # 802.3ad ae0; + # } + # } + # ge-0/0/2 { + # description "Ansible configured interface 2"; + # } + # ae0 { + # aggregated-ether-options { + # lacp { + # active; + # } + # } + # } + # ge-0/0/3 { + # description "Ansible configured interface 3"; + # } + # Using gathered + # Before state: + # ------------ + # + # ansible@cm123456tr21# show interfaces + # ge-0/0/1 { + # ether-options { + # 802.3ad ae1; + # } + # } + # ge-0/0/2 { + # ether-options { + # 802.3ad ae1; + # } + # } + # ge-0/0/3 { + # ether-options { + # 802.3ad { + # ae2; + # primary; + # } + # } + # } + # ge-0/0/4 { + # ether-options { + # 802.3ad { + # ae2; + # backup; + # } + # } + # } + # ge-1/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.1/24; + # address 10.200.16.20/24; + # } + # family inet6; + # } + # } + # ge-2/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.2/24; + # address 10.200.16.21/24; + # } + # family inet6; + # } + # } + # ge-3/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.3/24; + # address 10.200.16.22/24; + # } + # family inet6; + # } + # } + # ae1 { + # description "Configured by Ansible"; + # aggregated-ether-options { + # lacp { + # active; + # } + # } + # } + # ae2 { + # description "Configured by Ansible"; + # aggregated-ether-options { + # link-protection; + # lacp { + # passive; + # } + # } + # } + # em1 { + # description TEST; + # } + # fxp0 { + # description ANSIBLE; + # speed 1g; + # link-mode automatic; + # unit 0 { + # family inet { + # address 10.8.38.38/24; + # } + # } + # } + - name: Gather junos lag interfaces as in given arguments + junipernetworks.junos.junos_lag_interfaces: + state: gathered + # Task Output (redacted) + # ----------------------- + # + # "gathered": [ + # { + # "members": [ + # { + # "member": "ge-0/0/1" + # }, + # { + # "member": "ge-0/0/2" + # } + # ], + # "mode": "active", + # "name": "ae1" + # }, + # { + # "link_protection": true, + # "members": [ + # { + # "link_type": "primary", + # "member": "ge-0/0/3" + # }, + # { + # "link_type": "backup", + # "member": "ge-0/0/4" + # } + # ], + # "mode": "passive", + # "name": "ae2" + # } + # ] + # After state: + # ------------ + # + # ansible@cm123456tr21# show interfaces + # ge-0/0/1 { + # ether-options { + # 802.3ad ae1; + # } + # } + # ge-0/0/2 { + # ether-options { + # 802.3ad ae1; + # } + # } + # ge-0/0/3 { + # ether-options { + # 802.3ad { + # ae2; + # primary; + # } + # } + # } + # ge-0/0/4 { + # ether-options { + # 802.3ad { + # ae2; + # backup; + # } + # } + # } + # ge-1/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.1/24; + # address 10.200.16.20/24; + # } + # family inet6; + # } + # } + # ge-2/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.2/24; + # address 10.200.16.21/24; + # } + # family inet6; + # } + # } + # ge-3/0/0 { + # unit 0 { + # family inet { + # address 192.168.100.3/24; + # address 10.200.16.22/24; + # } + # family inet6; + # } + # } + # ae1 { + # description "Configured by Ansible"; + # aggregated-ether-options { + # lacp { + # active; + # } + # } + # } + # ae2 { + # description "Configured by Ansible"; + # aggregated-ether-options { + # link-protection; + # lacp { + # passive; + # } + # } + # } + # em1 { + # description TEST; + # } + # fxp0 { + # description ANSIBLE; + # speed 1g; + # link-mode automatic; + # unit 0 { + # family inet { + # address 10.8.38.38/24; + # } + # } + # } + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # + # + # + # ge-0/0/1 + # + # + # ae1 + # + # + # + # + # ge-0/0/2 + # + # + # ae1 + # + # + # + # + # ge-0/0/3 + # + # + # ae2 + # + # + # + # + # + # ge-0/0/4 + # + # + # ae2 + # + # + # + # + # + # ge-1/0/0 + # + # 0 + # + # + #
+ # 192.168.100.1/24 + #
+ #
+ # 10.200.16.20/24 + #
+ #
+ # + # + #
+ #
+ #
+ # + # ge-2/0/0 + # + # 0 + # + # + #
+ # 192.168.100.2/24 + #
+ #
+ # 10.200.16.21/24 + #
+ #
+ # + # + #
+ #
+ #
+ # + # ge-3/0/0 + # + # 0 + # + # + #
+ # 192.168.100.3/24 + #
+ #
+ # 10.200.16.22/24 + #
+ #
+ # + # + #
+ #
+ #
+ # + # ae1 + # Configured by Ansible + # + # + # + # + # + # + # + # ae2 + # Configured by Ansible + # + # + # + # + # + # + # + # + # + # em1 + # TEST + # + # + # fxp0 + # ANSIBLE + # 1g + # automatic + # + # 0 + # + # + #
+ # 10.8.38.38/24 + #
+ #
+ #
+ #
+ #
+ #
+ #
+ #
+ # - name: Convert interfaces config to argspec without connecting to the appliance + # junipernetworks.junos.junos_lag_interfaces: + # running_config: "{{ lookup('file', './parsed.cfg') }}" + # state: parsed + # Task Output (redacted) + # ----------------------- + # "parsed": [ + # { + # "members": [ + # { + # "member": "ge-0/0/1" + # }, + # { + # "member": "ge-0/0/2" + # } + # ], + # "mode": "active", + # "name": "ae1" + # }, + # { + # "link_protection": true, + # "members": [ + # { + # "link_type": "primary", + # "member": "ge-0/0/3" + # }, + # { + # "link_type": "backup", + # "member": "ge-0/0/4" + # } + # ], + # "mode": "passive", + # "name": "ae2" + # } + # ] + # Using rendered + - name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae1 + members: + - member: ge-0/0/1 + - member: ge-0/0/2 + mode: active + + - name: ae2 + link_protection: true + members: + - member: ge-0/0/3 + link_type: primary + - member: ge-0/0/4 + link_type: backup + mode: passive + # Task Output (redacted) + # ----------------------- + # "rendered": " + # + # ae1 + # + # + # + # + # + # + # + # ge-0/0/1 + # + # + # ae1 + # + # + # + # + # ge-0/0/2 + # + # + # ae1 + # + # + # + # + # ae2 + # + # + # + # + # + # + # + # + # ge-0/0/3 + # + # + # ae2 + # + # + # + # + # + # ge-0/0/4 + # + # + # ae2 + # + # + # + # + # " + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ list +
+
when changed +
The configuration as structured data after module completion.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ list +
+
always +
The configuration as structured data prior to module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ xml + +
+ list +
+
always +
The set of xml rpc payload pushed to the remote device.
+
+
Sample:
+
['<nc:interfaces xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:interface> <nc:name>ae1</nc:name> <nc:aggregated-ether-options> <nc:lacp> <nc:active/> </nc:lacp> </nc:aggregated-ether-options> </nc:interface> <nc:interface> <nc:name>ge-0/0/1</nc:name> <nc:ether-options> <nc:ieee-802.3ad> <nc:bundle>ae1</nc:bundle> </nc:ieee-802.3ad> </nc:ether-options> </nc:interface> <nc:interface> <nc:name>ge-0/0/2</nc:name> <nc:ether-options> <nc:ieee-802.3ad> <nc:bundle>ae1</nc:bundle> </nc:ieee-802.3ad> </nc:ether-options> </nc:interface> <nc:interface> <nc:name>ae2</nc:name> <nc:aggregated-ether-options> <nc:lacp> <nc:passive/> </nc:lacp> <nc:link-protection/> </nc:aggregated-ether-options> </nc:interface> <nc:interface> <nc:name>ge-0/0/3</nc:name> <nc:ether-options> <nc:ieee-802.3ad> <nc:bundle>ae2</nc:bundle> <nc:primary/> </nc:ieee-802.3ad> </nc:ether-options> </nc:interface> <nc:interface> <nc:name>ge-0/0/4</nc:name> <nc:ether-options> <nc:ieee-802.3ad> <nc:bundle>ae2</nc:bundle> <nc:backup/> </nc:ieee-802.3ad> </nc:ether-options> </nc:interface> </nc:interfaces>', 'xml 2', 'xml 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ganesh Nalawade (@ganeshrn) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lldp_global_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lldp_global_module.rst new file mode 100644 index 00000000..28e9a7d8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lldp_global_module.rst @@ -0,0 +1,444 @@ +.. _junipernetworks.junos.junos_lldp_global_module: + + +*************************************** +junipernetworks.junos.junos_lldp_global +*************************************** + +**LLDP resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages link layer discovery protocol (LLDP) attributes on Juniper JUNOS devices. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
The list of link layer discovery protocol attribute configurations
+
+
+ address + +
+ string +
+
+ +
This argument sets the management address from LLDP.
+
+
+ enabled + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
This argument is a boolean value to enabled or disable LLDP.
+
+
+ hold_multiplier + +
+ integer +
+
+ +
Specify the number of seconds that LLDP information is held before it is discarded. The multiplier value is used in combination with the interval value.
+
+
+ interval + +
+ integer +
+
+ +
Frequency at which LLDP advertisements are sent (in seconds).
+
+
+ transmit_delay + +
+ integer +
+
+ +
Specify the number of seconds the device waits before sending advertisements to neighbors after a change is made in local system.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show protocols lldp.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • deleted
  • +
  • gathered
  • +
  • rendered
  • +
  • parsed
  • +
+
+
The state of the configuration after module completion.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 18.4R1. + - This module works with connection ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # Before state: + # ------------- + # user@junos01# # show protocols lldp + # + - name: Merge provided configuration with device configuration + junipernetworks.junos.junos_lldp_global: + config: + interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + state: merged + + # After state: + # ------------- + # user@junos01# show protocols lldp + # management-address 10.1.1.1; + # advertisement-interval 10000; + # transmit-delay 400; + # hold-multiplier 10; + + # Using replaced + # Before state: + # ------------- + # user@junos01# show protocols lldp + # management-address 10.1.1.1; + # advertisement-interval 10000; + # transmit-delay 400; + # hold-multiplier 10; + + - name: Replace provided configuration with device configuration + junipernetworks.junos.junos_lldp_global: + config: + address: 20.2.2.2 + hold_multiplier: 30 + enabled: false + state: replaced + + # After state: + # ------------- + # user@junos01# show protocols lldp + # disable; + # management-address 20.2.2.2; + # hold-multiplier 30; + + # Using deleted + # Before state: + # ------------- + # user@junos01# show protocols lldp + # management-address 20.2.2.2; + # hold-multiplier 30; + + - name: Delete lldp configuration (this will by default remove all lldp configuration) + junipernetworks.junos.junos_lldp_global: + state: deleted + + # After state: + # ------------- + # user@junos01# # show protocols lldp + # + # + # Using gathered + # Before state: + # ------------ + # + # ansible@cm123456tr21# show protocols lldp + # management-address 10.1.1.1; + # advertisement-interval 10000; + # transmit-delay 400; + # hold-multiplier 10; + # interface ge-0/0/1; + # interface ge-0/0/2 { + # disable; + # } + - name: Gather junos lldp_global as in given arguments + junipernetworks.junos.junos_lldp_global: + state: gathered + # Task Output (redacted) + # ----------------------- + # + # "gathered": { + # "address": "10.1.1.1", + # "hold_multiplier": 10, + # "interval": 10000, + # "transmit_delay": 400 + # } + # After state: + # ------------ + # + # ansible@cm123456tr21# show protocols lldp + # management-address 10.1.1.1; + # advertisement-interval 10000; + # transmit-delay 400; + # hold-multiplier 10; + # interface ge-0/0/1; + # interface ge-0/0/2 { + # disable; + # } + # Using rendered + - name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_lldp_global: + config: + interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + state: rendered + # Task Output (redacted) + # ----------------------- + # "rendered": " + # + # 10.1.1.1 + # 10000 + # 400 + # 10 + # + # + # " + # + # parsed.cfg + # ------------ + # + # + # + # + # + # + # + # 0.0.0.0 + # + # ge-0/0/0.0 + # + # + # + # + # 10.1.1.1 + # 10000 + # 400 + # 10 + # + # ge-0/0/1 + # + # + # ge-0/0/2 + # + # + # + # + # + # + # - name: Convert lldp global config to argspec without connecting to the appliance + # junipernetworks.junos.junos_lldp_global: + # running_config: "{{ lookup('file', './parsed.cfg') }}" + # state: parsed + # Task Output (redacted) + # ----------------------- + # "parsed": { + # "address": "10.1.1.1", + # "hold_multiplier": 10, + # "interval": 10000, + # "transmit_delay": 400 + # } + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The configuration as structured data after module completion.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration as structured data prior to module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:lldp> <nc:management-address>10.1.1.1</nc:management-address> <nc:advertisement-interval>10000</nc:advertisement-interval> <nc:transmit-delay>400</nc:transmit-delay> <nc:hold-multiplier>10</nc:hold-multiplier> <nc:disable delete="delete"/> </nc:lldp> </nc:protocols>', 'xml 2', 'xml 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ganesh Nalawade (@ganeshrn) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lldp_interfaces_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lldp_interfaces_module.rst new file mode 100644 index 00000000..d4721c00 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_lldp_interfaces_module.rst @@ -0,0 +1,427 @@ +.. _junipernetworks.junos.junos_lldp_interfaces_module: + + +******************************************* +junipernetworks.junos.junos_lldp_interfaces +******************************************* + +**LLDP interfaces resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages link layer discovery protocol (LLDP) attributes of interfaces on Juniper JUNOS devices. + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
The list of link layer discovery protocol interface attribute configurations
+
+
+ enabled + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
This is a boolean value to control disabling of LLDP on the interface name
+
+
+ name + +
+ string + / required +
+
+ +
Name of the interface LLDP needs to be configured on.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show protocols lldp.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • rendered
  • +
  • parsed
  • +
+
+
The state of the configuration after module completion.
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # Before state: + # ------------- + # user@junos01# # show protocols lldp + # management-address 10.1.1.1; + # advertisement-interval 10000; + + - name: Merge provided configuration with device configuration + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + enabled: false + state: merged + + # After state: + # ------------- + # user@junos01# show protocols lldp + # management-address 10.1.1.1; + # advertisement-interval 10000; + # interface ge-0/0/1; + # interface ge-0/0/2 { + # disable; + # } + + # Using replaced + # Before state: + # ------------- + # user@junos01# show protocols lldp + # management-address 10.1.1.1; + # advertisement-interval 10000; + # interface ge-0/0/1; + # interface ge-0/0/2 { + # disable; + # } + + - name: Replace provided configuration with device configuration + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/2 + disable: false + - name: ge-0/0/3 + enabled: false + state: replaced + + # After state: + # ------------- + # user@junos01# show protocols lldp + # management-address 10.1.1.1; + # advertisement-interval 10000; + # interface ge-0/0/1; + # interface ge-0/0/2; + # interface ge-0/0/3 { + # disable; + # } + + # Using overridden + # Before state: + # ------------- + # user@junos01# show protocols lldp + # management-address 10.1.1.1; + # advertisement-interval 10000; + # interface ge-0/0/1; + # interface ge-0/0/2 { + # disable; + # } + + - name: Override provided configuration with device configuration + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/2 + enabled: false + state: overridden + + # After state: + # ------------- + # user@junos01# show protocols lldp + # management-address 10.1.1.1; + # advertisement-interval 10000; + # interface ge-0/0/2 { + # disable; + # } + + # Using deleted + # Before state: + # ------------- + # user@junos01# show protocols lldp + # management-address 10.1.1.1; + # advertisement-interval 10000; + # interface ge-0/0/1; + # interface ge-0/0/2; + # interface ge-0/0/3 { + # disable; + # } + - name: Delete lldp interface configuration (this will not delete other lldp configuration) + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/3 + state: deleted + + # After state: + # ------------- + # user@junos01# show protocols lldp + # management-address 10.1.1.1; + # advertisement-interval 10000; + # interface ge-0/0/2; + # interface ge-0/0/1; + # Using gathered + # Before state: + # ------------ + # + # ansible@cm123456tr21# show protocols lldp + # interface ge-0/0/1; + # interface ge-0/0/2 { + # disable; + # } + - name: Gather junos lldp interfaces as in given arguments + junipernetworks.junos.junos_lldp_interfaces: + state: gathered + # Task Output (redacted) + # ----------------------- + # + # "gathered": [ + # { + # "name": "ge-0/0/1" + # }, + # { + # "enabled": false, + # "name": "ge-0/0/2" + # } + # ] + # After state: + # ------------ + # + # ansible@cm123456tr21# show protocols lldp + # interface ge-0/0/1; + # interface ge-0/0/2 { + # disable; + # } + # Using rendered + - name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + enabled: false + state: rendered + # Task Output (redacted) + # ----------------------- + # "rendered": " + # + # + # ge-0/0/1 + # + # + # + # ge-0/0/2 + # + # + # + # " + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # + # + # + # + # 0.0.0.0 + # + # ge-0/0/0.0 + # + # + # + # + # + # ge-0/0/1 + # + # + # ge-0/0/2 + # + # + # + # + # + # + # - name: Convert lldp interfaces config to argspec without connecting to the appliance + # junipernetworks.junos.junos_lldp_interfaces: + # running_config: "{{ lookup('file', './parsed.cfg') }}" + # state: parsed + # Task Output (redacted) + # ----------------------- + # "parsed": [ + # { + # "name": "ge-0/0/1" + # }, + # { + # "enabled": false, + # "name": "ge-0/0/2" + # } + # ] + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ list +
+
when changed +
The configuration as structured data after module completion.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ list +
+
always +
The configuration as structured data prior to module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:lldp> <nc:interface> <nc:name>ge-0/0/1</nc:name> <nc:disable delete="delete"/> </nc:interface> <nc:interface> <nc:name>ge-0/0/2</nc:name> <nc:disable/> </nc:interface> </nc:lldp> </nc:protocols>', 'xml 2', 'xml 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ganesh Nalawade (@ganeshrn) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_logging_global_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_logging_global_module.rst new file mode 100644 index 00000000..26c5903b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_logging_global_module.rst @@ -0,0 +1,5615 @@ +.. _junipernetworks.junos.junos_logging_global_module: + + +****************************************** +junipernetworks.junos.junos_logging_global +****************************************** + +**Manage logging configuration on Junos devices.** + + +Version added: 2.4.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages logging configuration on devices running Junos. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
A dictionary of logging configuration.
+
+
+ allow_duplicates + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not suppress the repeated message for all targets.
+
+
+ archive + +
+ dictionary +
+
+ +
Specify archive file information.
+
+
+ binary_data + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Mark file as if it contains binary data.
+
+
+ file_size + +
+ string +
+
+ +
Size of files to be archived (65536..1073741824 bytes).
+
+
+ files + +
+ integer +
+
+ +
Specify number of files to be archived (1..1000).
+
+
+ no_binary_data + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't mark file as if it contains binary data.
+
+
+ no_world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set archive file information.
+
+
+ world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allow any user to read the log file.
+
+
+ console + +
+ dictionary +
+
+ +
Set console logging parameters.
+
+
+ any + +
+ dictionary +
+
+ +
Set All facilities.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ authorization + +
+ dictionary +
+
+ +
Specify authorization system.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ change_log + +
+ dictionary +
+
+ +
Specify configuration change log.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ conflict_log + +
+ dictionary +
+
+ +
Specify configuration conflict log.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ daemon + +
+ dictionary +
+
+ +
Specify various system processes.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ dfc + +
+ dictionary +
+
+ +
Specify dynamic flow capture.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ external + +
+ dictionary +
+
+ +
Specify Local external applications.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ firewall + +
+ dictionary +
+
+ +
Specify Firewall filtering system.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ ftp + +
+ dictionary +
+
+ +
Specify FTP process.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ interactive_commands + +
+ dictionary +
+
+ +
Specify commands executed by the UI.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ kernel + +
+ dictionary +
+
+ +
Specify Kernel specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ ntp + +
+ dictionary +
+
+ +
Specify NTP process specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ pfe + +
+ dictionary +
+
+ +
Specify Packet Forwarding Engine specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ security + +
+ dictionary +
+
+ +
Specify Security related logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ user + +
+ dictionary +
+
+ +
Specify user specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ files + +
+ list + / elements=dictionary +
+
+ +
Specify files logging.
+
+
+ allow_duplicates + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not suppress the repeated message for all targets.
+
+
+ any + +
+ dictionary +
+
+ +
Set All facilities.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ archive + +
+ dictionary +
+
+ +
Specify archive file information.
+
+
+ archive_sites + +
+ list + / elements=string +
+
+ +
Specify Primary and failover URLs to receive archive facilities.
+
+
+ binary_data + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Mark file as if it contains binary data.
+
+
+ file_size + +
+ string +
+
+ +
Size of files to be archived (65536..1073741824 bytes).
+
+
+ files + +
+ integer +
+
+ +
Specify number of files to be archived (1..1000).
+
+
+ no_binary_data + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't mark file as if it contains binary data.
+
+
+ no_world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set archive file information.
+
+
+ start_time + +
+ string +
+
+ +
Specify start time for file transmission (yyyy-mm-dd.hh:mm).
+
+
+ transfer_interval + +
+ integer +
+
+ +
Specify frequency at which to transfer files to archive sites (5..2880 minutes).
+
+
+ world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allow any user to read the log file.
+
+
+ authorization + +
+ dictionary +
+
+ +
Specify authorization system.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ change_log + +
+ dictionary +
+
+ +
Specify configuration change log.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ conflict_log + +
+ dictionary +
+
+ +
Specify configuration conflict log.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ daemon + +
+ dictionary +
+
+ +
Specify various system processes.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ dfc + +
+ dictionary +
+
+ +
Specify dynamic flow capture.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ explicit_priority + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Include priority and facility in messages.
+
+
+ external + +
+ dictionary +
+
+ +
Specify Local external applications.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ firewall + +
+ dictionary +
+
+ +
Specify Firewall filtering system.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ ftp + +
+ dictionary +
+
+ +
Specify FTP process.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ interactive_commands + +
+ dictionary +
+
+ +
Specify commands executed by the UI.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ kernel + +
+ dictionary +
+
+ +
Specify Kernel specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ match + +
+ string +
+
+ +
Specify regular expression for lines to be logged.
+
+
+ match_strings + +
+ list + / elements=string +
+
+ +
Specify matching string(s) for lines to be logged.
+
+
+ name + +
+ string +
+
+ +
Specify filename in which to log data.
+
+
+ ntp + +
+ dictionary +
+
+ +
Specify NTP process specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ pfe + +
+ dictionary +
+
+ +
Specify Packet Forwarding Engine specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ security + +
+ dictionary +
+
+ +
Specify Security related logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ structured_data + +
+ dictionary +
+
+ +
Specify Log system message in structured format.
+
+
+ brief + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Omit English-language text from end of logged messages.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Log system message in structured format.
+
+
+ user + +
+ dictionary +
+
+ +
Specify user specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ hosts + +
+ list + / elements=dictionary +
+
+ +
Specify hosts to be notified.
+
+
+ allow_duplicates + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not suppress the repeated message for all targets.
+
+
+ any + +
+ dictionary +
+
+ +
Set All facilities.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ authorization + +
+ dictionary +
+
+ +
Specify authorization system.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ change_log + +
+ dictionary +
+
+ +
Specify configuration change log.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ conflict_log + +
+ dictionary +
+
+ +
Specify configuration conflict log.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ daemon + +
+ dictionary +
+
+ +
Specify various system processes.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ dfc + +
+ dictionary +
+
+ +
Specify dynamic flow capture.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ exclude_hostname + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify exclude hostname field in messages.
+
+
+ explicit_priority + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Include priority and facility in messages.
+
+
+ external + +
+ dictionary +
+
+ +
Specify Local external applications.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ facility_override + +
+ string +
+
+ +
Specify alternate facility for logging to remote host.
+
+
+ firewall + +
+ dictionary +
+
+ +
Specify Firewall filtering system.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ ftp + +
+ dictionary +
+
+ +
Specify FTP process.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ interactive_commands + +
+ dictionary +
+
+ +
Specify commands executed by the UI.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ kernel + +
+ dictionary +
+
+ +
Specify Kernel specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ log_prefix + +
+ string +
+
+ +
Prefix for all logging to this host.
+
+
+ match + +
+ string +
+
+ +
Specify regular expression for lines to be logged.
+
+
+ match_strings + +
+ list + / elements=string +
+
+ +
Specify matching string(s) for lines to be logged.
+
+
+ name + +
+ string +
+
+ +
Specify the host name.
+
+
+ ntp + +
+ dictionary +
+
+ +
Specify NTP process specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ pfe + +
+ dictionary +
+
+ +
Specify Packet Forwarding Engine specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ port + +
+ integer +
+
+ +
Specify port number.
+
+
+ routing_instance + +
+ string +
+
+ +
Specify routing-instance.
+
+
+ security + +
+ dictionary +
+
+ +
Specify Security related logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ source_address + +
+ string +
+
+ +
Specify address as source address.
+
+
+ structured_data + +
+ dictionary +
+
+ +
Specify Log system message in structured format.
+
+
+ brief + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Omit English-language text from end of logged messages.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Log system message in structured format.
+
+
+ user + +
+ dictionary +
+
+ +
Specify user specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ log_rotate_frequency + +
+ integer +
+
+ +
Specify Rotate log frequency (1..59 minutes).
+
+
+ routing_instance + +
+ string +
+
+ +
Specify Routing routing-instance.
+
+
+ server + +
+ dictionary +
+
+ +
Specify syslog server logging.
+
+
+ routing_instance + +
+ dictionary +
+
+ +
nable/disable syslog server in routing-instances.
+
+
+ all + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable/disable all routing instances.
+
+
+ default + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable/disable default routing instances.
+
+
+ routing_instances + +
+ list + / elements=dictionary +
+
+ +
Specify routing-instances.
+
+
+ disable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable syslog server in this routing instances.
+
+
+ name + +
+ string +
+
+ +
Specify routing-instance name.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable syslog server.
+
+
+ source_address + +
+ string +
+
+ +
Specify address as source address.
+
+
+ time_format + +
+ dictionary +
+
+ +
Specify additional information to include in system log timestamp.
+
+
+ millisecond + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Include milliseconds in timestamp.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set time-format
+
+
+ year + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Include year in timestamp.
+
+
+ users + +
+ list + / elements=dictionary +
+
+ +
Specify user logging
+
+
+ allow_duplicates + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not suppress the repeated message for all targets.
+
+
+ any + +
+ dictionary +
+
+ +
Set All facilities.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ authorization + +
+ dictionary +
+
+ +
Specify authorization system.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ change_log + +
+ dictionary +
+
+ +
Specify configuration change log.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ conflict_log + +
+ dictionary +
+
+ +
Specify configuration conflict log.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ daemon + +
+ dictionary +
+
+ +
Specify various system processes.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ dfc + +
+ dictionary +
+
+ +
Specify dynamic flow capture.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ external + +
+ dictionary +
+
+ +
Specify Local external applications.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ firewall + +
+ dictionary +
+
+ +
Specify Firewall filtering system.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ ftp + +
+ dictionary +
+
+ +
Specify FTP process.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ interactive_commands + +
+ dictionary +
+
+ +
Specify commands executed by the UI.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ kernel + +
+ dictionary +
+
+ +
Specify Kernel specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ match + +
+ string +
+
+ +
Specify regular expression for lines to be logged.
+
+
+ match_strings + +
+ list + / elements=string +
+
+ +
Specify matching string(s) for lines to be logged.
+
+
+ name + +
+ string +
+
+ +
Specify user name.
+
+
+ ntp + +
+ dictionary +
+
+ +
Specify NTP process specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ pfe + +
+ dictionary +
+
+ +
Specify Packet Forwarding Engine specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ security + +
+ dictionary +
+
+ +
Specify Security related logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ user + +
+ dictionary +
+
+ +
Specify user specific logging.
+
+
+ level + +
+ string + / required +
+
+
    Choices: +
  • alert
  • +
  • any
  • +
  • critical
  • +
  • emergency
  • +
  • error
  • +
  • info
  • +
  • none
  • +
  • notice
  • +
  • warning
  • +
+
+
Set severity logging level.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show system syslog.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • deleted
  • +
  • overridden
  • +
  • parsed
  • +
  • gathered
  • +
  • rendered
  • +
+
+
The state the configuration should be left in.
+
Refer to examples for more details.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. + - See `the Junos OS Platform Options `_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # vagrant@vsrx# show system syslog + # + # [edit] + # vagrant@vsrx# show routing-instances + # inst11 { + # description inst11; + # } + - name: Merge provided logging configuration into running configuration. + junipernetworks.junos.junos_logging_global: + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: 65578 + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: 65578 + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: merged + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "allow_duplicates": true, + # "archive": { + # "file_size": 65578, + # "files": 10, + # "no_binary_data": true, + # "no_world_readable": true + # }, + # "console": { + # "any": { + # "level": "info" + # }, + # "authorization": { + # "level": "any" + # }, + # "change_log": { + # "level": "critical" + # }, + # "ftp": { + # "level": "none" + # } + # }, + # "files": [ + # { + # "allow_duplicates": true, + # "name": "file101" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "file102", + # "structured_data": { + # "set": true + # } + # }, + # { + # "archive": { + # "file_size": 65578, + # "files": 10, + # "no_binary_data": true, + # "no_world_readable": true + # }, + # "explicit_priority": true, + # "match": "^set*", + # "match_strings": [ + # "^delete", + # "^prompt" + # ], + # "name": "file103" + # } + # ], + # "hosts": [ + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "exclude_hostname": true, + # "facility_override": "ftp", + # "log_prefix": "field", + # "match": "^set*", + # "match_strings": [ + # "^delete", + # "^prompt" + # ], + # "name": "host111", + # "port": 1231, + # "routing_instance": "inst11", + # "source_address": "11.1.1.11", + # "structured_data": { + # "brief": true + # } + # } + # ], + # "log_rotate_frequency": 45, + # "routing_instance": "inst11", + # "source_address": "33.33.33.33", + # "time_format": { + # "millisecond": true, + # "year": true + # }, + # "users": [ + # { + # "allow_duplicates": true, + # "name": "user1" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "user2", + # "user": { + # "level": "info" + # } + # } + # ] + # }, + # "before": {}, + # "changed": true, + # "commands": [ + # "" + # "10" + # "65578" + # "change-log" + # "anyauthorization" + # "ftp" + # "file101file102" + # "any" + # "file10310" + # "65578" + # "^set*^delete" + # "^prompthost111" + # "any" + # "ftp" + # "field^set*^delete" + # "^prompt1231" + # "inst1111.1.1.11" + # "" + # "45inst11" + # "33.33.33.33" + # "user1" + # "user2any" + # "user" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show system syslog + # archive size 65578 files 10 no-world-readable no-binary-data; + # user user1 { + # allow-duplicates; + # } + # user user2 { + # any any; + # user info; + # allow-duplicates; + # } + # host host111 { + # any any; + # match "^set*"; + # allow-duplicates; + # port 1231; + # facility-override ftp; + # log-prefix field; + # source-address 11.1.1.11; + # routing-instance inst11; + # exclude-hostname; + # match-strings [ "^delete" "^prompt" ]; + # structured-data { + # brief; + # } + # } + # allow-duplicates; + # file file101 { + # allow-duplicates; + # } + # file file102 { + # any any; + # allow-duplicates; + # structured-data; + # } + # file file103 { + # match "^set*"; + # archive size 65578 files 10 no-world-readable no-binary-data; + # explicit-priority; + # match-strings [ "^delete" "^prompt" ]; + # } + # console { + # any info; + # authorization any; + # ftp none; + # change-log critical; + # } + # time-format year millisecond; + # source-address 33.33.33.33; + # routing-instance inst11; + # log-rotate-frequency 45; + # Using replaced + # + # Before state + # ------------ + # + # vagrant@vsrx# show system syslog + # archive size 65578 files 10 no-world-readable no-binary-data; + # user user1 { + # allow-duplicates; + # } + # user user2 { + # any any; + # user info; + # allow-duplicates; + # } + # host host111 { + # any any; + # match "^set*"; + # allow-duplicates; + # port 1231; + # facility-override ftp; + # log-prefix field; + # source-address 11.1.1.11; + # routing-instance inst11; + # exclude-hostname; + # match-strings [ "^delete" "^prompt" ]; + # structured-data { + # brief; + # } + # } + # allow-duplicates; + # file file101 { + # allow-duplicates; + # } + # file file102 { + # any any; + # allow-duplicates; + # structured-data; + # } + # file file103 { + # match "^set*"; + # archive size 65578 files 10 no-world-readable no-binary-data; + # explicit-priority; + # match-strings [ "^delete" "^prompt" ]; + # } + # console { + # any info; + # authorization any; + # ftp none; + # change-log critical; + # } + # time-format year millisecond; + # source-address 33.33.33.33; + # routing-instance inst11; + # log-rotate-frequency 45; + - name: Replaced running logging global configuration with provided configuration + junipernetworks.junos.junos_logging_global: + config: + files: + - name: "file104" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + hosts: + - name: host222 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: replaced + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "files": [ + # { + # "allow_duplicates": true, + # "name": "file104" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "file102", + # "structured_data": { + # "set": true + # } + # } + # ], + # "hosts": [ + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "exclude_hostname": true, + # "facility_override": "ftp", + # "log_prefix": "field", + # "match": "^set*", + # "match_strings": [ + # "^delete", + # "^prompt" + # ], + # "name": "host222", + # "port": 1231, + # "routing_instance": "inst11", + # "source_address": "11.1.1.11", + # "structured_data": { + # "brief": true + # } + # } + # ], + # "users": [ + # { + # "allow_duplicates": true, + # "name": "user1" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "user2", + # "user": { + # "level": "info" + # } + # } + # ] + # }, + # "before": { + # "allow_duplicates": true, + # "archive": { + # "file_size": 65578, + # "files": 10, + # "no_binary_data": true, + # "no_world_readable": true + # }, + # "console": { + # "any": { + # "level": "info" + # }, + # "authorization": { + # "level": "any" + # }, + # "change_log": { + # "level": "critical" + # }, + # "ftp": { + # "level": "none" + # } + # }, + # "files": [ + # { + # "allow_duplicates": true, + # "name": "file101" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "file102", + # "structured_data": { + # "set": true + # } + # }, + # { + # "archive": { + # "file_size": 65578, + # "files": 10, + # "no_binary_data": true, + # "no_world_readable": true + # }, + # "explicit_priority": true, + # "match": "^set*", + # "match_strings": [ + # "^delete", + # "^prompt" + # ], + # "name": "file103" + # } + # ], + # "hosts": [ + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "exclude_hostname": true, + # "facility_override": "ftp", + # "log_prefix": "field", + # "match": "^set*", + # "match_strings": [ + # "^delete", + # "^prompt" + # ], + # "name": "host111", + # "port": 1231, + # "routing_instance": "inst11", + # "source_address": "11.1.1.11", + # "structured_data": { + # "brief": true + # } + # } + # ], + # "log_rotate_frequency": 45, + # "routing_instance": "inst11", + # "source_address": "33.33.33.33", + # "time_format": { + # "millisecond": true, + # "year": true + # }, + # "users": [ + # { + # "allow_duplicates": true, + # "name": "user1" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "user2", + # "user": { + # "level": "info" + # } + # } + # ] + # }, + # "changed": true, + # "commands": [ + # "" + # "file104" + # "file102" + # "any" + # "host222any" + # "ftp" + # "field^set*" + # "^delete" + # "^prompt1231" + # "inst1111.1.1.11" + # "user1" + # "user2" + # "any" + # "user" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show system syslog + # user user1 { + # allow-duplicates; + # } + # user user2 { + # any any; + # user info; + # allow-duplicates; + # } + # host host222 { + # any any; + # match "^set*"; + # allow-duplicates; + # port 1231; + # facility-override ftp; + # log-prefix field; + # source-address 11.1.1.11; + # routing-instance inst11; + # exclude-hostname; + # match-strings [ "^delete" "^prompt" ]; + # structured-data { + # brief; + # } + # } + # file file104 { + # allow-duplicates; + # } + # file file102 { + # any any; + # allow-duplicates; + # structured-data; + # } + # Using overridden + # + # Before state + # ------------ + # + # vagrant@vsrx# show system syslog + # archive size 65578 files 10 no-world-readable no-binary-data; + # user user1 { + # allow-duplicates; + # } + # user user2 { + # any any; + # user info; + # allow-duplicates; + # } + # host host111 { + # any any; + # match "^set*"; + # allow-duplicates; + # port 1231; + # facility-override ftp; + # log-prefix field; + # source-address 11.1.1.11; + # routing-instance inst11; + # exclude-hostname; + # match-strings [ "^delete" "^prompt" ]; + # structured-data { + # brief; + # } + # } + # allow-duplicates; + # file file101 { + # allow-duplicates; + # } + # file file102 { + # any any; + # allow-duplicates; + # structured-data; + # } + # file file103 { + # match "^set*"; + # archive size 65578 files 10 no-world-readable no-binary-data; + # explicit-priority; + # match-strings [ "^delete" "^prompt" ]; + # } + # console { + # any info; + # authorization any; + # ftp none; + # change-log critical; + # } + # time-format year millisecond; + # source-address 33.33.33.33; + # routing-instance inst11; + # log-rotate-frequency 45; + - name: Override running logging global configuration with provided configuration + junipernetworks.junos.junos_logging_global: + config: + files: + - name: "file104" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + hosts: + - name: host222 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: overridden + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "files": [ + # { + # "allow_duplicates": true, + # "name": "file104" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "file102", + # "structured_data": { + # "set": true + # } + # } + # ], + # "hosts": [ + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "exclude_hostname": true, + # "facility_override": "ftp", + # "log_prefix": "field", + # "match": "^set*", + # "match_strings": [ + # "^delete", + # "^prompt" + # ], + # "name": "host222", + # "port": 1231, + # "routing_instance": "inst11", + # "source_address": "11.1.1.11", + # "structured_data": { + # "brief": true + # } + # } + # ], + # "users": [ + # { + # "allow_duplicates": true, + # "name": "user1" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "user2", + # "user": { + # "level": "info" + # } + # } + # ] + # }, + # "before": { + # "allow_duplicates": true, + # "archive": { + # "file_size": 65578, + # "files": 10, + # "no_binary_data": true, + # "no_world_readable": true + # }, + # "console": { + # "any": { + # "level": "info" + # }, + # "authorization": { + # "level": "any" + # }, + # "change_log": { + # "level": "critical" + # }, + # "ftp": { + # "level": "none" + # } + # }, + # "files": [ + # { + # "allow_duplicates": true, + # "name": "file101" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "file102", + # "structured_data": { + # "set": true + # } + # }, + # { + # "archive": { + # "file_size": 65578, + # "files": 10, + # "no_binary_data": true, + # "no_world_readable": true + # }, + # "explicit_priority": true, + # "match": "^set*", + # "match_strings": [ + # "^delete", + # "^prompt" + # ], + # "name": "file103" + # } + # ], + # "hosts": [ + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "exclude_hostname": true, + # "facility_override": "ftp", + # "log_prefix": "field", + # "match": "^set*", + # "match_strings": [ + # "^delete", + # "^prompt" + # ], + # "name": "host111", + # "port": 1231, + # "routing_instance": "inst11", + # "source_address": "11.1.1.11", + # "structured_data": { + # "brief": true + # } + # } + # ], + # "log_rotate_frequency": 45, + # "routing_instance": "inst11", + # "source_address": "33.33.33.33", + # "time_format": { + # "millisecond": true, + # "year": true + # }, + # "users": [ + # { + # "allow_duplicates": true, + # "name": "user1" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "user2", + # "user": { + # "level": "info" + # } + # } + # ] + # }, + # "changed": true, + # "commands": [ + # "" + # "file104" + # "file102" + # "any" + # "host222any" + # "ftp" + # "field^set*" + # "^delete" + # "^prompt1231" + # "inst1111.1.1.11" + # "user1" + # "user2" + # "any" + # "user" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show system syslog + # user user1 { + # allow-duplicates; + # } + # user user2 { + # any any; + # user info; + # allow-duplicates; + # } + # host host222 { + # any any; + # match "^set*"; + # allow-duplicates; + # port 1231; + # facility-override ftp; + # log-prefix field; + # source-address 11.1.1.11; + # routing-instance inst11; + # exclude-hostname; + # match-strings [ "^delete" "^prompt" ]; + # structured-data { + # brief; + # } + # } + # file file104 { + # allow-duplicates; + # } + # file file102 { + # any any; + # allow-duplicates; + # structured-data; + # } + # Using deleted + # + # Before state + # ------------ + # + # vagrant@vsrx# show system syslog + # user user1 { + # allow-duplicates; + # } + # user user2 { + # any any; + # user info; + # allow-duplicates; + # } + # host host222 { + # any any; + # match "^set*"; + # allow-duplicates; + # port 1231; + # facility-override ftp; + # log-prefix field; + # source-address 11.1.1.11; + # routing-instance inst11; + # exclude-hostname; + # match-strings [ "^delete" "^prompt" ]; + # structured-data { + # brief; + # } + # } + # file file104 { + # allow-duplicates; + # } + # file file102 { + # any any; + # allow-duplicates; + # structured-data; + # } + - name: Delete running logging global configuration + junipernetworks.junos.junos_logging_global: + config: + state: deleted + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": {}, + # "before": { + # "files": [ + # { + # "allow_duplicates": true, + # "name": "file104" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "file102", + # "structured_data": { + # "set": true + # } + # } + # ], + # "hosts": [ + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "exclude_hostname": true, + # "facility_override": "ftp", + # "log_prefix": "field", + # "match": "^set*", + # "match_strings": [ + # "^delete", + # "^prompt" + # ], + # "name": "host222", + # "port": 1231, + # "routing_instance": "inst11", + # "source_address": "11.1.1.11", + # "structured_data": { + # "brief": true + # } + # } + # ], + # "users": [ + # { + # "allow_duplicates": true, + # "name": "user1" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "user2", + # "user": { + # "level": "info" + # } + # } + # ] + # }, + # "changed": true, + # "commands": [ + # "" + # "" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show system syslog + # + # [edit] + # Using gathered + # + # Before state + # ------------ + # + # vagrant@vsrx# show system syslog + # user user1 { + # allow-duplicates; + # } + # user user2 { + # any any; + # user info; + # allow-duplicates; + # } + # host host222 { + # any any; + # match "^set*"; + # allow-duplicates; + # port 1231; + # facility-override ftp; + # log-prefix field; + # source-address 11.1.1.11; + # routing-instance inst11; + # exclude-hostname; + # match-strings [ "^delete" "^prompt" ]; + # structured-data { + # brief; + # } + # } + # file file104 { + # allow-duplicates; + # } + # file file102 { + # any any; + # allow-duplicates; + # structured-data; + # } + - name: Gather running logging global configuration + junipernetworks.junos.junos_logging_global: + state: gathered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "gathered": { + # "files": [ + # { + # "allow_duplicates": true, + # "name": "file104" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "file102", + # "structured_data": { + # "set": true + # } + # } + # ], + # "hosts": [ + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "exclude_hostname": true, + # "facility_override": "ftp", + # "log_prefix": "field", + # "match": "^set*", + # "match_strings": [ + # "^delete", + # "^prompt" + # ], + # "name": "host222", + # "port": 1231, + # "routing_instance": "inst11", + # "source_address": "11.1.1.11", + # "structured_data": { + # "brief": true + # } + # } + # ], + # "users": [ + # { + # "allow_duplicates": true, + # "name": "user1" + # }, + # { + # "allow_duplicates": true, + # "any": { + # "level": "any" + # }, + # "name": "user2", + # "user": { + # "level": "info" + # } + # } + # ] + # }, + # "changed": false, + # Using rendered + # + # Before state + # ------------ + # + - name: Render xml for provided facts. + junipernetworks.junos.junos_logging_global: + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: 65578 + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: 65578 + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: rendered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "rendered": [ + # "" + # "10" + # "65578" + # "change-log" + # "anyauthorization" + # "ftp" + # "file101file102" + # "any" + # "file10310" + # "65578" + # "^set*^delete" + # "^prompthost111" + # "any" + # "ftp" + # "field^set*^delete" + # "^prompt1231" + # "inst1111.1.1.11" + # "" + # "45inst11" + # "33.33.33.33" + # "user1" + # "user2any" + # "user" + # ] + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # + # + # * + # + # any + # + # + # + # + # messages + # + # any + # + # + # + # authorization + # + # + # + # + # interactive-commands + # + # interactive-commands + # + # + # + # + # + # + # + - name: Parse logging global running config + junipernetworks.junos.junos_routing_instances: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # + # "parsed": { + # "files": [ + # { + # "any": { + # "level": "any" + # }, + # "authorization": { + # "level": "info" + # }, + # "name": "messages" + # }, + # { + # "interactive_commands": { + # "level": "any" + # }, + # "name": "interactive-commands" + # } + # ], + # "users": [ + # { + # "any": { + # "level": "emergency" + # }, + # "name": "*" + # } + # ] + # } + # + # + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:allow-duplicates/></nc:user><nc:user><nc:name>user2</nc:name> <nc:allow-duplicates/><nc:contents><nc:name>any</nc:name><nc:any/> </nc:contents><nc:contents><nc:name>user</nc:name><nc:info/></nc:contents> </nc:user></nc:syslog></nc:system>"', 'xml 2', 'xml 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Rohit Thakur (@rohitthakur2590) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_netconf.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_netconf.rst new file mode 100644 index 00000000..fef45678 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_netconf.rst @@ -0,0 +1,76 @@ +.. _junipernetworks.junos.junos_netconf: + + +*************************** +junipernetworks.junos.junos +*************************** + +**Use junos netconf plugin to run netconf commands on Juniper JUNOS platform** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This junos plugin provides low level abstraction apis for sending and receiving netconf commands from Juniper JUNOS network devices. + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + +
ParameterChoices/DefaultsConfigurationComments
+
+ ncclient_device_handler + +
+ string +
+
+ Default:
"junos"
+
+ +
Specifies the ncclient device handler name for Juniper junos network os. To identify the ncclient device handler name refer ncclient library documentation.
+
+
+ + + + + + + + +Status +------ + + +Authors +~~~~~~~ + +- Ansible Networking Team (@ansible-network) + + +.. hint:: + Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up. diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_netconf_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_netconf_module.rst new file mode 100644 index 00000000..9f2e3aa7 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_netconf_module.rst @@ -0,0 +1,146 @@ +.. _junipernetworks.junos.junos_netconf_module: + + +*********************************** +junipernetworks.junos.junos_netconf +*********************************** + +**Configures the Junos Netconf system service** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module provides an abstraction that enables and configures the netconf system service running on Junos devices. This module can be used to easily enable the Netconf API. Netconf provides a programmatic interface for working with configuration and state resources as defined in RFC 6242. If the ``netconf_port`` is not mentioned in the task by default netconf will be enabled on port 830 only. + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ netconf_port + +
+ integer +
+
+ Default:
830
+
+
This argument specifies the port the netconf service should listen on for SSH connections. The default port as defined in RFC 6242 is 830.
+

aliases: listens_on
+
+
+ state + +
+ string +
+
+
    Choices: +
  • present ←
  • +
  • absent
  • +
+
+
Specifies the state of the junos_netconf resource on the remote device. If the state argument is set to present the netconf service will be configured. If the state argument is set to absent the netconf service will be removed from the configuration.
+
+
+ + +Notes +----- + +.. note:: + - Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. + - Recommended connection is ``network_cli``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - This module also works with ``local`` connections for legacy playbooks. + - If ``netconf_port`` value is not mentioned in task by default it will be enabled on port 830 only. Although ``netconf_port`` value can be from 1 through 65535, avoid configuring access on a port that is normally assigned for another service. This practice avoids potential resource conflicts. + - For information on using CLI and netconf see the :ref:`Junos OS Platform Options guide ` + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` + - For more information on using Ansible to manage Juniper network devices see https://www.ansible.com/ansible-juniper. + + + +Examples +-------- + +.. code-block:: yaml + + - name: enable netconf service on port 830 + junipernetworks.junos.junos_netconf: + listens_on: 830 + state: present + + - name: disable netconf service + junipernetworks.junos.junos_netconf: + state: absent + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + +
KeyReturnedDescription
+
+ commands + +
+ string +
+
when changed is True +
Returns the command sent to the remote device
+
+
Sample:
+
set system services netconf ssh port 830
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Peter Sprygada (@privateip) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ntp_global_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ntp_global_module.rst new file mode 100644 index 00000000..0aaeb963 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ntp_global_module.rst @@ -0,0 +1,1551 @@ +.. _junipernetworks.junos.junos_ntp_global_module: + + +************************************** +junipernetworks.junos.junos_ntp_global +************************************** + +**Manage NTP configuration on Junos devices.** + + +Version added: 2.6.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages NTP configuration on devices running Junos. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
A dictionary of NTP configuration.
+
+
+ authentication_keys + +
+ list + / elements=dictionary +
+
+ +
NTP authentication key.
+
+
+ algorithm + +
+ string +
+
+
    Choices: +
  • md5
  • +
  • sha1
  • +
  • sha256
  • +
+
+
Authentication key type.
+
+
+ id + +
+ integer +
+
+ +
Authentication key number.
+
+
+ key + +
+ string +
+
+ +
Authentication key value.
+
+
+ boot_server + +
+ string +
+
+ +
Server to query during boot sequence.
+
+
+ broadcast_client + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Listen to broadcast NTP.
+
+
+ broadcasts + +
+ list + / elements=dictionary +
+
+ +
Broadcast parameters.
+
+
+ address + +
+ string +
+
+ +
Broadcast or multicast address to use.
+
+
+ key + +
+ string +
+
+ +
Authentication key.
+
+
+ routing_instance_name + +
+ string +
+
+ +
Routing intance name in which interface has address in broadcast subnet.
+
+
+ ttl + +
+ integer +
+
+ +
TTL value to transmit.
+
+
+ version + +
+ integer +
+
+ +
NTP version to use.
+
+
+ interval_range + +
+ integer +
+
+ +
Set the minpoll and maxpoll interval range.
+
+
+ multicast_client + +
+ string +
+
+ +
Listen to multicast NTP address.
+
+
+ peers + +
+ list + / elements=dictionary +
+
+ +
NTP Peers.
+
+
+ key_id + +
+ integer +
+
+ +
Key-id to be used while communicating.
+
+
+ peer + +
+ string +
+
+ +
Hostname/IP address of the NTP Peer.
+
+
+ prefer + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Prefer this peer.
+
+
+ version + +
+ integer +
+
+ +
NTP version to use.
+
+
+ servers + +
+ list + / elements=dictionary +
+
+ +
NTP Servers.
+
+
+ key_id + +
+ integer +
+
+ +
Key-id to be used while communicating.
+
+
+ prefer + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Prefer this peer_serv.
+
+
+ routing_instance + +
+ string +
+
+ +
Routing instance through which server is reachable.
+
+
+ server + +
+ string +
+
+ +
IP address or hostname of the server.
+
+
+ version + +
+ integer +
+
+ +
NTP version to use.
+
+
+ source_addresses + +
+ list + / elements=dictionary +
+
+ +
Source-Address parameters.
+
+
+ routing_instance + +
+ string +
+
+ +
Routing intance name in which source address is defined.
+
+
+ source_address + +
+ string +
+
+ +
Use specified address as source address.
+
+
+ threshold + +
+ dictionary +
+
+ +
Set the maximum threshold(sec) allowed for NTP adjustment.
+
+
+ action + +
+ string +
+
+
    Choices: +
  • accept
  • +
  • reject
  • +
+
+
Select actions for NTP abnormal adjustment.
+
+
+ value + +
+ integer +
+
+ +
The maximum value(sec) allowed for NTP adjustment.
+
+
+ trusted_keys + +
+ list + / elements=dictionary +
+
+ +
List of trusted authentication keys.
+
+
+ key_id + +
+ integer +
+
+ +
Trusted-Key number.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show system syslog.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • deleted
  • +
  • overridden
  • +
  • parsed
  • +
  • gathered
  • +
  • rendered
  • +
+
+
The state the configuration should be left in.
+
The states replaced and overridden have identical behaviour for this module.
+
Refer to examples for more details.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. + - See `the Junos OS Platform Options `_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # vagrant@vsrx# show system ntp + # + # [edit] + # vagrant@vsrx# show routing-instances + # rt1 { + # description rt1; + # } + # rt2 { + - name: Merge provided NTP configuration into running configuration. + junipernetworks.junos.junos_ntp_global: + config: + boot_server: '78.46.194.186' + broadcasts: + - address: '172.16.255.255' + key: '50' + ttl: 200 + version: 3 + routing_instance_name: 'rt1' + - address: '192.16.255.255' + key: '50' + ttl: 200 + version: 3 + routing_instance_name: 'rt2' + broadcast_client: true + interval_range: 2 + multicast_client: "224.0.0.1" + peers: + - peer: "78.44.194.186" + - peer: "172.44.194.186" + key_id: 10000 + prefer: true + version: 3 + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: 'rt1' + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + source_addresses: + - source_address: "172.45.194.186" + routing_instance: 'rt1' + - source_address: "171.45.194.186" + routing_instance: 'rt2' + threshold: + value: 300 + action: "accept" + trusted_keys: + - key_id: 3000 + - key_id: 2000 + state: merged + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "boot_server": "78.46.194.186", + # "broadcast_client": true, + # "broadcasts": [ + # { + # "address": "172.16.255.255", + # "key": "50", + # "routing_instance_name": "rt1", + # "ttl": 200, + # "version": 3 + # }, + # { + # "address": "192.16.255.255", + # "key": "50", + # "routing_instance_name": "rt2", + # "ttl": 200, + # "version": 3 + # } + # ], + # "interval_range": 2, + # "multicast_client": "224.0.0.1", + # "peers": [ + # { + # "peer": "78.44.194.186" + # }, + # { + # "key_id": 10000, + # "peer": "172.44.194.186", + # "prefer": true, + # "version": 3 + # } + # ], + # "servers": [ + # { + # "key_id": 34, + # "prefer": true, + # "routing_instance": "rt1", + # "server": "48.46.194.186", + # "version": 2 + # }, + # { + # "key_id": 34, + # "prefer": true, + # "server": "48.45.194.186", + # "version": 2 + # } + # ], + # "source_addresses": [ + # { + # "routing_instance": "rt1", + # "source_address": "172.45.194.186" + # }, + # { + # "routing_instance": "rt2", + # "source_address": "171.45.194.186" + # } + # ], + # "threshold": { + # "action": "accept", + # "value": 300 + # }, + # "trusted_keys": [ + # {"key_id": 2000}, + # {"key_id": 3000} + # ] + # }, + # "before": {}, + # "changed": true, + # "commands": [ + # "" + # "78.46.194.186" + # "172.16.255.25550rt1" + # "2003192.16.255.255" + # "50rt2200" + # "32" + # "224.0.0.178.44.194.186" + # "172.44.194.186100003" + # "48.46.194.18634rt1" + # "248.45.194.18634" + # "2172.45.194.186" + # "rt1" + # "171.45.194.186rt2" + # "300accept" + # "30002000" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show system ntp + # boot-server 78.46.194.186; + # interval-range 2; + # peer 78.44.194.186; + # peer 172.44.194.186 key 10000 version 3 prefer; ## SECRET-DATA + # server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA + # server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA + # broadcast 172.16.255.255 routing-instance-name rt1 key 50 version 3 ttl 200; + # broadcast 192.16.255.255 routing-instance-name rt2 key 50 version 3 ttl 200; + # broadcast-client; + # multicast-client 224.0.0.1; + # trusted-key [ 3000 2000 ]; + # threshold 300 action accept; + # source-address 172.45.194.186 routing-instance rt1; + # source-address 171.45.194.186 routing-instance rt2; + # + # + # Using Replaced + # Before state + # ------------ + # + # vagrant@vsrx# show system ntp + # boot-server 78.46.194.186; + # interval-range 2; + # peer 78.44.194.186; + # peer 172.44.194.186 key 10000 version 3 prefer; ## SECRET-DATA + # server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA + # server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA + # broadcast 172.16.255.255 routing-instance-name rt1 key 50 version 3 ttl 200; + # broadcast 192.16.255.255 routing-instance-name rt2 key 50 version 3 ttl 200; + # broadcast-client; + # multicast-client 224.0.0.1; + # trusted-key [ 3000 2000 ]; + # threshold 300 action accept; + # source-address 172.45.194.186 routing-instance rt1; + # source-address 171.45.194.186 routing-instance rt2; + + - name: Replaced running ntp global configuration with provided configuration + junipernetworks.junos.junos_ntp_global: + config: + authentication_keys: + - id: 2 + algorithm: 'md5' + key: 'asdfghd' + - id: 5 + algorithm: 'sha1' + key: 'aasdad' + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: 'rt1' + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + state: replaced + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "authentication_keys": [ + # { + # "algorithm": "md5", + # "id": 2, + # "key": "$9$03aAB1hreW7NbO1rvMLVbgoJ" + # }, + # { + # "algorithm": "sha1", + # "id": 5, + # "key": "$9$DXiHmf5F/A0ZUjq.P3n" + # } + # ], + # "servers": [ + # { + # "key_id": 34, + # "prefer": true, + # "routing_instance": "rt1", + # "server": "48.46.194.186", + # "version": 2 + # }, + # { + # "key_id": 34, + # "prefer": true, + # "server": "48.45.194.186", + # "version": 2 + # } + # ] + # }, + # "before": { + # "boot_server": "78.46.194.186", + # "broadcast_client": true, + # "broadcasts": [ + # { + # "address": "172.16.255.255", + # "key": "50", + # "routing_instance_name": "rt1", + # "ttl": 200, + # "version": 3 + # }, + # { + # "address": "192.16.255.255", + # "key": "50", + # "routing_instance_name": "rt2", + # "ttl": 200, + # "version": 3 + # } + # ], + # "interval_range": 2, + # "multicast_client": "224.0.0.1", + # "peers": [ + # { + # "peer": "78.44.194.186" + # }, + # { + # "key_id": 10000, + # "peer": "172.44.194.186", + # "prefer": true, + # "version": 3 + # } + # ], + # "servers": [ + # { + # "key_id": 34, + # "prefer": true, + # "routing_instance": "rt1", + # "server": "48.46.194.186", + # "version": 2 + # }, + # { + # "key_id": 34, + # "prefer": true, + # "server": "48.45.194.186", + # "version": 2 + # } + # ], + # "source_addresses": [ + # { + # "routing_instance": "rt1", + # "source_address": "172.45.194.186" + # }, + # { + # "routing_instance": "rt2", + # "source_address": "171.45.194.186" + # } + # ], + # "threshold": { + # "action": "accept", + # "value": 300 + # }, + # "trusted_keys": [ + # {"key_id": 2000}, + # {"key_id": 3000} + # ] + # }, + # "changed": true, + # "commands": [ + # " + # "2md5 + # "asdfghd5 + # "sha1aasdad + # "48.46.194.18634rt1 + # "248.45.194.186 + # "342" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show system ntp + # authentication-key 2 type md5 value "$9$03aAB1hreW7NbO1rvMLVbgoJ"; ## SECRET-DATA + # authentication-key 5 type sha1 value "$9$DXiHmf5F/A0ZUjq.P3n"; ## SECRET-DATA + # server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA + # server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA + + # Using overridden + # + # Before state + # ------------ + # + # vagrant@vsrx# show system ntp + # boot-server 78.46.194.186; + # interval-range 2; + # peer 78.44.194.186; + # peer 172.44.194.186 key 10000 version 3 prefer; ## SECRET-DATA + # server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA + # server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA + # broadcast 172.16.255.255 routing-instance-name rt1 key 50 version 3 ttl 200; + # broadcast 192.16.255.255 routing-instance-name rt2 key 50 version 3 ttl 200; + # broadcast-client; + # multicast-client 224.0.0.1; + # trusted-key [ 3000 2000 ]; + # threshold 300 action accept; + # source-address 172.45.194.186 routing-instance rt1; + # source-address 171.45.194.186 routing-instance rt2; + + - name: Override running ntp global configuration with provided configuration + junipernetworks.junos.junos_ntp_global: + config: + authentication_keys: + - id: 2 + algorithm: 'md5' + key: 'asdfghd' + - id: 5 + algorithm: 'sha1' + key: 'aasdad' + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: 'rt1' + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + state: overridden + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "authentication_keys": [ + # { + # "algorithm": "md5", + # "id": 2, + # "key": "$9$03aAB1hreW7NbO1rvMLVbgoJ" + # }, + # { + # "algorithm": "sha1", + # "id": 5, + # "key": "$9$DXiHmf5F/A0ZUjq.P3n" + # } + # ], + # "servers": [ + # { + # "key_id": 34, + # "prefer": true, + # "routing_instance": "rt1", + # "server": "48.46.194.186", + # "version": 2 + # }, + # { + # "key_id": 34, + # "prefer": true, + # "server": "48.45.194.186", + # "version": 2 + # } + # ] + # }, + # "before": { + # "boot_server": "78.46.194.186", + # "broadcast_client": true, + # "broadcasts": [ + # { + # "address": "172.16.255.255", + # "key": "50", + # "routing_instance_name": "rt1", + # "ttl": 200, + # "version": 3 + # }, + # { + # "address": "192.16.255.255", + # "key": "50", + # "routing_instance_name": "rt2", + # "ttl": 200, + # "version": 3 + # } + # ], + # "interval_range": 2, + # "multicast_client": "224.0.0.1", + # "peers": [ + # { + # "peer": "78.44.194.186" + # }, + # { + # "key_id": 10000, + # "peer": "172.44.194.186", + # "prefer": true, + # "version": 3 + # } + # ], + # "servers": [ + # { + # "key_id": 34, + # "prefer": true, + # "routing_instance": "rt1", + # "server": "48.46.194.186", + # "version": 2 + # }, + # { + # "key_id": 34, + # "prefer": true, + # "server": "48.45.194.186", + # "version": 2 + # } + # ], + # "source_addresses": [ + # { + # "routing_instance": "rt1", + # "source_address": "172.45.194.186" + # }, + # { + # "routing_instance": "rt2", + # "source_address": "171.45.194.186" + # } + # ], + # "threshold": { + # "action": "accept", + # "value": 300 + # }, + # "trusted_keys": [ + # {"key_id": 2000}, + # {"key_id": 3000} + # ] + # }, + # "changed": true, + # "commands": [ + # " + # "2md5 + # "asdfghd5 + # "sha1aasdad + # "48.46.194.18634rt1 + # "248.45.194.186 + # "342" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show system ntp + # authentication-key 2 type md5 value "$9$03aAB1hreW7NbO1rvMLVbgoJ"; ## SECRET-DATA + # authentication-key 5 type sha1 value "$9$DXiHmf5F/A0ZUjq.P3n"; ## SECRET-DATA + # server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA + # server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA + # + # Using deleted + # + # Before state + # ------------ + # + # vagrant@vsrx# show system ntp + # authentication-key 2 type md5 value "$9$03aAB1hreW7NbO1rvMLVbgoJ"; ## SECRET-DATA + # authentication-key 5 type sha1 value "$9$DXiHmf5F/A0ZUjq.P3n"; ## SECRET-DATA + # server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA + # server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA + # + - name: Delete running NTP global configuration + junipernetworks.junos.junos_ntp_global: + config: + state: deleted + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": {}, + # "before": { + # "authentication_keys": [ + # { + # "algorithm": "md5", + # "id": 2, + # "key": "$9$03aAB1hreW7NbO1rvMLVbgoJ" + # }, + # { + # "algorithm": "sha1", + # "id": 5, + # "key": "$9$DXiHmf5F/A0ZUjq.P3n" + # } + # ], + # "servers": [ + # { + # "key_id": 34, + # "prefer": true, + # "routing_instance": "rt1", + # "server": "48.46.194.186", + # "version": 2 + # }, + # { + # "key_id": 34, + # "prefer": true, + # "server": "48.45.194.186", + # "version": 2 + # } + # ] + # }, + # "changed": true, + # "commands": [ + # "" + # "" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show system ntp + # + # [edit] + # Using gathered + # + # Before state + # ------------ + # + # vagrant@vsrx# show system ntp + # boot-server 78.46.194.186; + # interval-range 2; + # peer 78.44.194.186; + # peer 172.44.194.186 key 10000 version 3 prefer; ## SECRET-DATA + # server 48.46.194.186 key 34 version 2 prefer routing-instance rt1; ## SECRET-DATA + # server 48.45.194.186 key 34 version 2 prefer; ## SECRET-DATA + # broadcast 172.16.255.255 routing-instance-name rt1 key 50 version 3 ttl 200; + # broadcast 192.16.255.255 routing-instance-name rt2 key 50 version 3 ttl 200; + # broadcast-client; + # multicast-client 224.0.0.1; + # trusted-key [ 3000 2000 ]; + # threshold 300 action accept; + # source-address 172.45.194.186 routing-instance rt1; + # source-address 171.45.194.186 routing-instance rt2; + - name: Gather running NTP global configuration + junipernetworks.junos.junos_ntp_global: + state: gathered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "gathered": { + # "boot_server": "78.46.194.186", + # "broadcast_client": true, + # "broadcasts": [ + # { + # "address": "172.16.255.255", + # "key": "50", + # "routing_instance_name": "rt1", + # "ttl": 200, + # "version": 3 + # }, + # { + # "address": "192.16.255.255", + # "key": "50", + # "routing_instance_name": "rt2", + # "ttl": 200, + # "version": 3 + # } + # ], + # "interval_range": 2, + # "multicast_client": "224.0.0.1", + # "peers": [ + # { + # "peer": "78.44.194.186" + # }, + # { + # "key_id": 10000, + # "peer": "172.44.194.186", + # "prefer": true, + # "version": 3 + # } + # ], + # "servers": [ + # { + # "key_id": 34, + # "prefer": true, + # "routing_instance": "rt1", + # "server": "48.46.194.186", + # "version": 2 + # }, + # { + # "key_id": 34, + # "prefer": true, + # "server": "48.45.194.186", + # "version": 2 + # } + # ], + # "source_addresses": [ + # { + # "routing_instance": "rt1", + # "source_address": "172.45.194.186" + # }, + # { + # "routing_instance": "rt2", + # "source_address": "171.45.194.186" + # } + # ], + # "threshold": { + # "action": "accept", + # "value": 300 + # }, + # "trusted_keys": [ + # {"key_id": 2000}, + # {"key_id": 3000} + # ] + # }, + # "changed": false, + # Using rendered + # + # Before state + # ------------ + # + - name: Render xml for provided facts. + junipernetworks.junos.junos_ntp_global: + config: + boot_server: '78.46.194.186' + broadcasts: + - address: '172.16.255.255' + key: '50' + ttl: 200 + version: 3 + routing_instance_name: 'rt1' + - address: '192.16.255.255' + key: '50' + ttl: 200 + version: 3 + routing_instance_name: 'rt2' + broadcast_client: true + interval_range: 2 + multicast_client: "224.0.0.1" + peers: + - peer: "78.44.194.186" + - peer: "172.44.194.186" + key_id: 10000 + prefer: true + version: 3 + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: 'rt1' + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + source_addresses: + - source_address: "172.45.194.186" + routing_instance: 'rt1' + - source_address: "171.45.194.186" + routing_instance: 'rt2' + threshold: + value: 300 + action: "accept" + trusted_keys: + - 3000 + - 2000 + state: rendered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "rendered": [ + # "" + # "78.46.194.186172.16.255.255" + # "50rt1200" + # "3192.16.255.255" + # "50rt2" + # "2003" + # "2224.0.0.1" + # "78.44.194.186172.44.194.186" + # "100003" + # "48.46.194.18634rt1" + # "248.45.194.186" + # "342" + # "172.45.194.186rt1" + # "171.45.194.186rt2" + # "300accept" + # "30002000" + # ] + # + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # + # + # 2 + # md5 + # $9$GxDjqfT3CA0UjfzF6u0RhS + # + # + # 5 + # sha1 + # $9$ZsUDk.mT3/toJGiHqQz + # + # + # + # + # + # + - name: Parse NTP global running config + junipernetworks.junos.junos_ntp_global: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # + # "parsed": { + # "authentication_keys": [ + # { + # "algorithm": "md5", + # "id": 2, + # "key": "$9$GxDjqfT3CA0UjfzF6u0RhS" + # }, + # { + # "algorithm": "sha1", + # "id": 5, + # "key": "$9$ZsUDk.mT3/toJGiHqQz" + # } + # ] + # } + # + # + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:name>78.44.194.186</nc:name></nc:peer><nc:peer><nc:name>172.44.194.186</nc:name>', 'xml 2', 'xml 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Rohit Thakur (@rohitthakur2590) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ospf_interfaces_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ospf_interfaces_module.rst new file mode 100644 index 00000000..8a68a001 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ospf_interfaces_module.rst @@ -0,0 +1,1223 @@ +.. _junipernetworks.junos.junos_ospf_interfaces_module: + + +******************************************* +junipernetworks.junos.junos_ospf_interfaces +******************************************* + +**OSPF Interfaces Resource Module.** + + +Version added: 1.3.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages OSPF(v2/v3) configuration of interfaces on devices running Juniper JUNOS. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
A list of OSPF configuration for interfaces.
+
+
+ address_family + +
+ list + / elements=dictionary +
+
+ +
OSPF settings on the interfaces in address-family context.
+
+
+ afi + +
+ string + / required +
+
+
    Choices: +
  • ipv4
  • +
  • ipv6
  • +
+
+
Address Family Identifier (AFI) for OSPF settings on the interfaces.
+
+
+ processes + +
+ dictionary +
+
+ +
Interfaces configuration for an OSPF process.
+
+
+ area + +
+ dictionary +
+
+ +
Specify the area-id
+
+
+ area_id + +
+ string +
+
+ +
Specify area id.
+
+
+ authentication + +
+ dictionary +
+
+ +
Specify authentication type
+
+
+ md5 + +
+ list + / elements=dictionary +
+
+ +
Specify md5 based authentication.
+
+
+ key_id + +
+ integer +
+
+ +
Specify md5 key-id
+
+
+ key_value + +
+ string +
+
+ +
Specify key value
+
+
+ start_time + +
+ string +
+
+ +
Specify start time for key transmission
+
+
+ simple_password + +
+ string +
+
+ +
Specify password for authentication.
+
+
+ bandwidth_based_metrics + +
+ list + / elements=dictionary +
+
+ +
Specify list of bandwidth based metrics
+
+
+ bandwidth + +
+ string +
+
+
    Choices: +
  • 1g
  • +
  • 10g
  • +
+
+
BW to apply metric to.
+
+
+ metric + +
+ integer +
+
+ +
Specify metric
+
+
+ dead_interval + +
+ integer +
+
+ +
Dead interval (seconds).
+
+
+ demand_circuit + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Interface functions as a demand circuit.
+
+
+ flood_reduction + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable flood reduction.
+
+
+ hello_interval + +
+ integer +
+
+ +
Hello interval (seconds).
+
+
+ interface_type + +
+ string +
+
+
    Choices: +
  • nbma
  • +
  • p2mp
  • +
  • p2p
  • +
+
+
Specify type of interface
+
+
+ ipsec_sa + +
+ string +
+
+ +
IPSec security association name
+
+
+ metric + +
+ integer +
+
+ +
Metric applied to the interface.
+
+
+ mtu + +
+ integer +
+
+ +
Maximum OSPF packet size
+
+
+ no_advertise_adjacency_segment + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not advertise an adjacency segment for this interface.
+
+
+ no_eligible_backup + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Not eligible to backup traffic from protected interfaces.
+
+
+ no_eligible_remote_backup + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Not eligible for Remote-LFA backup traffic from protected interfaces.
+
+
+ no_interface_state_traps + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not send interface state change traps.
+
+
+ no_neighbor_down_notification + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't inform other protocols about neighbor down events.
+
+
+ node_link_protection + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Protect interface from both link and node faults.
+
+
+ passive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not run OSPF, but advertise it.
+
+
+ poll_interval + +
+ integer +
+
+ +
Poll interval (seconds).
+
+
+ priority + +
+ integer +
+
+ +
Priority for the interface.
+
+
+ retransmit_interval + +
+ integer +
+
+ +
Retransmit interval (seconds).
+
+
+ secondary + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Treat interface as secondary
+
+
+ te_metric + +
+ integer +
+
+ +
Traffic engineering metric applied to the interface.
+
+
+ transit_delay + +
+ integer +
+
+ +
Transit delay (seconds).
+
+
+ name + +
+ string + / required +
+
+ +
Name/Identifier of the interface.
+
+
+ router_id + +
+ string +
+
+ +
The OSPF router id.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show protocols ospf.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • parsed
  • +
  • gathered
  • +
  • rendered
  • +
+
+
The state the configuration should be left in.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # admin# show protocols ospf + + - name: Merge Junos OSPF interfaces config + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: 'ge-0/0/2.0' + address_family: + - afi: 'ipv4' + processes: + area: + area_id: '0.0.0.2' + priority: 3 + metric: 5 + state: merged + + # After state + # ----------- + # + # admin# show protocols ospf + # area 0.0.0.2 { + # interface ge-0/0/2.0 { + # metric 5; + # priority 3; + # } + # } + + # Using replaced + # + # Before state + # ------------ + # + # admin# show protocols ospf + # area 0.0.0.2 { + # interface ge-0/0/2.0 { + # metric 5; + # priority 3; + # } + # } + - name: Replace Junos OSPF interfaces config + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: 'ge-0/0/2.0' + address_family: + - afi: 'ipv4' + processes: + area: + area_id: '0.0.0.1' + priority: 6 + metric: 6 + state: replaced + + # After state + # ----------- + # + # admin# show protocols ospf + # area 0.0.0.1 { + # interface ge-0/0/2.0 { + # metric 6; + # priority 6; + # } + # } + + # Using overridden + # + # Before state + # ------------ + # + # admin# show protocols ospf + # area 0.0.0.3 { + # interface ge-0/0/3.0 { + # metric 5; + # priority 3; + # } + # } + # area 0.0.0.2 { + # interface ge-0/0/2.0 { + # metric 5; + # priority 3; + # } + # } + + - name: Override Junos OSPF interfaces config + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: 'ge-0/0/1.0' + address_family: + - afi: 'ipv4' + processes: + area: + area_id: '0.0.0.1' + priority: 3 + metric: 5 + state: overridden + + # After state + # ----------- + # + # admin# show protocols ospf + # area 0.0.0.1 { + # interface ge-0/0/1.0 { + # metric 5; + # priority 3; + # } + # } + + # + # Using deleted + # + # Before state + # ------------ + # + # admin# show protocols ospf + # area 0.0.0.1 { + # interface ge-0/0/1.0 { + # metric 5; + # priority 3; + # } + # } + + - name: Delete Junos OSPF interfaces config + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: 'ge-0/0/1.0' + state: deleted + + # After state + # ----------- + # + # admin# show protocols ospf + # Using gathered + # + # Before state + # ------------ + # + # admin# show protocols ospf + # area 0.0.0.3 { + # interface ge-0/0/3.0 { + # metric 5; + # priority 3; + # } + # } + # area 0.0.0.2 { + # interface ge-0/0/2.0 { + # metric 5; + # priority 3; + # } + # } + + - name: Gather Junos OSPF interfaces config + junipernetworks.junos.junos_ospf_interfaces: + config: + state: gathered + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # "gathered": [ + # { + # "address_family": [ + # { + # "afi": "ipv4", + # "processes": { + # "area": { + # "area_id": "0.0.0.3" + # }, + # "metric": 5, + # "priority": 3 + # } + # } + # ], + # "name": "ge-0/0/3.0", + # }, + # { + # "address_family": [ + # { + # "afi": "ipv4", + # "processes": { + # "area": { + # "area_id": "0.0.0.2" + # }, + # "metric": 5, + # "priority": 3 + # } + # } + # ], + # "name": "ge-0/0/2.0", + # } + # ] + # + # Using rendered + # + # + - name: Render the commands for provided configuration + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: 'ge-0/0/2.0' + address_family: + - afi: 'ipv4' + processes: + area: + area_id: '0.0.0.2' + priority: 3 + metric: 5 + state: rendered + + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # + # "rendered": " + # + # + # + # 0.0.0.2 + # + # ge-0/0/2.0 + # 3 + # 5 + # + # + # + # " + # + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # + # + # + # 0.0.0.2 + # + # 200 + # + # + # ge-0/0/2.0 + # 5 + # 3 + # + # + # + # + # + # 10.200.16.75 + # + # + # + + + - name: Parsed the device configuration to get output commands + junipernetworks.junos.junos_ospf_interfaces: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # + # "parsed": [ + # { + # "address_family": [ + # { + # "afi": "ipv4", + # "processes": { + # "area": { + # "area_id": "0.0.0.2" + # }, + # "metric": 5, + # "priority": 3 + # } + # } + # ], + # "name": "ge-0/0/2.0", + # } + # ] + # + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:ospf> <nc:area> <nc:name>0.0.0.3</nc:name> <nc:interface> <nc:name>ge-0/0/3.0</nc:name> <nc:priority>3</nc:priority> <nc:metric>5</nc:metric> </nc:interface> </nc:area> <nc:area> <nc:name>0.0.0.2</nc:name> <nc:interface> <nc:name>ge-0/0/2.0</nc:name> <nc:priority>3</nc:priority> <nc:metric>5</nc:metric> </nc:interface> </nc:area> </nc:ospf> </nc:protocols>", " <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:router-id>10.200.16.75</nc:router-id> <nc:router-id>10.200.16.75</nc:router-id> </nc:routing-options>', 'xml 2', 'xml 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Rohit Thakur (@rohitthakur2590) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ospfv2_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ospfv2_module.rst new file mode 100644 index 00000000..18e04ea6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ospfv2_module.rst @@ -0,0 +1,1995 @@ +.. _junipernetworks.junos.junos_ospfv2_module: + + +********************************** +junipernetworks.junos.junos_ospfv2 +********************************** + +**OSPFv2 resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages OSPFv2 configuration on devices running Juniper JUNOS. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
A list of OSPFv2 process configuration.
+
+
+ areas + +
+ list + / elements=dictionary +
+
+ +
A list of OSPFv2 areas' configuration.
+
+
+ area_id + +
+ string + / required +
+
+ +
The Area ID as an integer or IP Address.
+
+
+ area_range + +
+ string +
+
+ +
Configure an address range for the area.
+
Included for compatibility, remove/deprecate after 2025-07-01.
+
Alternate for this would be area_ranges which is a list.
+
+
+ area_ranges + +
+ list + / elements=dictionary +
+
+ +
Configure IP address ranges for the area.
+
+
+ address + +
+ string +
+
+ +
Specify ip address.
+
+
+ exact + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enforce exact match for advertisement of this area range.
+
+
+ override_metric + +
+ integer +
+
+ +
Override the dynamic metric for this area-range.
+
+
+ restrict + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Restrict advertisement of this area range.
+
+
+ interfaces + +
+ list + / elements=dictionary +
+
+ +
List of interfaces in this area.
+
+
+ authentication + +
+ dictionary +
+
+ +
Specify authentication type
+
+
+ md5 + +
+ list + / elements=dictionary +
+
+ +
MD5 authentication keys
+
+
+ key + +
+ string +
+
+ +
Specify key value
+
+
+ key_id + +
+ integer +
+
+ +
Specify the key identity
+
+
+ start_time + +
+ string +
+
+ +
Specify Start time for key transmission (YYYY-MM-DD.HH:MM)
+
+
+ password + +
+ string +
+
+ +
Specify authentication key.
+
+
+ type + +
+ dictionary +
+
+ +
Type of authentication to use.
+
Included for compatibility, remove/deprecate after 2025-07-01.
+
+
+ bandwidth_based_metrics + +
+ list + / elements=dictionary +
+
+ +
Specify list of bandwidth based metrics
+
+
+ bandwidth + +
+ string +
+
+
    Choices: +
  • 1g
  • +
  • 10g
  • +
+
+
BW to apply metric to.
+
+
+ metric + +
+ integer +
+
+ +
Specify metric
+
+
+ flood_reduction + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable flood reduction.
+
+
+ metric + +
+ integer +
+
+ +
Metric applied to the interface.
+
+
+ name + +
+ string + / required +
+
+ +
Name of the interface.
+
+
+ passive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify passive
+
+
+ priority + +
+ integer +
+
+ +
Priority for the interface.
+
+
+ timers + +
+ dictionary +
+
+ +
Specify timers
+
+
+ dead_interval + +
+ integer +
+
+ +
Dead interval (seconds).
+
+
+ hello_interval + +
+ integer +
+
+ +
Hello interval (seconds).
+
+
+ poll_interval + +
+ integer +
+
+ +
Poll interval (seconds).
+
+
+ retransmit_interval + +
+ integer +
+
+ +
Retransmit interval (seconds).
+
+
+ transit_delay + +
+ integer +
+
+ +
Transit delay (seconds).
+
+
+ stub + +
+ dictionary +
+
+ +
Settings for configuring the area as a stub.
+
+
+ default_metric + +
+ integer +
+
+ +
Metric for the default route in this area.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Configure the area as a stub.
+
+
+ external_preference + +
+ integer +
+
+ +
Preference of external routes.
+
+
+ overload + +
+ dictionary +
+
+ +
Specify time for overload mode reset
+
+
+ allow_route_leaking + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allow routes to be leaked when overload is configured.
+
+
+ as_external + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise As External with maximum usable metric.
+
+
+ stub_network + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise Stub Network with maximum metric.
+
+
+ timeout + +
+ integer +
+
+ +
Time after which overload mode is reset (seconds).
+
+
+ preference + +
+ integer +
+
+ +
Preference of internal routes.
+
+
+ prefix_export_limit + +
+ integer +
+
+ +
Maximum number of external prefixes that can be exported.
+
+
+ reference_bandwidth + +
+ string +
+
+
    Choices: +
  • 1g
  • +
  • 10g
  • +
+
+
Bandwidth for calculating metric defaults.
+
+
+ rfc1583compatibility + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set RFC1583 compatibility
+
+
+ router_id + +
+ string +
+
+ +
The OSPFv2 router id.
+
+
+ spf_options + +
+ dictionary +
+
+ +
Configure options for SPF.
+
+
+ delay + +
+ integer +
+
+ +
Time to wait before running an SPF (seconds).
+
+
+ holddown + +
+ integer +
+
+ +
Time to hold down before running an SPF (seconds).
+
+
+ no_ignore_our_externals + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not ignore self-generated external and NSSA LSAs.
+
+
+ rapid_runs + +
+ integer +
+
+ +
Number of maximum rapid SPF runs before holddown (seconds).
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show protocols ospf.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • rendered
  • +
  • parsed
  • +
+
+
The state the configuration should be left in.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. + - See `the Junos OS Platform Options `_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # admin# show protocols ospf + + - name: Merge provided OSPFv2 configuration into running config. + junipernetworks.junos.junos_ospfv2: + config: + - reference_bandwidth: 10g + areas: + - area_id: 0.0.0.100 + area_ranges: + - address: 10.200.17.0/24 + exact: true + restrict: true + override_metric: 2000 + - address: 10.200.15.0/24 + exact: true + restrict: true + override_metric: 2000 + stub: + default_metric: 100 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: false + passive: true + bandwidth_based_metrics: + - bandwidth: 1g + metric: 5 + - bandwidth: 10g + metric: 40 + timers: + dead_interval: 4 + hello_interval: 2 + poll_interval: 2 + retransmit_interval: 2 + rfc1583compatibility: false + state: merged + + # Task Output: + # ------------ + # + # before: [] + # + # commands: + # - + # 10g + # 0.0.0.10010.200.17.0/24 + # 2000 + # 10.200.15.0/242000 + # so-0/0/0.03 + # 51g + # 510g40 + # 4 + # 22 + # 2 + # 100 + # + # after: + # - areas: + # - area_id: 0.0.0.100 + # area_range: '[''10.200.17.0/24'', ''10.200.15.0/24'']' + # area_ranges: + # - address: 10.200.17.0/24 + # exact: true + # override_metric: 2000 + # restrict: true + # - address: 10.200.15.0/24 + # exact: true + # override_metric: 2000 + # restrict: true + # interfaces: + # - bandwidth_based_metrics: + # - bandwidth: 1g + # metric: 5 + # - bandwidth: 10g + # metric: 40 + # metric: 5 + # name: so-0/0/0.0 + # passive: true + # priority: 3 + # timers: + # dead_interval: 4 + # hello_interval: 2 + # poll_interval: 2 + # retransmit_interval: 2 + # stub: + # default_metric: 100 + # set: true + # reference_bandwidth: 10g + # rfc1583compatibility: false + + # After state + # ----------- + # + # admin# show protocols ospf + # reference-bandwidth 10g; + # no-rfc-1583; + # area 0.0.0.100 { + # stub default-metric 100; + # area-range 10.200.17.0/24 { + # restrict; + # exact; + # override-metric 2000; + # } + # area-range 10.200.15.0/24 { + # restrict; + # exact; + # override-metric 2000; + # } + # interface so-0/0/0.0 { + # passive; + # bandwidth-based-metrics { + # bandwidth 1g metric 5; + # bandwidth 10g metric 40; + # } + # metric 5; + # priority 3; + # retransmit-interval 2; + # hello-interval 2; + # dead-interval 4; + # poll-interval 2; + # } + # } + # + # Using replaced + # + # Before state + # ------------ + # + # admin# show protocols ospf + # reference-bandwidth 10g; + # no-rfc-1583; + # area 0.0.0.100 { + # stub default-metric 100; + # area-range 10.200.17.0/24 { + # restrict; + # exact; + # override-metric 2000; + # } + # area-range 10.200.15.0/24 { + # restrict; + # exact; + # override-metric 2000; + # } + # interface so-0/0/0.0 { + # passive; + # bandwidth-based-metrics { + # bandwidth 1g metric 5; + # bandwidth 10g metric 40; + # } + # metric 5; + # priority 3; + # retransmit-interval 2; + # hello-interval 2; + # dead-interval 4; + # poll-interval 2; + # } + # } + + - name: Replace existing Junos OSPFv2 config with provided config + junipernetworks.junos.junos_ospfv2: + config: + - reference_bandwidth: 10g + areas: + - area_id: 0.0.0.100 + area_ranges: + - address: 10.200.17.0/24 + exact: true + restrict: true + - address: 10.200.16.0/24 + exact: true + restrict: true + override_metric: 1000 + stub: + default_metric: 100 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: false + passive: true + bandwidth_based_metrics: + - bandwidth: 1g + metric: 5 + - bandwidth: 10g + metric: 40 + timers: + dead_interval: 4 + hello_interval: 2 + poll_interval: 2 + retransmit_interval: 2 + rfc1583compatibility: false + state: replacedd + + # Task Output: + # ------------ + # + # before: + # - areas: + # - area_id: 0.0.0.100 + # area_range: '[''10.200.17.0/24'', ''10.200.15.0/24'']' + # area_ranges: + # - address: 10.200.17.0/24 + # exact: true + # override_metric: 2000 + # restrict: true + # - address: 10.200.15.0/24 + # exact: true + # override_metric: 2000 + # restrict: true + # interfaces: + # - bandwidth_based_metrics: + # - bandwidth: 1g + # metric: 5 + # - bandwidth: 10g + # metric: 40 + # metric: 5 + # name: so-0/0/0.0 + # passive: true + # priority: 3 + # timers: + # dead_interval: 4 + # hello_interval: 2 + # poll_interval: 2 + # retransmit_interval: 2 + # stub: + # default_metric: 100 + # set: true + # reference_bandwidth: 10g + # rfc1583compatibility: false + # + # commands: + # - + # 0.0.0.100 + # 10g + # 0.0.0.10010.200.17.0/24 + # 10.200.16.0/24 + # 1000 + # so-0/0/0.035 + # 1g5 + # 10g40 + # 42 + # 22 + # 100 + # + # after: + # - areas: + # - area_id: 0.0.0.100 + # area_range: '[''10.200.17.0/24'', ''10.200.16.0/24'']' + # area_ranges: + # - address: 10.200.17.0/24 + # exact: true + # restrict: true + # - address: 10.200.16.0/24 + # exact: true + # override_metric: 1000 + # restrict: true + # interfaces: + # - bandwidth_based_metrics: + # - bandwidth: 1g + # metric: 5 + # - bandwidth: 10g + # metric: 40 + # metric: 5 + # name: so-0/0/0.0 + # passive: true + # priority: 3 + # timers: + # dead_interval: 4 + # hello_interval: 2 + # poll_interval: 2 + # retransmit_interval: 2 + # stub: + # default_metric: 100 + # set: true + # reference_bandwidth: 10g + # rfc1583compatibility: false + # + # After state + # ----------- + # + # admin# show protocols ospf + # reference-bandwidth 10g; + # no-rfc-1583; + # area 0.0.0.100 { + # stub default-metric 100; + # area-range 10.200.17.0/24 { + # restrict; + # exact; + # } + # area-range 10.200.16.0/24 { + # restrict; + # exact; + # override-metric 1000; + # } + # interface so-0/0/0.0 { + # passive; + # bandwidth-based-metrics { + # bandwidth 1g metric 5; + # bandwidth 10g metric 40; + # } + # metric 5; + # priority 3; + # retransmit-interval 2; + # hello-interval 2; + # dead-interval 4; + # poll-interval 2; + # } + # } + # + # Using overridden + # + # Before state + # ------------ + # + # admin# show protocols ospf + # reference-bandwidth 10g; + # no-rfc-1583; + # area 0.0.0.100 { + # stub default-metric 100; + # area-range 10.200.17.0/24 { + # restrict; + # exact; + # } + # area-range 10.200.16.0/24 { + # restrict; + # exact; + # override-metric 1000; + # } + # interface so-0/0/0.0 { + # passive; + # bandwidth-based-metrics { + # bandwidth 1g metric 5; + # bandwidth 10g metric 40; + # } + # metric 5; + # priority 3; + # retransmit-interval 2; + # hello-interval 2; + # dead-interval 4; + # poll-interval 2; + # } + # } + + - name: Override runnig OSPFv2 config with provided config + junipernetworks.junos.junos_ospfv2: + config: + - reference_bandwidth: 10g + areas: + - area_id: 0.0.0.110 + area_ranges: + - address: 20.200.17.0/24 + exact: true + restrict: true + override_metric: 2000 + - address: 20.200.15.0/24 + exact: true + restrict: true + override_metric: 2000 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: false + passive: true + bandwidth_based_metrics: + - bandwidth: 1g + metric: 5 + - bandwidth: 10g + metric: 40 + state: overridden + + # Task Output: + # ------------ + # + # before: + # - areas: + # - area_id: 0.0.0.100 + # area_range: '[''10.200.17.0/24'', ''10.200.16.0/24'']' + # area_ranges: + # - address: 10.200.17.0/24 + # exact: true + # restrict: true + # - address: 10.200.16.0/24 + # exact: true + # override_metric: 1000 + # restrict: true + # interfaces: + # - bandwidth_based_metrics: + # - bandwidth: 1g + # metric: 5 + # - bandwidth: 10g + # metric: 40 + # metric: 5 + # name: so-0/0/0.0 + # passive: true + # priority: 3 + # timers: + # dead_interval: 4 + # hello_interval: 2 + # poll_interval: 2 + # retransmit_interval: 2 + # stub: + # default_metric: 100 + # set: true + # reference_bandwidth: 10g + # rfc1583compatibility: false + # + # commands: + # - + # 0.0.0.100 + # 10g0.0.0.110 + # 20.200.17.0/24 + # 2000 + # 20.200.15.0/242000 + # so-0/0/0.03 + # 51g + # 510g40 + # + # 200 + # + # after: + # - areas: + # - area_id: 0.0.0.110 + # area_range: '[''20.200.17.0/24'', ''20.200.15.0/24'']' + # area_ranges: + # - address: 20.200.17.0/24 + # exact: true + # override_metric: 2000 + # restrict: true + # - address: 20.200.15.0/24 + # exact: true + # override_metric: 2000 + # restrict: true + # interfaces: + # - bandwidth_based_metrics: + # - bandwidth: 1g + # metric: 5 + # - bandwidth: 10g + # metric: 40 + # metric: 5 + # name: so-0/0/0.0 + # passive: true + # priority: 3 + # stub: + # default_metric: 200 + # set: true + # reference_bandwidth: 10g + # rfc1583compatibility: false + + # After state + # ----------- + # + # admin# show protocols ospf + # reference-bandwidth 10g; + # no-rfc-1583; + # area 0.0.0.110 { + # stub default-metric 200; + # area-range 20.200.17.0/24 { + # restrict; + # exact; + # override-metric 2000; + # } + # area-range 20.200.15.0/24 { + # restrict; + # exact; + # override-metric 2000; + # } + # interface so-0/0/0.0 { + # passive; + # bandwidth-based-metrics { + # bandwidth 1g metric 5; + # bandwidth 10g metric 40; + # } + # metric 5; + # priority 3; + # } + # } + # Using deleted + # + # Before state + # ------------ + # + # admin# show protocols ospf + # reference-bandwidth 10g; + # no-rfc-1583; + # area 0.0.0.110 { + # stub default-metric 200; + # area-range 20.200.17.0/24 { + # restrict; + # exact; + # override-metric 2000; + # } + # area-range 20.200.15.0/24 { + # restrict; + # exact; + # override-metric 2000; + # } + # interface so-0/0/0.0 { + # passive; + # bandwidth-based-metrics { + # bandwidth 1g metric 5; + # bandwidth 10g metric 40; + # } + # metric 5; + # priority 3; + # } + # } + + - name: Delete OSPFv2 running config. + junipernetworks.junos.junos_ospfv2: + config: + state: deleted + + # Task Output: + # ------------ + # + # before: + # - areas: + # - area_id: 0.0.0.110 + # area_range: '[''20.200.17.0/24'', ''20.200.15.0/24'']' + # area_ranges: + # - address: 20.200.17.0/24 + # exact: true + # override_metric: 2000 + # restrict: true + # - address: 20.200.15.0/24 + # exact: true + # override_metric: 2000 + # restrict: true + # interfaces: + # - bandwidth_based_metrics: + # - bandwidth: 1g + # metric: 5 + # - bandwidth: 10g + # metric: 40 + # metric: 5 + # name: so-0/0/0.0 + # passive: true + # priority: 3 + # stub: + # default_metric: 200 + # set: true + # reference_bandwidth: 10g + # rfc1583compatibility: false + # + # commands: + # - + # 0.0.0.100 + # + # + # after: [] + # + # + # After state + # ----------- + # + # admin# show protocols ospf + + # Using gathered + # + # Before state + # ------------ + # + # admin# show protocols ospf + # reference-bandwidth 10g; + # no-rfc-1583; + # area 0.0.0.100 { + # stub default-metric 100; + # area-range 10.200.17.0/24 { + # restrict; + # exact; + # override-metric 2000; + # } + # area-range 10.200.15.0/24 { + # restrict; + # exact; + # override-metric 2000; + # } + # interface so-0/0/0.0 { + # passive; + # bandwidth-based-metrics { + # bandwidth 1g metric 5; + # bandwidth 10g metric 40; + # } + # metric 5; + # priority 3; + # retransmit-interval 2; + # hello-interval 2; + # dead-interval 4; + # poll-interval 2; + # } + # } + + - name: Gather Junos OSPFv2 running-configuration + junipernetworks.junos.junos_ospfv2: + config: + state: gathered + # + # + # Task Output: + # ------------ + # + # gathered: + # + # - areas: + # - area_id: 0.0.0.100 + # area_range: '[''10.200.17.0/24'', ''10.200.15.0/24'']' + # area_ranges: + # - address: 10.200.17.0/24 + # exact: true + # override_metric: 2000 + # restrict: true + # - address: 10.200.15.0/24 + # exact: true + # override_metric: 2000 + # restrict: true + # interfaces: + # - bandwidth_based_metrics: + # - bandwidth: 1g + # metric: 5 + # - bandwidth: 10g + # metric: 40 + # metric: 5 + # name: so-0/0/0.0 + # passive: true + # priority: 3 + # timers: + # dead_interval: 4 + # hello_interval: 2 + # poll_interval: 2 + # retransmit_interval: 2 + # stub: + # default_metric: 100 + # set: true + # reference_bandwidth: 10g + # rfc1583compatibility: false + + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # + # 10g + # + # + # 0.0.0.100 + # + # 100 + # + # + # 10.200.16.0/24 + # + # 10000 + # + # + # 10.200.11.0/24 + # + # + # + # + # so-0/0/0.0 + # + # + # + # + # 1g + # 5 + # + # + # 10g + # 40 + # + # + # 5 + # 3 + # 2 + # 2 + # 4 + # 2 + # + # + # + # + # + # + # + # 172.16.17.0/24 + # + # + # + # 10.200.16.75 + # + # 65432 + # + # + # + # + + + - name: Parsed the ospfv2 config into structured ansible resource facts. + junipernetworks.junos.junos_ospfv2: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # Task Output: + # ------------ + # + # parsed: + # - areas: + # - area_id: 0.0.0.100 + # area_range: '[''10.200.16.0/24'', ''10.200.11.0/24'']' + # area_ranges: + # - address: 10.200.16.0/24 + # exact: true + # override_metric: 10000 + # - address: 10.200.11.0/24 + # exact: true + # restrict: true + # interfaces: + # - bandwidth_based_metrics: + # - bandwidth: 1g + # metric: 5 + # - bandwidth: 10g + # metric: 40 + # metric: 5 + # name: so-0/0/0.0 + # passive: true + # priority: 3 + # timers: + # dead_interval: 4 + # hello_interval: 2 + # poll_interval: 2 + # retransmit_interval: 2 + # stub: + # default_metric: 100 + # set: true + # reference_bandwidth: 10g + # rfc1583compatibility: false + # router_id: 10.200.16.75 + + # Using rendered + # + - name: Render the commands for provided configuration + junipernetworks.junos.junos_ospfv2: + config: + - reference_bandwidth: 10g + areas: + - area_id: 0.0.0.100 + area_ranges: + - address: 10.200.17.0/24 + exact: true + restrict: true + override_metric: 2000 + - address: 10.200.15.0/24 + exact: true + restrict: true + override_metric: 2000 + stub: + default_metric: 100 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: false + passive: true + bandwidth_based_metrics: + - bandwidth: 1g + metric: 5 + - bandwidth: 10g + metric: 40 + timers: + dead_interval: 4 + hello_interval: 2 + poll_interval: 2 + retransmit_interval: 2 + rfc1583compatibility: false + state: rendered + + # Task Output: + # ------------ + # + # rendered: " + # 10g0.0.0.100 + # 10.200.17.0/242000 + # 10.200.15.0/24 + # 2000so-0/0/0.0 + # 35 + # 1g510g + # 404 + # 22 + # 2 + # 100" + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">< nc:ospf><nc:area delete="delete">0.0.0.100</nc:area><nc:reference-bandwidth delete="delete"/> <nc:no-rfc-1583 delete="delete"/></nc:ospf></nc:protocols>', 'xml 2', 'xml 3']
+
+
+ gathered + +
+ list +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ list +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ list +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Daniel Mellado (@dmellado) +- Rohit Thakur (@rohitthakur2590) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ospfv3_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ospfv3_module.rst new file mode 100644 index 00000000..82a4fef1 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ospfv3_module.rst @@ -0,0 +1,1346 @@ +.. _junipernetworks.junos.junos_ospfv3_module: + + +********************************** +junipernetworks.junos.junos_ospfv3 +********************************** + +**OSPFv3 resource module** + + +Version added: 1.2.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages global OSPFv3 configuration on devices running Juniper JUNOS. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
A list of OSPFv3 process configuration.
+
+
+ areas + +
+ list + / elements=dictionary +
+
+ +
A list of OSPFv3 areas' configuration.
+
+
+ area_id + +
+ string + / required +
+
+ +
The Area ID as an integer or IP Address.
+
+
+ area_range + +
+ string +
+
+ +
Configure an address range for the area.
+
+
+ interfaces + +
+ list + / elements=dictionary +
+
+ +
List of interfaces in this area.
+
+
+ authentication + +
+ dictionary +
+
+ +
Specify authentication type
+
+
+ type + +
+ dictionary +
+
+ +
Type of authentication to use.
+
+
+ bandwidth_based_metrics + +
+ list + / elements=dictionary +
+
+ +
Specify list of bandwidth based metrics
+
+
+ bandwidth + +
+ string +
+
+
    Choices: +
  • 1g
  • +
  • 10g
  • +
+
+
BW to apply metric to.
+
+
+ metric + +
+ integer +
+
+ +
Specify metric
+
+
+ flood_reduction + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable flood reduction.
+
+
+ metric + +
+ integer +
+
+ +
Metric applied to the interface.
+
+
+ name + +
+ string + / required +
+
+ +
Name of the interface.
+
+
+ passive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify passive
+
+
+ priority + +
+ integer +
+
+ +
Priority for the interface.
+
+
+ timers + +
+ dictionary +
+
+ +
Specify timers
+
+
+ dead_interval + +
+ integer +
+
+ +
Dead interval (seconds).
+
+
+ hello_interval + +
+ integer +
+
+ +
Hello interval (seconds).
+
+
+ poll_interval + +
+ integer +
+
+ +
Poll interval (seconds).
+
+
+ retransmit_interval + +
+ integer +
+
+ +
Retransmit interval (seconds).
+
+
+ transit_delay + +
+ integer +
+
+ +
Transit delay (seconds).
+
+
+ stub + +
+ dictionary +
+
+ +
Settings for configuring the area as a stub.
+
+
+ default_metric + +
+ integer +
+
+ +
Metric for the default route in this area.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Configure the area as a stub.
+
+
+ external_preference + +
+ integer +
+
+ +
Preference of external routes.
+
+
+ overload + +
+ dictionary +
+
+ +
Specify time for overload mode reset
+
+
+ timeout + +
+ integer +
+
+ +
Time after which overload mode is reset (seconds).
+
+
+ preference + +
+ integer +
+
+ +
Preference of internal routes.
+
+
+ prefix_export_limit + +
+ integer +
+
+ +
Maximum number of external prefixes that can be exported.
+
+
+ reference_bandwidth + +
+ string +
+
+
    Choices: +
  • 1g
  • +
  • 10g
  • +
+
+
Bandwidth for calculating metric defaults.
+
+
+ rfc1583compatibility + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set RFC1583 compatibility
+
+
+ router_id + +
+ string +
+
+ +
The OSPFv3 router id.
+
+
+ spf_options + +
+ dictionary +
+
+ +
Configure options for SPF.
+
+
+ delay + +
+ integer +
+
+ +
Time to wait before running an SPF (seconds).
+
+
+ holddown + +
+ integer +
+
+ +
Time to hold down before running an SPF (seconds).
+
+
+ rapid_runs + +
+ integer +
+
+ +
Number of maximum rapid SPF runs before holddown (seconds).
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show protocols ospf.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • rendered
  • +
  • parsed
  • +
+
+
The state the configuration should be left in.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # admin# show protocols ospf3 + + - name: Merge Junos OSPFv3 config + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - metric: 5 + name: so-0/0/0.0 + priority: 3 + - metric: 6 + name: so-0/0/1.0 + priority: 2 + stub: + default_metric: 200 + set: true + state: merged + + # Task Output: + # ------------ + # + # before: [] + # + # commands: + # - + # 0.0.0.100so-0/0/0.0 + # 35 + # so-0/0/1.026 + # 200 + # - + # 10.200.16.75 + # + # after: + # - areas: + # - area_id: 0.0.0.100 + # interfaces: + # - metric: 5 + # name: so-0/0/0.0 + # priority: 3 + # - metric: 6 + # name: so-0/0/1.0 + # priority: 2 + # stub: + # default_metric: 200 + # set: true + # router_id: 10.200.16.75 + + # After state + # ----------- + # + # admin# show protocols ospf3 + # area 0.0.0.100 { + # stub default-metric 200; + # interface so-0/0/0.0 { + # metric 5; + # priority 3; + # } + # interface so-0/0/1.0 { + # metric 6; + # priority 2; + # } + # } + # + # Using replaced + # + # Before state + # ------------ + # + # admin# show protocols ospf3 + # admin# show protocols ospf3 + # area 0.0.0.100 { + # stub default-metric 200; + # interface so-0/0/0.0 { + # metric 5; + # priority 3; + # } + # interface so-0/0/1.0 { + # metric 6; + # priority 2; + # } + # } + + - name: Replace existing Junos OSPFv3 config with provided config + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + state: replaced + + # Task Output: + # ------------ + # + # before: + # - areas: + # - area_id: 0.0.0.100 + # interfaces: + # - metric: 5 + # name: so-0/0/0.0 + # priority: 3 + # - metric: 6 + # name: so-0/0/1.0 + # priority: 2 + # stub: + # default_metric: 200 + # set: true + # router_id: 10.200.16.75 + # + # commands: + # - + # 0.0.0.100 + # so-0/0/0.0 + # 0.0.0.100so-0/0/0.0 + # + # - + # 10.200.16.7510.200.16.75 + # + # after: + # - areas: + # - area_id: 0.0.0.100 + # interfaces: + # - metric: 6 + # name: so-0/0/1.0 + # priority: 2 + # - name: so-0/0/0.0 + # stub: + # default_metric: 200 + # set: true + # router_id: 10.200.16.75 + # + # After state + # ----------- + # + # admin# show protocols ospf3 + # area 0.0.0.100 { + # stub default-metric 200; + # interface so-0/0/1.0 { + # metric 6; + # priority 2; + # } + # interface so-0/0/0.0; + # } + # + # Using overridden + # + # Before state + # ------------ + # + # admin# show protocols ospf3 + # area 0.0.0.100 { + # stub default-metric 200; + # interface so-0/0/1.0 { + # metric 6; + # priority 2; + # } + # interface so-0/0/0.0; + # } + + - name: Override runnig OSPFv3 config with provided config + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: true + passive: true + - area_id: 0.0.0.200 + interfaces: + - name: ge-1/1/0.0 + - name: ge-2/2/0.0 + state: overridden + + # Task Output: + # ------------ + # + # before: + # - areas: + # - area_id: 0.0.0.100 + # interfaces: + # - metric: 6 + # name: so-0/0/1.0 + # priority: 2 + # - name: so-0/0/0.0 + # stub: + # default_metric: 200 + # set: true + # router_id: 10.200.16.75 + # + # commands: + # - + # 0.0.0.100 + # so-0/0/0.03 + # 5 + # 200 + # 0.0.0.200ge-1/1/0.0 + # ge-2/2/0.0 + # + # - + # 10.200.16.75 + # + # after: + # - areas: + # - area_id: 0.0.0.100 + # interfaces: + # - flood_reduction: true + # metric: 5 + # name: so-0/0/0.0 + # passive: true + # priority: 3 + # stub: + # default_metric: 200 + # set: true + # - area_id: 0.0.0.200 + # interfaces: + # - name: ge-1/1/0.0 + # - name: ge-2/2/0.0 + # router_id: 10.200.16.75 + + # After state + # ----------- + # + # admin# show protocols ospf3 + # area 0.0.0.100 { + # stub default-metric 200; + # interface so-0/0/0.0 { + # passive; + # metric 5; + # priority 3; + # flood-reduction; + # } + # } + # area 0.0.0.200 { + # interface ge-1/1/0.0; + # interface ge-2/2/0.0; + # } + # Using deleted + # + # Before state + # ------------ + # + # admin# show protocols ospf3 + # area 0.0.0.100 { + # stub default-metric 200; + # interface so-0/0/0.0 { + # passive; + # metric 5; + # priority 3; + # flood-reduction; + # } + # } + # area 0.0.0.200 { + # interface ge-1/1/0.0; + # interface ge-2/2/0.0; + # } + + - name: Delete OSPFv3 running config. + junipernetworks.junos.junos_ospfv3: + config: + state: deleted + + # Task Output: + # ------------ + # + # before: + # - areas: + # - area_id: 0.0.0.100 + # interfaces: + # - flood_reduction: true + # metric: 5 + # name: so-0/0/0.0 + # passive: true + # priority: 3 + # stub: + # default_metric: 200 + # set: true + # - area_id: 0.0.0.200 + # interfaces: + # - name: ge-1/1/0.0 + # - name: ge-2/2/0.0 + # router_id: 10.200.16.75 + # + # commands: + # - + # + # - + # + # + # after: [] + # + # + # After state + # ----------- + # + # admin# show protocols ospf3 + + # Using gathered + # + # Before state + # ------------ + # + # admin# show protocols ospf3 + # area 0.0.0.100 { + # stub default-metric 200; + # interface so-0/0/0.0 { + # metric 5; + # priority 3; + # } + # interface so-0/0/1.0 { + # metric 6; + # priority 2; + # } + + - name: Gather Junos OSPFv3 running-configuration + junipernetworks.junos.junos_ospfv3: + config: + state: gathered + # + # + # Task Output: + # ------------ + # + # gathered: + # + # - areas: + # - area_id: 0.0.0.100 + # interfaces: + # - metric: 5 + # name: so-0/0/0.0 + # priority: 3 + # - metric: 6 + # name: so-0/0/1.0 + # priority: 2 + # stub: + # default_metric: 200 + # set: true + # router_id: 10.200.16.75 + + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # + # + # + # 0.0.0.100 + # + # 200 + # + # + # so-0/0/0.0 + # + # 5 + # 3 + # + # + # + # + # 0.0.0.200 + # + # ge-1/1/0.0 + # + # + # ge-2/2/0.0 + # + # + # + # + # + # 10.200.16.75 + # + # + # + + + - name: Parsed the ospfv3 config into structured ansible resource facts. + junipernetworks.junos.junos_ospfv3: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # Task Output: + # ------------ + # + # parsed: + # - router_id: 10.200.16.75 + # areas: + # - area_id: 0.0.0.100 + # stub: + # default_metric: 200 + # set: true + # interfaces: + # - name: so-0/0/0.0 + # priority: 3 + # metric: 5 + # flood_reduction: true + # passive: true + # - area_id: 0.0.0.200 + # interfaces: + # - name: ge-1/1/0.0 + # - name: ge-2/2/0.0 + + # Using rendered + # + - name: Render the commands for provided configuration + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - metric: 5 + name: so-0/0/0.0 + priority: 3 + - metric: 6 + name: so-0/0/1.0 + priority: 2 + stub: + default_metric: 200 + set: true + state: rendered + + # Task Output: + # ------------ + # + # rendered: " + # 0.0.0.100 + # so-0/0/0.03 + # 5so-0/0/1.0 + # 26 + # 200" + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">< nc:ospf3><nc:area><nc:name>0.0.0.100</nc:name><nc:interface>', 'xml 2', 'xml 3']
+
+
+ gathered + +
+ list +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ list +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ list +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Rohit Thakur (@rohitthakur2590) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_package_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_package_module.rst new file mode 100644 index 00000000..22887557 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_package_module.rst @@ -0,0 +1,424 @@ +.. _junipernetworks.junos.junos_package_module: + + +*********************************** +junipernetworks.junos.junos_package +*********************************** + +**Installs packages on remote devices running Junos** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module can install new and updated packages on remote devices running Junos. The module will compare the specified package with the one running on the remote device and install the specified version if there is a mismatch + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- junos-eznc +- ncclient (>=v0.5.2) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ force + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
The force argument instructs the module to bypass the package version check and install the packaged identified in src on the remote device.
+
+
+ force_host + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
The force_host argument controls the way software package or bundle is added on remote JUNOS host and is applicable for JUNOS QFX5100 device. If the value is set to True it will ignore any warnings while adding the host software package or bundle.
+
+
+ issu + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
The issu argument is a boolean flag when set to True allows unified in-service software upgrade (ISSU) feature which enables you to upgrade between two different Junos OS releases with no disruption on the control plane and with minimal disruption of traffic.
+
+
+ no_copy + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
The no_copy argument is responsible for instructing the remote device on where to install the package from. When enabled, the package is transferred to the remote device prior to installing.
+
+
+ provider + +
+ dictionary +
+
+ +
Deprecated
+
Starting with Ansible 2.5 we recommend using connection: network_cli or connection: netconf.
+
For more information please see the Junos OS Platform Options guide.
+

+
A dict object containing connection details.
+
+
+ host + +
+ string +
+
+ +
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.
+
+
+ password + +
+ string +
+
+ +
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 ANSIBLE_NET_PASSWORD will be used instead.
+
+
+ port + +
+ integer +
+
+ +
Specifies the port to use when building the connection to the remote device. The port value will default to the well known SSH port of 22 (for transport=cli) or port 830 (for transport=netconf) device.
+
+
+ ssh_keyfile + +
+ path +
+
+ +
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 ANSIBLE_NET_SSH_KEYFILE will be used instead.
+
+
+ timeout + +
+ integer +
+
+ +
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.
+
+
+ transport + +
+ string +
+
+
    Choices: +
  • cli
  • +
  • netconf ←
  • +
+
+
Configures the transport connection to use when connecting to the remote device.
+
+
+ username + +
+ string +
+
+ +
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 ANSIBLE_NET_USERNAME will be used instead.
+
+
+ reboot + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes ←
  • +
+
+
In order for a package to take effect, the remote device must be restarted. When enabled, this argument will instruct the module to reboot the device once the updated package has been installed. If disabled or the remote package does not need to be changed, the device will not be started.
+
+
+ src + +
+ path + / required +
+
+ +
The src argument specifies the path to the source package to be installed on the remote device in the advent of a version mismatch. The src argument can be either a localized path or a full path to the package file to install.
+

aliases: package
+
+
+ ssh_config + +
+ path +
+
+ +
The ssh_config argument is path to the SSH configuration file. This can be used to load SSH information from a configuration file. If this option is not given by default ~/.ssh/config is queried.
+
+
+ ssh_private_key_file + +
+ path +
+
+ +
The ssh_private_key_file argument is path to the SSH private key file. This can be used if you need to provide a private key rather than loading the key into the ssh-key-ring/environment
+
+
+ unlink + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
The unlink argument is responsible for instructing the remote device to remove the installation packages after installation.
+
+
+ validate + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes ←
  • +
+
+
The validate argument is responsible for instructing the remote device to skip checking the current device configuration compatibility with the package being installed. When set to false validation is not performed.
+
+
+ version + +
+ string +
+
+ +
The version argument can be used to explicitly specify the version of the package that should be installed on the remote device. If the version argument is not specified, then the version is extracts from the src filename.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. + - Works with ``local`` connections only. + - Since this module uses junos-eznc to establish connection with junos device the netconf configuration parameters needs to be passed using module options for example ``ssh_config`` unlike other junos modules that uses ``netconf`` connection type. + - For information on using CLI and netconf see the :ref:`Junos OS Platform Options guide ` + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` + - For more information on using Ansible to manage Juniper network devices see https://www.ansible.com/ansible-juniper. + + + +Examples +-------- + +.. code-block:: yaml + + # the required set of connection arguments have been purposely left off + # the examples for brevity + + - name: install local package on remote device + junipernetworks.junos.junos_package: + src: junos-vsrx-12.1X46-D10.2-domestic.tgz + + - name: install local package on remote device without rebooting + junipernetworks.junos.junos_package: + src: junos-vsrx-12.1X46-D10.2-domestic.tgz + reboot: false + + - name: install local package on remote device with jumpost + junipernetworks.junos.junos_package: + src: junos-vsrx-12.1X46-D10.2-domestic.tgz + ssh_config: /home/user/customsshconfig + + + + +Status +------ + + +Authors +~~~~~~~ + +- Peter Sprygada (@privateip) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ping_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ping_module.rst new file mode 100644 index 00000000..0c32f602 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_ping_module.rst @@ -0,0 +1,366 @@ +.. _junipernetworks.junos.junos_ping_module: + + +******************************** +junipernetworks.junos.junos_ping +******************************** + +**Tests reachability using ping from devices running Juniper JUNOS** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- Tests reachability using ping from devices running Juniper JUNOS to a remote destination. +- Tested against Junos (17.3R1.10) +- For a general purpose network module, see the :ref:`ansible.netcommon.net_ping ` module. +- For Windows targets, use the :ref:`ansible.windows.win_ping ` module instead. +- For targets running Python, use the :ref:`ansible.builtin.ping ` module instead. + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ count + +
+ integer +
+
+ Default:
5
+
+
Number of packets to send to check reachability.
+
+
+ dest + +
+ string + / required +
+
+ +
The IP Address or hostname (resolvable by the device) of the remote node.
+
+
+ df_bit + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
Determines whether to set the DF bit.
+
+
+ interface + +
+ string +
+
+ +
The source interface to use while sending the ping packet(s).
+
+
+ interval + +
+ integer +
+
+ +
Determines the interval (in seconds) between consecutive pings.
+
+
+ rapid + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
Determines whether to send the packets rapidly.
+
+
+ size + +
+ integer +
+
+ +
Determines the size (in bytes) of the ping packet(s).
+
+
+ source + +
+ string +
+
+ +
The IP Address to use while sending the ping packet(s).
+
+
+ state + +
+ string +
+
+
    Choices: +
  • absent
  • +
  • present ←
  • +
+
+
Determines if the expected result is success or fail.
+
+
+ ttl + +
+ integer +
+
+ +
The time-to-live value for the ICMP packet(s).
+
+
+ + +Notes +----- + +.. note:: + - For a general purpose network module, see the :ref:`ansible.netcommon.net_ping ` module. + - For Windows targets, use the :ref:`ansible.windows.win_ping ` module instead. + - For targets running Python, use the :ref:`ansible.builtin.ping ` module instead. + - This module works only with connection ``network_cli``. + - For information on using CLI and netconf see the :ref:`Junos OS Platform Options guide ` + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` + - For more information on using Ansible to manage Juniper network devices see https://www.ansible.com/ansible-juniper. + + + +Examples +-------- + +.. code-block:: yaml + + - name: Test reachability to 10.10.10.10 + junipernetworks.junos.junos_ping: + dest: 10.10.10.10 + + - name: Test reachability to 10.20.20.20 using source and size set + junipernetworks.junos.junos_ping: + dest: 10.20.20.20 + size: 1024 + ttl: 128 + + - name: Test unreachability to 10.30.30.30 using interval + junipernetworks.junos.junos_ping: + dest: 10.30.30.30 + interval: 3 + state: absent + + - name: Test reachability to 10.40.40.40 setting count and interface + junipernetworks.junos.junos_ping: + dest: 10.40.40.40 + interface: fxp0 + count: 20 + size: 512 + + - name: Test reachability to 10.50.50.50 using do-not-fragment and rapid + junipernetworks.junos.junos_ping: + dest: 10.50.50.50 + df_bit: true + rapid: true + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ commands + +
+ list +
+
always +
List of commands sent.
+
+
Sample:
+
['ping 10.8.38.44 count 10 source 10.8.38.38 ttl 128']
+
+
+ packet_loss + +
+ string +
+
always +
Percentage of packets lost.
+
+
Sample:
+
0%
+
+
+ packets_rx + +
+ integer +
+
always +
Packets successfully received.
+
+
Sample:
+
20
+
+
+ packets_tx + +
+ integer +
+
always +
Packets successfully transmitted.
+
+
Sample:
+
20
+
+
+ rtt + +
+ dictionary +
+
when ping succeeds +
The round trip time (RTT) stats.
+
+
Sample:
+
{'avg': 2, 'max': 8, 'min': 1, 'stddev': 24}
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Nilashish Chakraborty (@NilashishC) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_prefix_lists_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_prefix_lists_module.rst new file mode 100644 index 00000000..383e7d87 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_prefix_lists_module.rst @@ -0,0 +1,654 @@ +.. _junipernetworks.junos.junos_prefix_lists_module: + + +**************************************** +junipernetworks.junos.junos_prefix_lists +**************************************** + +**Manage prefix-lists attributes of interfaces on Junos devices.** + + +Version added: 2.1.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- Manage prefix-lists attributes of interfaces on Junos network devices. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
The provided link BGP address family dictionary.
+
+
+ address_prefixes + +
+ list + / elements=string +
+
+ +
Specify address prefixes.
+
+
+ dynamic_db + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable object to exist in dynamic DB.
+
+
+ name + +
+ string + / required +
+
+ +
Specify the name of the prefix-list.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show policy-options.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • parsed
  • +
  • gathered
  • +
  • rendered
  • +
+
+
The state the configuration should be left in.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. + - See `the Junos OS Platform Options `_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # vagrant@vsrx# show policy-options + # + # [edit] + + - name: Merge Junos prefix lists + junipernetworks.junos.junos_prefix_lists: + config: + - name: Internal + address_prefixes: + - 172.16.1.32 + - 172.16.3.32 + - name: Test1 + dynamic_db: true + - name: Test2 + address_prefixes: + - 172.16.2.32 + - 172.16.7.32 + - 172.16.9.32 + state: merged + + # Task Output + # ------------- + # + # before: [] + # commands: + # - + # - "Internal172.16.1.32" + # - "172.16.3.32" + # - "Test1" + # - "Test2" + # - "172.16.2.32" + # - "172.16.7.32" + # - "172.16.9.32" + # - "" + # after: + # - address_prefixes: + # - 172.16.1.32/32 + # - 172.16.3.32/32 + # name: Internal + # - dynamic_db: true + # name: Test1 + # - address_prefixes: + # - 172.16.2.32/32 + # - 172.16.7.32/32 + # - 172.16.9.32/32 + # name: Test2 + + + # After state + # ----------- + # + # vagrant@vsrx# show policy-options + # prefix-list Internal { + # 172.16.1.32/32; + # 172.16.3.32/32; + # } + # prefix-list Test1 { + # dynamic-db; + # } + # prefix-list Test2 { + # 172.16.2.32/32; + # 172.16.7.32/32; + # 172.16.9.32/32; + # } + + + # Using gathered + # + # Before state + # ------------ + # + # vagrant@vsrx# show policy-options + # prefix-list Internal { + # 172.16.1.32/32; + # 172.16.3.32/32; + # } + # prefix-list Test1 { + # dynamic-db; + # } + # prefix-list Test2 { + # 172.16.2.32/32; + # 172.16.7.32/32; + # 172.16.9.32/32; + # } + + - name: Gather Junos prefix-lists + junipernetworks.junos.junos_prefix_lists: + state: gathered + + + # Task Output + # ------------- + # + # gathered: + # - address_prefixes: + # - 172.16.1.32/32 + # - 172.16.3.32/32 + # name: Internal + # - dynamic_db: true + # name: Test1 + # - address_prefixes: + # - 172.16.2.32/32 + # - 172.16.7.32/32 + # - 172.16.9.32/32 + # name: Test2 + + + # Using replaced + + + # Before state + # ------------ + # + # vagrant@vsrx# show policy-options + # prefix-list Internal { + # 172.16.1.32/32; + # 172.16.3.32/32; + # } + # prefix-list Test1 { + # dynamic-db; + # } + # prefix-list Test2 { + # 172.16.2.32/32; + # 172.16.7.32/32; + # 172.16.9.32/32; + # } + + + - name: Replace existing Junos prefix-lists configuration with provided config + junipernetworks.junos.junos_prefix_lists: + config: + - name: Test2 + address_prefixes: + - 172.16.4.32 + - 172.16.8.32 + - 172.16.9.32" + state: replaced + + + # Task Output + # ------------- + # + # before: + # - address_prefixes: + # - 172.16.1.32/32 + # - 172.16.3.32/32 + # name: Internal + # - dynamic_db: true + # name: Test1 + # - address_prefixes: + # - 172.16.2.32/32 + # - 172.16.7.32/32 + # - 172.16.9.32/32 + # name: Test2 + # commands: + # - + # - Test2 + # - "Test2172.16.4.32" + # - "172.16.8.32" + # - "172.16.9.32" + # - "" + # after: + # - address_prefixes: + # - 172.16.1.32/32 + # - 172.16.3.32/32 + # name: Internal + # - dynamic_db: true + # name: Test1 + # - address_prefixes: + # - 172.16.4.32/32 + # - 172.16.8.32/32 + # - 172.16.9.32/32 + # name: Test2 + + # After state + # ----------- + # + # vagrant@vsrx# show policy-options + # prefix-list Internal { + # 172.16.1.32/32; + # 172.16.3.32/32; + # } + # prefix-list Test1 { + # dynamic-db; + # } + # prefix-list Test2 { + # 172.16.4.32/32; + # 172.16.8.32/32; + # 172.16.9.32/32; + # } + + + # Using overridden + + # Before state + # ------------ + # + # vagrant@vsrx# show policy-options + # prefix-list Internal { + # 172.16.1.32/32; + # 172.16.3.32/32; + # } + # prefix-list Test1 { + # dynamic-db; + # } + # prefix-list Test2 { + # 172.16.4.32/32; + # 172.16.8.32/32; + # 172.16.9.32/32; + # } + + + - name: Override Junos prefix-lists configuration with provided configuration + junipernetworks.junos.junos_prefix_lists: + config: + - name: Test2 + address_prefixes: + - 172.16.4.32/28 + - 172.16.8.32/28 + - 172.16.9.32/28 + state: overridden + + + # Task Output + # ------------- + # + # before: + # - address_prefixes: + # - 172.16.1.32/32 + # - 172.16.3.32/32 + # name: Internal + # - dynamic_db: true + # name: Test1 + # - address_prefixes: + # - 172.16.4.32/32 + # - 172.16.8.32/32 + # - 172.16.9.32/32 + # name: Test2 + # commands: + # - + # - Internal + # - Test1 + # - Test2 + # - "Test2" + # - "172.16.4.32/28" + # - "172.16.8.32/28" + # - "172.16.9.32/28" + # after: + # - address_prefixes: + # - 172.16.4.32/28 + # - 172.16.8.32/28 + # - 172.16.9.32/28 + # name: Test2 + + # After state + # ----------- + # + # vagrant@vsrx# show policy-options + # prefix-list Test2 { + # 172.16.4.32/28; + # 172.16.8.32/28; + # 172.16.9.32/28; + # } + + + # Using deleted + + + # Before state + # ------------ + # + # vagrant@vsrx# show policy-options + # prefix-list Internal { + # 172.16.1.32/32; + # 172.16.3.32/32; + # } + # prefix-list Test1 { + # dynamic-db; + # } + # prefix-list Test2 { + # 172.16.2.32/32; + # 172.16.7.32/32; + # 172.16.9.32/32; + # } + + + - name: Delete provided prefix-lists + junipernetworks.junos.junos_prefix_lists: + config: + - name: "Test1" + - name: "Test2" + state: deleted + + + # Task Output + # ------------- + # + # before: + # - address_prefixes: + # - 172.16.1.32/32 + # - 172.16.3.32/32 + # name: Internal + # - dynamic_db: true + # name: Test1 + # - address_prefixes: + # - 172.16.2.32/32 + # - 172.16.7.32/32 + # - 172.16.9.32/32 + # name: Test2 + # commands: + # - + # - Test1 + # - Test2 + # after: + # - address_prefixes: + # - 172.16.1.32/32 + # - 172.16.3.32/32 + # name: Internal + + + # After state + # ----------- + # + # vagrant@vsrx# show policy-options + # prefix-list Internal { + # 172.16.1.32/32; + # 172.16.3.32/32; + # } + # + + + # Using deleted without specifying config + + + # Before state + # ------------ + # + # vagrant@vsrx# show policy-options + # prefix-list Internal { + # 172.16.1.32/32; + # 172.16.3.32/32; + # } + # prefix-list Test1 { + # dynamic-db; + # } + # prefix-list Test2 { + # 172.16.2.32/32; + # 172.16.7.32/32; + # 172.16.9.32/32; + # } + + + - name: Delete complete Junos prefix-lists configuration + junipernetworks.junos.junos_prefix_lists: + state: deleted + + + # Task Output + # ------------- + # + # before: + # - address_prefixes: + # - 172.16.1.32/32 + # - 172.16.3.32/32 + # name: Internal + # - dynamic_db: true + # name: Test1 + # - address_prefixes: + # - 172.16.2.32/32 + # - 172.16.7.32/32 + # - 172.16.9.32/32 + # name: Test2 + # commands: + # - + # - + # after: [] + + + # After state + # ----------- + # + # vagrant@vsrx# show policy-options + # + # [edit] + + + # Using parsed + + + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # + # 64510 + # + # + # 64500 + # + # + # 172.16.1.16/28 + # + # + # 172.16.1.32/28 + # + # + # + # + # + + + - name: Parse running prefix-lists configuration + junipernetworks.junos.junos_prefix_lists: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + + + # Task Output + # ------------- + # parsed: + # - name: '64510' + # - address_prefixes: + # - 172.16.1.16/28 + # - 172.16.1.32/28 + # dynamic_db: true + # name: '64500' + + + # Using rendered + + + - name: Render the xml for provided configuration + junipernetworks.junos.junos_prefix_lists: + config: + - name: Internal + address_prefixes: + - 172.16.1.32 + - 172.16.3.32 + - name: Test1 + dynamic_db: true + - name: Test2 + address_prefixes: + - 172.16.2.32 + - 172.16.7.32 + - 172.16.9.32 + state: rendered + + + # Task Output + # ------------- + # rendered: + # - + # - "Internal172.16.1.32" + # - "172.16.3.32" + # - "Test1" + # - "Test2" + # - "172.16.2.32" + # - "172.16.7.32" + # - "172.16.9.32" + # - "" + + + + +Status +------ + + +Authors +~~~~~~~ + +- Rohit Thakur (@rohitthakur2590) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_routing_instances_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_routing_instances_module.rst new file mode 100644 index 00000000..5b69b687 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_routing_instances_module.rst @@ -0,0 +1,1318 @@ +.. _junipernetworks.junos.junos_routing_instances_module: + + +********************************************* +junipernetworks.junos.junos_routing_instances +********************************************* + +**Manage routing instances on Junos devices.** + + +Version added: 2.1.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- Manage routing instances on Junos network devices. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
The provided Routing instance configuration list.
+
+
+ bridge_domains + +
+ list + / elements=dictionary +
+
+ +
Bridge domain configuration.
+
This has been tested for junos MX204.
+
+
+ description + +
+ string +
+
+ +
Specify domain description.
+
+
+ domain_id + +
+ integer +
+
+ +
Provide the domain ID.
+
+
+ enable_mac_move_action + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable blocking action due to mac-move in this Bridge Domain.
+
+
+ mcae_mac_flush + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable IRB MAC synchronization in this bridge domain
+
+
+ name + +
+ string +
+
+ +
Specify the name of the bridge domain.
+
+
+ no_irb_layer_2_copy + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable transmission of layer-2 copy of packets of irb routing-interface.
+
+
+ no_local_switching + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable local switching within CE-facing interfaces.
+
+
+ service_id + +
+ integer +
+
+ +
Specify service id.
+
+
+ vlan_id + +
+ integer +
+
+ +
IEEE 802.1q VLAN identifier for bridging domain (1..4094)
+
+
+ connector_id_advertise + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Advertise connector-id attribute.
+
+
+ description + +
+ string +
+
+ +
Specify text description of routing instance.
+
+
+ egress_protection + +
+ dictionary +
+
+ +
Egress instance protection dictionary.
+
+
+ context_identifier + +
+ string +
+
+ +
Specify context identifier.
+
+
+ protector + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable Edge Protector functionality for this VPN.
+
+
+ instance_role + +
+ string +
+
+
    Choices: +
  • access
  • +
  • nni
  • +
+
+
Primary role of L2Backhaul-vpn router.
+
+
+ interfaces + +
+ list + / elements=dictionary +
+
+ +
Interface name for this routing instance.
+
+
+ name + +
+ string +
+
+ +
Specify name of the interface.
+
+
+ protect_interface + +
+ string +
+
+ +
Specify name of the protected interface.
+
+
+ l2vpn_id + +
+ string +
+
+ +
Layer-2 vpn-id for this instance.
+
+
+ name + +
+ string +
+
+ +
Specify routing instance name.
+
+
+ no_irb_layer_2_copy + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable transmission of layer-2 copy of packets of irb routing-interface.
+
+
+ no_local_switching + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable vlan id normalization for interfaces.
+
+
+ no_normalization + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable vlan id normalization for interfaces.
+
+
+ no_vrf_advertise + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable vlan id normalization for interfaces.
+
+
+ no_vrf_propagate_ttl + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable TTL propagation from IP to MPLS (on push) and MPLS to IP (on pop).
+
+
+ qualified_bum_pruning_mode + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable BUM pruning for VPLS instance.
+
+
+ route_distinguisher + +
+ string +
+
+ +
Route distinguisher for this instance
+
+
+ routing_interface + +
+ list + / elements=string +
+
+ +
Routing interface name for this routing-instance.
+
+
+ type + +
+ string +
+
+
    Choices: +
  • evpn
  • +
  • evpn-vpws
  • +
  • forwarding
  • +
  • l2backhaul-vpn
  • +
  • l2vpn
  • +
  • layer2-control
  • +
  • mac-vrf
  • +
  • mpls-forwarding
  • +
  • mpls-internet-multicast
  • +
  • no-forwarding
  • +
  • virtual-router
  • +
  • virtual-switch
  • +
  • vpls
  • +
  • vrf
  • +
+
+
Specify instance type.
+
+
+ vrf_exports + +
+ list + / elements=string +
+
+ +
Export policy for VRF instance RIBs.
+
+
+ vrf_imports + +
+ list + / elements=string +
+
+ +
Import policy for VRF instance RIBs.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show routing-instances.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • parsed
  • +
  • gathered
  • +
  • rendered
  • +
+
+
The state the configuration should be left in.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # admin# show routing-instances + # + # [edit] + # vagrant@vsrx# show policy-options + # policy-statement test-policy { + # term t1 { + # then reject; + # } + # } + # policy-statement test-policy-1 { + # term t1 { + # then reject; + # } + # } + + - name: Merge Junos BGP address family configuration + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + state: merged + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # After state + # ----------- + # + # admin# show routing-instances + # forwardinst { + # description "Configured by Ansible Content Team"; + # instance-type forwarding; + # } + # test { + # instance-type vrf; + # interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined + # interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined + # route-distinguisher 10.58.255.1:37; + # vrf-import test-policy; + # vrf-export [ test-policy test-policy-1 ]; + # connector-id-advertise; + # } + # + # Using gathered + # + # Before state + # ------------ + # + # admin# show routing-instances + # + # [edit] + # admin# show routing-instances + # forwardinst { + # description "Configured by Ansible Content Team"; + # instance-type forwarding; + # } + # test { + # instance-type vrf; + # interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined + # interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined + # route-distinguisher 10.58.255.1:37; + # vrf-import test-policy; + # vrf-export [ test-policy test-policy-1 ]; + # connector-id-advertise; + # } + - name: Gather Junos routing-instances + junipernetworks.junos.junos_routing_instances: + state: gathered + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # "gathered": [ + # { + # "description": "Configured by Ansible Content Team", + # "name": "forwardinst", + # "type": "forwarding" + # }, + # { + # "connector_id_advertise": true, + # "interfaces": [ + # { + # "name": "gr-0/0/0.0" + # }, + # { + # "name": "sp-0/0/0.0" + # } + # ], + # "name": "test", + # "route_distinguisher": "10.58.255.1:37", + # "type": "vrf", + # "vrf_exports": [ + # "test-policy", + # "test-policy-1" + # ], + # "vrf_imports": [ + # "test-policy" + # ] + # } + # ] + # + # Using replaced + # + # Before state + # ------------ + # + # admin# show routing-instances + # forwardinst { + # description "Configured by Ansible Content Team"; + # instance-type forwarding; + # } + # test { + # instance-type vrf; + # interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined + # interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined + # route-distinguisher 10.58.255.1:37; + # vrf-import test-policy; + # vrf-export [ test-policy test-policy-1 ]; + # connector-id-advertise; + # } + + - name: Replace existing Junos routing instance config with provided config + junipernetworks.junos.junos_routing_instances: + config: + address_family: + - name: "test" + type: "vrf" + route_distinguisher: "10.57.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: false + description: "Configured by Ansible Content Team" + state: replaced + + # After state + # ----------- + # + # admin@vsrx# show routing-instances + # forwardinst { + # description "Configured by Ansible Content Team"; + # instance-type forwarding; + # } + # test { + # description "Configured by Ansible Content Team"; + # instance-type vrf; + # interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined + # interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined + # route-distinguisher 10.57.255.1:37; + # vrf-import test-policy; + # vrf-export test-policy; + # } + + # Using overridden + # + # Before state + # ------------ + # + # admin@vsrx# show routing-instances + # forwardinst { + # description "Configured by Ansible Content Team"; + # instance-type forwarding; + # } + # test { + # description "Configured by Ansible Content Team"; + # instance-type vrf; + # interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined + # interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined + # route-distinguisher 10.57.255.1:37; + # vrf-import test-policy; + # vrf-export test-policy; + # } + + - name: Override Junos routing-instances configuration + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + - name: "vtest1" + type: "virtual-router" + state: overridden + + # After state + # ----------- + # + # admin@vsrx# show routing-instances + # forwardinst { + # description "Configured by Ansible Content Team"; + # instance-type forwarding; + # } + # test { + # instance-type vrf; + # interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined + # interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined + # route-distinguisher 10.58.255.1:37; + # vrf-import test-policy; + # vrf-export [ test-policy test-policy-1 ]; + # connector-id-advertise; + # } + # vtest1 { + # instance-type virtual-router; + # } + + + # Using deleted + # + # Before state + # ------------ + # + # admin@vsrx# show routing-instances + # forwardinst { + # description "Configured by Ansible Content Team"; + # instance-type forwarding; + # } + # test { + # instance-type vrf; + # interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined + # interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined + # route-distinguisher 10.58.255.1:37; + # vrf-import test-policy; + # vrf-export [ test-policy test-policy-1 ]; + # connector-id-advertise; + # } + + - name: Delete provided junos routing-instamce + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + state: deleted + + # After state + # ----------- + # + # admin@vsrx# show routing-instances + # forwardinst { + # description "Configured by Ansible Content Team"; + # instance-type forwarding; + # } + + # Using deleted without config + # + # Before state + # ------------ + # + # admin@vsrx# show routing-instances + # forwardinst { + # description "Configured by Ansible Content Team"; + # instance-type forwarding; + # } + # test { + # instance-type vrf; + # interface gr-0/0/0.0; ## 'gr-0/0/0.0' is not defined + # interface sp-0/0/0.0; ## 'sp-0/0/0.0' is not defined + # route-distinguisher 10.58.255.1:37; + # vrf-import test-policy; + # vrf-export [ test-policy test-policy-1 ]; + # connector-id-advertise; + # } + # vtest1 { + # instance-type virtual-router; + # } + + - name: Delete complete Junos routing-instances config + junipernetworks.junos.junos_routing_instances: + config: + state: deleted + + # After state + # ----------- + # + # admin@vsrx# show routing-instances + # + # [edit] + + - name: Gather Junos BGP address family config + junipernetworks.junos.junos_routing_instances: + config: + state: gathered + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # "gathered": { + # "address_family": [ + # { + # "af_type": [ + # { + # "accepted_prefix_limit": { + # "idle_timeout_value": 2001, + # "limit_threshold": 98, + # "maximum": 20 + # }, + # "damping": true, + # "defer_initial_multipath_build": { + # "maximum_delay": 2 + # }, + # "type": "signaling" + # } + # ], + # "afi": "evpn" + # }, + # { + # "af_type": [ + # { + # "accepted_prefix_limit": { + # "idle_timeout_value": 2000, + # "limit_threshold": 99, + # "maximum": 20 + # }, + # "damping": true, + # "defer_initial_multipath_build": { + # "maximum_delay": 2 + # }, + # "delay_route_advertisements": { + # "max_delay_route_age": 20, + # "max_delay_routing_uptime": 32000, + # "min_delay_inbound_convergence": 32000, + # "min_delay_routing_uptime": 23000 + # }, + # "graceful_restart_forwarding_state_bit": "from-fib", + # "type": "any" + # }, + # { + # "legacy_redirect_ip_action": { + # "receive": true, + # "send": true + # }, + # "loops": 4, + # "no_install": true, + # "output_queue_priority_expedited": true, + # "secondary_independent_resolution": true, + # "type": "flow" + # }, + # { + # "entropy_label": { + # "no_next_hop_validation": true + # }, + # "explicit_null": { + # "connected_only": true + # }, + # "per_group_label": true, + # "per_prefix_label": true, + # "prefix_limit": { + # "forever": true, + # "limit_threshold": 99, + # "maximum": 20 + # }, + # "resolve_vpn": true, + # "rib": "inet.3", + # "route_refresh_priority_priority": 3, + # "type": "labeled-unicast" + # }, + # { + # "extended_nexthop": true, + # "extended_nexthop_color": true, + # "local_ipv4_address": "9.9.9.9", + # "type": "unicast" + # } + # ], + # "afi": "inet" + # } + # ] + # } + # + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # + # forwardinst + # Configured by Ansible Content Team + # forwarding + # + # + # test + # vrf + # + # gr-0/0/0.0 + # + # + # sp-0/0/0.0 + # + # + # 10.58.255.1:37 + # + # test-policy + # test-policy + # test-policy-1 + # + # + # + # + # + + - name: Parse routing instance running config + junipernetworks.junos.junos_routing_instances: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # + # "parsed": [ + # { + # "description": "Configured by Ansible Content Team", + # "name": "forwardinst", + # "type": "forwarding" + # }, + # { + # "connector_id_advertise": true, + # "interfaces": [ + # { + # "name": "gr-0/0/0.0" + # }, + # { + # "name": "sp-0/0/0.0" + # } + # ], + # "name": "test", + # "route_distinguisher": "10.58.255.1:37", + # "type": "vrf", + # "vrf_exports": [ + # "test-policy", + # "test-policy-1" + # ], + # "vrf_imports": [ + # "test-policy" + # ] + # } + # ] + # + # + # Using rendered + # + # + - name: Render the xml for provided configuration + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + state: rendered + + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # + # "rendered": " + # testvrf + # sp-0/0/0.0gr-0/0/0.0 + # 10.58.255.1:37 + # test-policytest-policy + # test-policy-1 + # forwardinstConfigured by Ansible Content Team + # forwarding" + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ list +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ list +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:routing-instances xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:instance> <nc:name>test</nc:name> <nc:connector-id-advertise/> <nc:instance-type>vrf</nc:instance-type> <nc:interface> <nc:name>sp-0/0/0.0</nc:name> </nc:interface> <nc:interface> <nc:name>gr-0/0/0.0</nc:name> </nc:interface> <nc:route-distinguisher> <nc:rd-type>10.58.255.1:37</nc:rd-type> </nc:route-distinguisher> <nc:vrf-import>test-policy</nc:vrf-import> <nc:vrf-export>test-policy</nc:vrf-export> <nc:vrf-export>test-policy-1</nc:vrf-export> </nc:instance> </routing-instances> </configuration> </rpc-reply>', 'xml2', 'xml 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Rohit Thakur (@rohitthakur2590) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_routing_options_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_routing_options_module.rst new file mode 100644 index 00000000..419e0b2b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_routing_options_module.rst @@ -0,0 +1,537 @@ +.. _junipernetworks.junos.junos_routing_options_module: + + +******************************************* +junipernetworks.junos.junos_routing_options +******************************************* + +**Manage routing-options configuration on Junos devices.** + + +Version added: 2.8.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages routing-options configuration on devices running Junos. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
A dictionary of routing-options configuration.
+
+
+ autonomous_system + +
+ dictionary +
+
+ +
Specify Autonomous system number.
+
+
+ as_number + +
+ string + / required +
+
+ +
Specify Autonomous system number.
+
+
+ asdot_notation + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable AS-Dot notation to display true 4 byte AS numbers.
+
+
+ loops + +
+ integer +
+
+ +
Specify maximum number of times this AS can be in an AS path.
+
+
+ router_id + +
+ string +
+
+ +
Specify Router identifier.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show system routing-options.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • deleted
  • +
  • overridden
  • +
  • parsed
  • +
  • gathered
  • +
  • rendered
  • +
+
+
The state the configuration should be left in.
+
Refer to examples for more details.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. + - See `the Junos OS Platform Options `_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # vagrant@vsrx# show system routing-options + # + - name: Merge provided NTP configuration into running configuration. + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + state: merged + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "autonomous_system": { + # "as_number": "2", + # "asdot_notation": true + # } + # }, + # "before": {}, + # "changed": true, + # "commands": [ + # "" + # "2" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show routing-options + # autonomous-system 2 asdot-notation; + # + # + # Using Replaced + # Before state + # ------------ + # + # vagrant@vsrx# show routing-options + # autonomous-system 2 asdot-notation; + + - name: Replaced running routing-options configuration with provided configuration + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + router_id: "1.1.1.1" + state: replaced + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "autonomous_system": { + # "as_number": "2", + # "asdot_notation": true + # }, + # "router_id": "1.1.1.1" + # }, + # "before": { + # "autonomous_system": { + # "as_number": "2", + # "asdot_notation": true + # } + # }, + # "changed": true, + # "commands": [ + # "" + # "2" + # "1.1.1.1" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show routing-options + # router-id 1.1.1.1; + # autonomous-system 2 asdot-notation; + + + # Using overridden + # + # vagrant@vsrx# show routing-options + # autonomous-system 2 asdot-notation; + + - name: Override running routing-options configuration with provided configuration + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + router_id: "1.1.1.1" + state: overridden + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "autonomous_system": { + # "as_number": "2", + # "asdot_notation": true + # }, + # "router_id": "1.1.1.1" + # }, + # "before": { + # "autonomous_system": { + # "as_number": "2", + # "asdot_notation": true + # } + # }, + # "changed": true, + # "commands": [ + # "" + # "2" + # "1.1.1.1" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show routing-options + # router-id 1.1.1.1; + # autonomous-system 2 asdot-notation; + # + # Using deleted + # + # Before state + # ------------ + # + # vagrant@vsrx# show routing-options + # router-id 1.1.1.1; + # autonomous-system 2 asdot-notation; + # + - name: Delete running routing-options configuration + junipernetworks.junos.junos_routing_options: + config: + state: deleted + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": {}, + # "before": { + # "autonomous_system": { + # "as_number": "2", + # "asdot_notation": true + # }, + # "router_id": "1.1.1.1" + # }, + # "changed": true, + # "commands": [ + # "" + # "" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show routing-options + # + # [edit] + # Using gathered + # + # Before state + # ------------ + # + # vagrant@vsrx# show routing-options + # router-id 1.1.1.1; + # autonomous-system 2 asdot-notation; + + - name: Gather running routing-options configuration + junipernetworks.junos.junos_routing_options: + state: gathered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "gathered": { + # "autonomous_system": { + # "as_number": "2", + # "asdot_notation": true + # }, + # "router_id": "1.1.1.1" + # }, + # "changed": false, + # Using rendered + # + # Before state + # ------------ + # + - name: Render xml for provided facts. + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + loops: 4 + router_id: 12.12.12.12 + state: rendered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "rendered": [ + # " + # "24 + # "12.12.12.12" + # ] + # + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # 12.12.12.12 + # + # 2 + # 4 + # + # + # + # + # + # + - name: Parse routing-options running config + junipernetworks.junos.junos_routing_options: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # + # "parsed": { + # "autonomous_system": { + # "as_number": "2", + # "asdot_notation": true, + # "loops": 4 + # }, + # "router_id": "12.12.12.12" + # } + # + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:autonomous-system delete="delete"/><nc:router-id delete="delete"/></nc:routing-options>']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Rohit Thakur (@rohitthakur2590) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_rpc_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_rpc_module.rst new file mode 100644 index 00000000..b9683588 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_rpc_module.rst @@ -0,0 +1,219 @@ +.. _junipernetworks.junos.junos_rpc_module: + + +******************************* +junipernetworks.junos.junos_rpc +******************************* + +**Runs an arbitrary RPC over NetConf on an Juniper JUNOS device** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- Sends a request to the remote device running JUNOS to execute the specified RPC using the NetConf transport. The reply is then returned to the playbook in the ``xml`` key. If an alternate output format is requested, the reply is transformed to the requested output. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.5.2) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ args + +
+ dictionary +
+
+ +
The args argument provides a set of arguments for the RPC call and are encoded in the request message. This argument accepts a set of key=value arguments.
+
+
+ attrs + +
+ dictionary +
+
+ +
The attrs arguments defines a list of attributes and their values to set for the RPC call. This accepts a dictionary of key-values.
+
+
+ output + +
+ string +
+
+
    Choices: +
  • xml ←
  • +
  • json
  • +
  • text
  • +
+
+
The output argument specifies the desired output of the return data. This argument accepts one of xml, text, or json. For json, the JUNOS device must be running a version of software that supports native JSON output.
+
+
+ rpc + +
+ string + / required +
+
+ +
The rpc argument specifies the RPC call to send to the remote devices to be executed. The RPC Reply message is parsed and the contents are returned to the playbook.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. + - Recommended connection is ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - This module also works with ``local`` connections for legacy playbooks. + - For information on using CLI and netconf see the :ref:`Junos OS Platform Options guide ` + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` + - For more information on using Ansible to manage Juniper network devices see https://www.ansible.com/ansible-juniper. + + + +Examples +-------- + +.. code-block:: yaml + + - name: collect interface information using rpc + junipernetworks.junos.junos_rpc: + rpc: get-interface-information + args: + interface-name: em0 + media: true + + - name: get system information + junipernetworks.junos.junos_rpc: + rpc: get-system-information + + - name: load configuration + junipernetworks.junos.junos_rpc: + rpc: load-configuration + attrs: + action: override + url: /tmp/config.conf + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ output + +
+ string +
+
always +
The rpc rely converted to the output format.
+
+
+
+ output_lines + +
+ list +
+
always +
The text output split into lines for readability.
+
+
+
+ xml + +
+ string +
+
always +
The xml return string from the rpc request.
+
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Peter Sprygada (@privateip) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_scp_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_scp_module.rst new file mode 100644 index 00000000..389939e1 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_scp_module.rst @@ -0,0 +1,376 @@ +.. _junipernetworks.junos.junos_scp_module: + + +******************************* +junipernetworks.junos.junos_scp +******************************* + +**Transfer files from or to remote devices running Junos** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + +DEPRECATED +---------- +:Removed in collection release after 2025-01-01 +:Why: Updated modules released with more functionality +:Alternative: Use :ref:`ansible.netcommon.net_get `, :ref:`ansible.netcommon.net_put ` instead. + + + +Synopsis +-------- +- This module transfers files via SCP from or to remote devices running Junos. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- junos-eznc +- ncclient (>=v0.5.2) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ dest + +
+ path +
+
+ Default:
"."
+
+
The dest argument specifies the path in which to receive the files.
+
+
+ provider + +
+ dictionary +
+
+ +
Deprecated
+
Starting with Ansible 2.5 we recommend using connection: network_cli or connection: netconf.
+
For more information please see the Junos OS Platform Options guide.
+

+
A dict object containing connection details.
+
+
+ host + +
+ string +
+
+ +
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.
+
+
+ password + +
+ string +
+
+ +
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 ANSIBLE_NET_PASSWORD will be used instead.
+
+
+ port + +
+ integer +
+
+ +
Specifies the port to use when building the connection to the remote device. The port value will default to the well known SSH port of 22 (for transport=cli) or port 830 (for transport=netconf) device.
+
+
+ ssh_keyfile + +
+ path +
+
+ +
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 ANSIBLE_NET_SSH_KEYFILE will be used instead.
+
+
+ timeout + +
+ integer +
+
+ +
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.
+
+
+ transport + +
+ string +
+
+
    Choices: +
  • cli
  • +
  • netconf ←
  • +
+
+
Configures the transport connection to use when connecting to the remote device.
+
+
+ username + +
+ string +
+
+ +
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 ANSIBLE_NET_USERNAME will be used instead.
+
+
+ recursive + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
The recursive argument enables recursive transfer of files and directories.
+
+
+ remote_src + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
The remote_src argument enables the download of files (scp get) from the remote device. The default behavior is to upload files (scp put) to the remote device.
+
+
+ src + +
+ list + / elements=path + / required +
+
+ +
The src argument takes a single path, or a list of paths to be transferred. The argument recursive must be true to transfer directories.
+
+
+ ssh_config + +
+ path +
+
+ +
The ssh_config argument is path to the SSH configuration file. This can be used to load SSH information from a configuration file. If this option is not given by default ~/.ssh/config is queried.
+
+
+ ssh_private_key_file + +
+ path +
+
+ +
The ssh_private_key_file argument is path to the SSH private key file. This can be used if you need to provide a private key rather than loading the key into the ssh-key-ring/environment
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vMX JUNOS version 17.3R1.10. + - Works with ``local`` connections only. + - Since this module uses junos-eznc to establish connection with junos device the netconf configuration parameters needs to be passed using module options for example ``ssh_config`` unlike other junos modules that uses ``netconf`` connection type. + - For information on using CLI and netconf see the :ref:`Junos OS Platform Options guide ` + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` + - For more information on using Ansible to manage Juniper network devices see https://www.ansible.com/ansible-juniper. + + + +Examples +-------- + +.. code-block:: yaml + + # the required set of connection arguments have been purposely left off + # the examples for brevity + - name: upload local file to home directory on remote device + junipernetworks.junos.junos_scp: + src: test.tgz + + - name: upload local file to tmp directory on remote device + junipernetworks.junos.junos_scp: + src: test.tgz + dest: /tmp/ + + - name: download file from remote device + junipernetworks.junos.junos_scp: + src: test.tgz + remote_src: true + + - name: ssh config file path for jumphost config + junipernetworks.junos.junos_scp: + src: test.tgz + remote_src: true + ssh_config: /home/user/customsshconfig + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + +
KeyReturnedDescription
+
+ changed + +
+ boolean +
+
always +
always true
+
+
+

+ + +Status +------ + + +- This module will be removed in a release after 2025-01-01. *[deprecated]* +- For more information see `DEPRECATED`_. + + +Authors +~~~~~~~ + +- Christian Giese (@GIC-de) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_security_policies_global_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_security_policies_global_module.rst new file mode 100644 index 00000000..24a16305 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_security_policies_global_module.rst @@ -0,0 +1,1446 @@ +.. _junipernetworks.junos.junos_security_policies_global_module: + + +**************************************************** +junipernetworks.junos.junos_security_policies_global +**************************************************** + +**Manage global security policy settings on Juniper JUNOS devices** + + +Version added: 2.9.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module provides declarative management of global security policy settings on Juniper JUNOS devices + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
A dictionary of security policies
+
+
+ default_policy + +
+ string +
+
+
    Choices: +
  • deny-all
  • +
  • permit-all
  • +
+
+
Configure the default security policy that defines the actions the device takes on a packet that does not match any user-defined policy.
+
+
+ policy_rematch + +
+ dictionary +
+
+ +
Enable the device to reevaluate an active session when its associated security policy is modified. The session remains open if it still matches the policy that allowed the session initially.
+
+
+ enable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable the device to reevaluate an active session when its associated security policy is modified. The session remains open if it still matches the policy that allowed the session initially.
+
+
+ extensive + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
When a policy is modified or deleted, extensive option checks if any suitable policy permit to keep these sessions alive.
+
+
+ policy_stats + +
+ dictionary +
+
+ +
Configure policies statistics.
+
+
+ enable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable policies statistics.
+
+
+ system_wide + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Configure systemwide policies statistics.
+
+
+ pre_id_default_policy_action + +
+ dictionary +
+
+ +
Configures default policy actions that occur prior to dynamic application identification (AppID) when the packet matches the criteria.
+
+
+ log + +
+ dictionary +
+
+ +
Specifies the log details at session close time and session initialization time.
+
+
+ session_close + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable logging on session close time
+
+
+ session_init + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable logging on session initialization time
+
+
+ session_timeout + +
+ dictionary +
+
+ +
When you update a session, the session timeout is configured, which specifies the session timeout details in seconds.
+
+
+ icmp + +
+ integer +
+
+ +
Timeout value for ICMP sessions (seconds)
+
+
+ icmp6 + +
+ integer +
+
+ +
Timeout value for ICMP6 sessions (seconds)
+
+
+ ospf + +
+ integer +
+
+ +
Timeout value for OSPF sessions (seconds)
+
+
+ others + +
+ integer +
+
+ +
Timeout value for other sessions (seconds)
+
+
+ tcp + +
+ integer +
+
+ +
Timeout value for TCP sessions (seconds)
+
+
+ udp + +
+ integer +
+
+ +
Timeout value for UDP sessions (seconds)
+
+
+ traceoptions + +
+ dictionary +
+
+ +
A dictionary of security policies
+
+
+ file + +
+ dictionary +
+
+ +
A dictionary to configure the trace file options
+
+
+ files + +
+ integer +
+
+ +
Maximum number of trace files
+
+
+ match + +
+ string +
+
+ +
Refine the output to include lines that contain the regular expression.
+
+
+ no_world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Log files can be accessed only by the user who configures the tracing operation.
+
+
+ size + +
+ string +
+
+ +
The maximum tracefile size
+
+
+ world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
The world_readable option enables any user to read the file.
+
+
+ flag + +
+ string +
+
+
    Choices: +
  • all
  • +
  • configuration
  • +
  • compilation
  • +
  • ipc
  • +
  • lookup
  • +
  • routing-socket
  • +
  • rules
  • +
+
+
Trace operation to perform.
+
+
+ no_remote_trace + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable remote tracing.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the JunOS device by executing the command show security policies.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • rendered
  • +
  • gathered
  • +
  • parsed
  • +
+
+
The state the configuration should be left in
+
The states rendered, gathered and parsed does not perform any change on the device.
+
The state rendered will transform the configuration in config option to platform specific CLI commands which will be returned in the rendered key within the result. For state rendered active connection to remote host is not required. behaviour for this module.
+
The state replaced will replace the running configuration with the provided configuration
+
The state replaced and state overridden have the same behaviour
+
The state 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 gathered key within the result.
+
The state parsed reads the configuration from running_config option and transforms it into JSON format as per the resource module parameters and the value is returned in the parsed key within the result. The value of running_config option should be the same format as the output of command show security policies detail executed on device. For state parsed active connection to remote host is not required.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. + - See `the Junos OS Platform Options `_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # vagrant@vsrx# show security policies + # default-policy { + # permit-all; + # } + # + - name: Update the running configuration with provided configuration + junipernetworks.junos.junos_security_policies_global: + config: + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + no_world_readable: true + flag: all + no_remote_trace: true + state: merged + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "default_policy": "permit-all", + # "policy_rematch": { + # "enable": true, + # "extensive": true + # }, + # "policy_stats": { + # "enable": true, + # "system_wide": true + # }, + # "pre_id_default_policy_action": { + # "log": { + # "session_init": true + # }, + # "session_timeout": { + # "icmp": 10, + # "others": 10 + # } + # }, + # "traceoptions": { + # "file": { + # "files": 3, + # "match": "/[A-Z]*/gm", + # "no_world_readable": true, + # "size": "10k" + # }, + # "flag": "all", + # "no_remote_trace": true + # } + # }, + # "before": {}, + # "changed": true, + # "commands": " + # + # enable + # 10 + # 10 + # 3/[A-Z]*/gm + # 10kall + # " + # After state + # ----------- + # + # vagrant@vsrx# show security policies + # traceoptions { + # no-remote-trace; + # file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; + # flag all; + # } + # default-policy { + # permit-all; + # } + # policy-rematch extensive; + # policy-stats; + # pre-id-default-policy { + # then { + # log { + # session-init; + # } + # session-timeout { + # icmp 10; + # others 10; + # } + # } + # } + # + # + # Using Replaced + # Before state + # ------------ + # + # vagrant@vsrx# show security policies + # traceoptions { + # no-remote-trace; + # file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; + # flag all; + # } + # default-policy { + # permit-all; + # } + # policy-rematch extensive; + # policy-stats; + # pre-id-default-policy { + # then { + # log { + # session-init; + # } + # session-timeout { + # icmp 10; + # others 10; + # } + # } + # } + + - name: Replace the running configuration with provided configuration + junipernetworks.junos.junos_security_policies_global: + config: + default_policy: deny-all + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + no_world_readable: true + flag: all + no_remote_trace: true + state: replaced + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "default_policy": "deny-all", + # "policy_rematch": { + # "enable": true + # }, + # "policy_stats": { + # "enable": true + # }, + # "pre_id_default_policy_action": { + # "log": { + # "session_init": true + # }, + # "session_timeout": { + # "icmp": 10, + # "others": 10 + # } + # }, + # "traceoptions": { + # "file": { + # "files": 4, + # "match": "/[A-Z]*/gm", + # "no_world_readable": true, + # "size": "10k" + # }, + # "flag": "all", + # "no_remote_trace": true + # } + # }, + # "before": { + # "default_policy": "permit-all", + # "policy_rematch": { + # "enable": true, + # "extensive": true + # }, + # "policy_stats": { + # "enable": true + # }, + # "pre_id_default_policy_action": { + # "log": { + # "session_init": true + # }, + # "session_timeout": { + # "icmp": 10, + # "others": 10 + # } + # }, + # "traceoptions": { + # "file": { + # "files": 4, + # "match": "/[A-Z]*/gm", + # "no_world_readable": true, + # "size": "10k" + # }, + # "flag": "all", + # "no_remote_trace": true + # } + # }, + # "changed": true, + # "commands": " + # + # + # 1010 + # + # 4/[A-Z]*/gm10k + # all + # " + # + # After state + # ----------- + # + # vagrant@vsrx# show security policies + # traceoptions { + # no-remote-trace; + # file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; + # flag all; + # } + # default-policy { + # deny-all; + # } + # policy-rematch; + # policy-stats; + # pre-id-default-policy { + # then { + # log { + # session-init; + # } + # session-timeout { + # icmp 10; + # others 10; + # } + # } + # } + + # Using overridden + # + # Before state + # ------------ + # + # vagrant@vsrx# show security policies + # traceoptions { + # no-remote-trace; + # file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; + # flag all; + # } + # default-policy { + # permit-all; + # } + # policy-rematch extensive; + # policy-stats; + # pre-id-default-policy { + # then { + # log { + # session-init; + # } + # session-timeout { + # icmp 10; + # others 10; + # } + # } + # } + + - name: Replace the running configuration with provided configuration + junipernetworks.junos.junos_security_policies_global: + config: + default_policy: deny-all + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + no_world_readable: true + flag: all + no_remote_trace: true + state: overridden + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "default_policy": "deny-all", + # "policy_rematch": { + # "enable": true + # }, + # "policy_stats": { + # "enable": true + # }, + # "pre_id_default_policy_action": { + # "log": { + # "session_init": true + # }, + # "session_timeout": { + # "icmp": 10, + # "others": 10 + # } + # }, + # "traceoptions": { + # "file": { + # "files": 4, + # "match": "/[A-Z]*/gm", + # "no_world_readable": true, + # "size": "10k" + # }, + # "flag": "all", + # "no_remote_trace": true + # } + # }, + # "before": { + # "default_policy": "permit-all", + # "policy_rematch": { + # "enable": true, + # "extensive": true + # }, + # "policy_stats": { + # "enable": true + # }, + # "pre_id_default_policy_action": { + # "log": { + # "session_init": true + # }, + # "session_timeout": { + # "icmp": 10, + # "others": 10 + # } + # }, + # "traceoptions": { + # "file": { + # "files": 4, + # "match": "/[A-Z]*/gm", + # "no_world_readable": true, + # "size": "10k" + # }, + # "flag": "all", + # "no_remote_trace": true + # } + # }, + # "changed": true, + # "commands": " + # + # + # 1010 + # + # 4/[A-Z]*/gm10k + # all + # " + # + # After state + # ----------- + # + # vagrant@vsrx# show security policies + # traceoptions { + # no-remote-trace; + # file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; + # flag all; + # } + # default-policy { + # deny-all; + # } + # policy-rematch; + # policy-stats; + # pre-id-default-policy { + # then { + # log { + # session-init; + # } + # session-timeout { + # icmp 10; + # others 10; + # } + # } + # } + # + # Using deleted + # + # Before state + # ------------ + # + # vagrant@vsrx# show security policies + # traceoptions { + # no-remote-trace; + # file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; + # flag all; + # } + # default-policy { + # deny-all; + # } + # policy-rematch; + # policy-stats; + # pre-id-default-policy { + # then { + # log { + # session-init; + # } + # session-timeout { + # icmp 10; + # others 10; + # } + # } + # } + # + - name: Delete the running configuration + junipernetworks.junos.junos_security_policies_global: + config: + state: deleted + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": {}, + # "before": { + # "default_policy": "deny-all", + # "policy_rematch": { + # "enable": true + # }, + # "policy_stats": { + # "enable": true + # }, + # "pre_id_default_policy_action": { + # "log": { + # "session_init": true + # }, + # "session_timeout": { + # "icmp": 10, + # "others": 10 + # } + # }, + # "traceoptions": { + # "file": { + # "files": 4, + # "match": "/[A-Z]*/gm", + # "no_world_readable": true, + # "size": "10k" + # }, + # "flag": "all", + # "no_remote_trace": true + # } + # }, + # "changed": true, + # "commands": " + # " + # + # After state + # ----------- + # + # vagrant@vsrx# show security policies + # + # + # Using gathered + # + # Before state + # ------------ + # + # vagrant@vsrx# show security policies + # traceoptions { + # no-remote-trace; + # file size 10k files 4 no-world-readable match "/[A-Z]*/gm"; + # flag all; + # } + # default-policy { + # deny-all; + # } + # policy-rematch; + # policy-stats; + # pre-id-default-policy { + # then { + # log { + # session-init; + # } + # session-timeout { + # icmp 10; + # others 10; + # } + # } + # } + # + - name: Gather the running configuration + junipernetworks.junos.junos_security_policies_global: + config: + state: gathered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "gathered": { + # "default_policy": "deny-all", + # "policy_rematch": { + # "enable": true + # }, + # "policy_stats": { + # "enable": true + # }, + # "pre_id_default_policy_action": { + # "log": { + # "session_init": true + # }, + # "session_timeout": { + # "icmp": 10, + # "others": 10 + # } + # }, + # "traceoptions": { + # "file": { + # "files": 4, + # "match": "/[A-Z]*/gm", + # "no_world_readable": true, + # "size": "10k" + # }, + # "flag": "all", + # "no_remote_trace": true + # } + # } + # + # Using rendered + # + # Before state + # ------------ + # + - name: Render the provided configuration + junipernetworks.junos.junos_security_policies_global: + config: + default_policy: deny-all + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + no_world_readable: true + flag: all + no_remote_trace: true + state: replaced + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "rendered": " + # + # + # 1010 + # 4 + # /[A-Z]*/gm10k + # all + # " + # + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # + # + # + # + # 10k + # 3 + # + # /[A-Z]*/gm + # + # + # all + # + # + # + # + # + # + # + # + # + # enable + # + # + # + # + # + # + # + # 10 + # 10 + # + # + # + # + # + # + # + # + # + - name: Parse security policies global running config + junipernetworks.junos.junos_security_policies_global: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # + # "parsed": { + # "default_policy": "permit-all", + # "policy_rematch": { + # "enable": true, + # "extensive": true + # }, + # "policy_stats": { + # "enable": true, + # "system_wide": true + # }, + # "pre_id_default_policy_action": { + # "log": { + # "session_init": true + # }, + # "session_timeout": { + # "icmp": 10, + # "others": 10 + # } + # }, + # "traceoptions": { + # "file": { + # "files": 3, + # "match": "/[A-Z]*/gm", + # "no_world_readable": true, + # "size": "10k" + # }, + # "flag": "all", + # "no_remote_trace": true + # } + # } + # + # + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration after module execution.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ before + +
+ dictionary +
+
when state is merged, replaced, overridden, deleted +
The configuration prior to the module execution.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ commands + +
+ list +
+
when state is merged, replaced, overridden or deleted +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<rpc-reply> <configuration> <security> <policies> <default-policy> <permit-all /> </default-policy> </policies> </security> </configuration> </rpc-reply>']
+
+
+ gathered + +
+ dictionary +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ dictionary +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ dictionary +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['<rpc-reply> <configuration> <security> <policies> <default-policy> <permit-all /> </default-policy> </policies> </security> </configuration> </rpc-reply>']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Pranav Bhatt (@pranav-bhatt) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_security_policies_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_security_policies_module.rst new file mode 100644 index 00000000..34e35428 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_security_policies_module.rst @@ -0,0 +1,7392 @@ +.. _junipernetworks.junos.junos_security_policies_module: + + +********************************************* +junipernetworks.junos.junos_security_policies +********************************************* + +**Create and manage security policies on Juniper JUNOS devices** + + +Version added: 2.9.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module provides declarative creation and management of security policies on Juniper JUNOS devices + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
A dictionary of security policies
+
+
+ from_zones + +
+ list + / elements=dictionary +
+
+ +
List of security zones from which the traffic originates from
+
+
+ name + +
+ string +
+
+ +
The name of the security zone from which the traffic originates from
+
+
+ to_zones + +
+ list + / elements=dictionary +
+
+ +
List of destination security zones of the traffic
+
+
+ name + +
+ string +
+
+ +
The name of the destination security zone of the traffic
+
+
+ policies + +
+ list + / elements=dictionary +
+
+ +
List of policies defined for the associated category
+
+
+ description + +
+ string +
+
+ +
Description of the security policy
+
+
+ match + +
+ dictionary +
+
+ +
Configure security policy match criteria
+
+
+ application + +
+ dictionary +
+
+ +
Specify the IP or remote procedure call (RPC) application or set of applications to be used as match criteria
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Match any predefined or custom applications or application sets
+
+
+ names + +
+ list + / elements=string +
+
+ +
Name of the predefined or custom application or application set used as match criteria
+
+
+ destination_address + +
+ dictionary +
+
+ +
Define the matching criteria You can specify one or more IP addresses, address sets, or wildcard addresses
+
+
+ addresses + +
+ list + / elements=string +
+
+ +
IP address, IP address set, or address book entry, or wildcard address (represented as ABCD/wildcard_mask)
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any IPv4 or IPv6 address
+
+
+ any_ipv4 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any IPv4 address
+
+
+ any_ipv6 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any IPv6 address
+
+
+ destination_address_excluded + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Exclude destination addresses
+
+
+ dynamic_application + +
+ dictionary +
+
+ +
Specify the dynamic applications or dynamic application groups used as match criteria within a security policy
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Configuring the dynamic application as any installs the policy with the application as a wildcard (default)
+
+
+ names + +
+ list + / elements=string +
+
+ +
Specify dynamic applications or dynamic application groups
+
+
+ none + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Configuring the dynamic application as none ignores classification results from AppID and does not use the dynamic application in security policy lookups
+
+
+ from_zone + +
+ dictionary +
+
+ +
Identify a single source zone or multiple source zones to be used as a match criteria for a policy
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Match any zone
+
+
+ junos_host + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
junos-host
+
+
+ names + +
+ list + / elements=string +
+
+ +
Name of single or multiple source zone
+
+
+ source_address + +
+ dictionary +
+
+ +
Define the matching criteria You can specify one or more IP addresses, address sets, or wildcard addresses
+
+
+ addresses + +
+ list + / elements=string +
+
+ +
IP address, IP address set, or address book entry, or wildcard address (represented as ABCD/wildcard_mask)
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any IPv4 or IPv6 address
+
+
+ any_ipv4 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any IPv4 address
+
+
+ any_ipv6 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any IPv6 address
+
+
+ source_address_excluded + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Exclude source addresses
+
+
+ source_end_user_profile + +
+ string +
+
+ +
Source end user profile name
+
+
+ source_identity + +
+ dictionary +
+
+ +
Identifies users and roles to be used as match criteria for a policy
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any user or role, as well as the keywords authenticated_user, unauthenticated_user, and unknown_user
+
+
+ authenticated_user + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
All users and roles that have been authenticated
+
+
+ names + +
+ list + / elements=string +
+
+ +
A list of specific users and roles
+
+
+ unauthenticated_user + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any user or role that does not have an IP_address mapped to authentication sources and the authentication source is up and running
+
+
+ unknown_user + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any user or role that does not have an IP address mapped to authentication sources, because the authentication source is disconnected from the SRX Series device
+
+
+ to_zone + +
+ dictionary +
+
+ +
Identify a single destination zone or multiple destination zones to be used as a match criteria for a policy
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Match any zone
+
+
+ junos_host + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
junos-host
+
+
+ names + +
+ list + / elements=string +
+
+ +
Name of single or multiple destination zone
+
+
+ url_category + +
+ dictionary +
+
+ +
URL category
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Apply to any url category
+
+
+ names + +
+ list + / elements=string +
+
+ +
Names of url category to match
+
+
+ none + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not apply to the url category
+
+
+ name + +
+ string +
+
+ +
Name of the policy
+
+
+ scheduler_name + +
+ string +
+
+ +
Name of the scheduler to run this policy
+
+
+ then + +
+ dictionary +
+
+ +
Specify the policy action to be performed when packets match the defined criteria
+
+
+ count + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable a count, in bytes or kilobytes, of all network traffic the policy allows to pass through the device in both directions; the originating traffic from the client to the server (from the from_zone to the to_zone), and the return traffic from the server to the originating client
+
+
+ deny + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Block the service at the firewall The device drops the packets
+
+
+ log + +
+ dictionary +
+
+ +
Log traffic information for a specific policy Traffic information is logged when a session begins (session_init) or closes (session_close)
+
+
+ session_close + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable logging on session close time
+
+
+ session_init + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable logging on session initialization time
+
+
+ permit + +
+ dictionary +
+
+ +
Block the service at the firewall The device drops the packets
+
+
+ application_services + +
+ dictionary +
+
+ +
Enable application services within a security policy
+
+
+ advanced_anti_malware_policy + +
+ string +
+
+ +
Specify advanced_anti_malware policy name
+
+
+ application_firewalls + +
+ list + / elements=dictionary +
+
+ +
Specify the rule sets configured as part of application firewall to be applied to the permitted traffic
+
+
+ rule_set + +
+ string +
+
+ +
name of rule set to use
+
+
+ application_traffic_control_rule_set + +
+ string +
+
+ +
Specify the rule set configured as part of AppQoS, application_aware quality of service, to be applied to the permitted traffic
+
+
+ gprs_gtp_profile + +
+ string +
+
+ +
Specify GPRS tunneling protocol profile name
+
+
+ gprs_sctp_profile + +
+ string +
+
+ +
Specify GPRS stream control protocol profile name
+
+
+ icap_redirect + +
+ string +
+
+ +
Specify icap redirect profile name
+
+
+ idp + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Intrusion Detection and Prevention (IDP)
+
+
+ idp_policy + +
+ string +
+
+ +
Specify IDP policy name
+
+
+ packet_capture + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Option to enable or disable packet capture
+
+
+ redirect_wx + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify the WX redirection needed for the packets that arrive from the LAN
+
+
+ reverse_redirect_wx + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify the WX redirection needed for the reverse flow of the packets that arrive from the WAN
+
+
+ security_intelligence + +
+ dictionary +
+
+ +
Specify the security intelligence feed post action
+
+
+ add_destination_identity_to_feed + +
+ string +
+
+ +
Add destination user identity to the security feed
+
+
+ add_destination_ip_to_feed + +
+ string +
+
+ +
Add the destination IP address to the security feed
+
+
+ add_source_identity_to_feed + +
+ string +
+
+ +
Add source user identity to the security feed
+
+
+ add_source_ip_to_feed + +
+ string +
+
+ +
Add the source IP address to the security feed
+
+
+ security_intelligence_policy + +
+ string +
+
+ +
Specify security_intelligence policy name
+
+
+ ssl_proxy + +
+ dictionary +
+
+ +
You can apply a redirect SSL proxy profile when a policy blocks HTTPS traffic with a reject action
+
+
+ enable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable SSL proxy
+
+
+ profile_name + +
+ string +
+
+ +
Name of SSL proxy profile
+
+
+ uac_policy + +
+ dictionary +
+
+ +
Enable Unified Access Control (UAC) for the security policy
+
+
+ captive_portal + +
+ string +
+
+ +
Specify the preconfigured security policy for captive portal on the Junos OS Enforcer to enable the captive portal feature
+
+
+ enable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable Unified Access Control (UAC)
+
+
+ utm_policy + +
+ string +
+
+ +
Specify UTM policy name
+
+
+ destination_address + +
+ string +
+
+
    Choices: +
  • drop-translated
  • +
  • drop-untranslated
  • +
+
+
Specify whether the traffic permitted by the security policy is limited to packets where the destination IP address has been translated by means of a destination NAT rule or to packets where the destination IP address has not been translated
+
+
+ firewall_authentication + +
+ dictionary +
+
+ +
Configure firewall authentication methods
+
+
+ pass_through + +
+ dictionary +
+
+ +
Configure pass-through firewall user authentication
+
+
+ access_profile + +
+ string +
+
+ +
Specify the name of the access profile
+
+
+ auth_only_browser + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Configure firewall authentication to ignore non-browser HTTP/HTTPS traffic
+
+
+ auth_user_agent + +
+ string +
+
+ +
Specify a user-agent value to be used to verify that the user's browser traffic is HTTP/HTTPS traffic
+
+
+ client_match + +
+ string +
+
+ +
Specify the name of the users or user groups in a profile who are allowed access by this policy
+
+
+ ssl_termination_profile + +
+ string +
+
+ +
Specify the SSL termination profile used for SSL offloading
+
+
+ web_redirect + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable redirecting an HTTP request to the device and redirecting the client system to a webpage for authentication
+
+
+ web_redirect_to_https + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Redirect unauthenticated HTTP requests to the internal HTTPS Web server of the device
+
+
+ push_to_identity_management + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
enables pushing to identity management devices
+
+
+ user_firewall + +
+ dictionary +
+
+ +
Configure user role firewall authentication, and map the source IP address to the username and its associated roles (groups)
+
+
+ access_profile + +
+ string +
+
+ +
Specify the name of the access profile to be used for authentication
+
+
+ auth_only_browser + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Configure firewall authentication to ignore non-browser HTTP/HTTPS traffic
+
+
+ auth_user_agent + +
+ string +
+
+ +
Specify a user-agent value to be used to verify that the user's browser traffic is HTTP/HTTPS traffic
+
+
+ domain + +
+ string +
+
+ +
Specify the name of the domain where firewall authentication occurs in the event that the Windows Management Instrumentation client (WMIC) is not available to get IP_to_user mapping for the integrated user firewall feature
+
+
+ ssl_termination_profile + +
+ string +
+
+ +
For HTTPS traffic, specify the name of the SSL termination profile used for SSL offloading
+
+
+ web_redirect + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable webpage redirection
+
+
+ web_redirect_to_https + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable redirection to HTTPS
+
+
+ web_authentication + +
+ list + / elements=string +
+
+ +
Specify that the policy allows access to users or user groups who have previously been authenticated by Web authentication
+
+
+ tcp_options + +
+ dictionary +
+
+ +
Specify the TCP options for each policy You can configure sync and sequence checks for each policy based on your requirements, and, because each policy has two directions, you can configure a TCP MSS value for both directions or for just one direction
+
+
+ initial_tcp_mss + +
+ integer +
+
+ +
Configure the TCP maximum segment size (MSS) for packets that arrive at the ingress interface (initial direction), match a specific policy, and for which a session is created
+
+
+ reverse_tcp_mss + +
+ integer +
+
+ +
Configure the TCP maximum segment size (MSS) for packets that match a specific policy and travel in the reverse direction of a session
+
+
+ sequence_check_required + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable sequence check per policy The sequence_check_required value overrides the global value no_sequence_check
+
+
+ syn_check_required + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable sync check per policy The syn_check_required value overrides the global value no_syn_check
+
+
+ window_scale + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable window_scale per policy
+
+
+ tunnel + +
+ dictionary +
+
+ +
Encapsulate outgoing IP packets and decapsulate incoming IP packets
+
+
+ ipsec_vpn + +
+ string +
+
+ +
name of the ipsec policy
+
+
+ pair_policy + +
+ string +
+
+ +
name of the pair policy
+
+
+ reject + +
+ dictionary +
+
+ +
Block the service at the firewall The device drops the packet and sends a TCP reset (RST) segment to the source host for TCP traffic and an ICMP "destination unreachable, port unreachable" message (type 3, code 3) for UDP traffic
+
+
+ enable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable rejection of packets based on match criteria
+
+
+ profile + +
+ string +
+
+ +
You can chose to provide a notification to the clients or redirect client request to an informative Web page when a policy blocks HTTP or HTTPS traffic with a deny or reject action
+
+
+ ssl_proxy + +
+ dictionary +
+
+ +
You can apply a redirect SSL proxy profile when a policy blocks HTTPS traffic with a reject action When you apply am SSL proxy profile, SSL proxy decrypts the traffic and application identification functionality identifies the application
+
+
+ enable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable SSL proxy
+
+
+ profile_name + +
+ string +
+
+ +
Name of SSL proxy profile
+
+
+ global + +
+ dictionary +
+
+ +
List of global security policies
+
+
+ policies + +
+ list + / elements=dictionary +
+
+ +
List of policies defined for the associated category
+
+
+ description + +
+ string +
+
+ +
Description of the security policy
+
+
+ match + +
+ dictionary +
+
+ +
Configure security policy match criteria
+
+
+ application + +
+ dictionary +
+
+ +
Specify the IP or remote procedure call (RPC) application or set of applications to be used as match criteria
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Match any predefined or custom applications or application sets
+
+
+ names + +
+ list + / elements=string +
+
+ +
Name of the predefined or custom application or application set used as match criteria
+
+
+ destination_address + +
+ dictionary +
+
+ +
Define the matching criteria You can specify one or more IP addresses, address sets, or wildcard addresses
+
+
+ addresses + +
+ list + / elements=string +
+
+ +
IP address, IP address set, or address book entry, or wildcard address (represented as ABCD/wildcard_mask)
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any IPv4 or IPv6 address
+
+
+ any_ipv4 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any IPv4 address
+
+
+ any_ipv6 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any IPv6 address
+
+
+ destination_address_excluded + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Exclude destination addresses
+
+
+ dynamic_application + +
+ dictionary +
+
+ +
Specify the dynamic applications or dynamic application groups used as match criteria within a security policy
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Configuring the dynamic application as any installs the policy with the application as a wildcard (default)
+
+
+ names + +
+ list + / elements=string +
+
+ +
Specify dynamic applications or dynamic application groups
+
+
+ none + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Configuring the dynamic application as none ignores classification results from AppID and does not use the dynamic application in security policy lookups
+
+
+ from_zone + +
+ dictionary +
+
+ +
Identify a single source zone or multiple source zones to be used as a match criteria for a policy
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Match any zone
+
+
+ junos_host + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
junos-host
+
+
+ names + +
+ list + / elements=string +
+
+ +
Name of single or multiple source zone
+
+
+ source_address + +
+ dictionary +
+
+ +
Define the matching criteria You can specify one or more IP addresses, address sets, or wildcard addresses
+
+
+ addresses + +
+ list + / elements=string +
+
+ +
IP address, IP address set, or address book entry, or wildcard address (represented as ABCD/wildcard_mask)
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any IPv4 or IPv6 address
+
+
+ any_ipv4 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any IPv4 address
+
+
+ any_ipv6 + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any IPv6 address
+
+
+ source_address_excluded + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Exclude source addresses
+
+
+ source_end_user_profile + +
+ string +
+
+ +
Source end user profile name
+
+
+ source_identity + +
+ dictionary +
+
+ +
Identifies users and roles to be used as match criteria for a policy
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any user or role, as well as the keywords authenticated_user, unauthenticated_user, and unknown_user
+
+
+ authenticated_user + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
All users and roles that have been authenticated
+
+
+ names + +
+ list + / elements=string +
+
+ +
A list of specific users and roles
+
+
+ unauthenticated_user + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any user or role that does not have an IP_address mapped to authentication sources and the authentication source is up and running
+
+
+ unknown_user + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Any user or role that does not have an IP address mapped to authentication sources, because the authentication source is disconnected from the SRX Series device
+
+
+ to_zone + +
+ dictionary +
+
+ +
Identify a single destination zone or multiple destination zones to be used as a match criteria for a policy
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Match any zone
+
+
+ junos_host + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
junos-host
+
+
+ names + +
+ list + / elements=string +
+
+ +
Name of single or multiple destination zone
+
+
+ url_category + +
+ dictionary +
+
+ +
URL category
+
+
+ any + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Apply to any url category
+
+
+ names + +
+ list + / elements=string +
+
+ +
Names of url category to match
+
+
+ none + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Do not apply to the url category
+
+
+ name + +
+ string +
+
+ +
Name of the policy
+
+
+ scheduler_name + +
+ string +
+
+ +
Name of the scheduler to run this policy
+
+
+ then + +
+ dictionary +
+
+ +
Specify the policy action to be performed when packets match the defined criteria
+
+
+ count + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable a count, in bytes or kilobytes, of all network traffic the policy allows to pass through the device in both directions; the originating traffic from the client to the server (from the from_zone to the to_zone), and the return traffic from the server to the originating client
+
+
+ deny + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Block the service at the firewall The device drops the packets
+
+
+ log + +
+ dictionary +
+
+ +
Log traffic information for a specific policy Traffic information is logged when a session begins (session_init) or closes (session_close)
+
+
+ session_close + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable logging on session close time
+
+
+ session_init + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable logging on session initialization time
+
+
+ permit + +
+ dictionary +
+
+ +
Block the service at the firewall The device drops the packets
+
+
+ application_services + +
+ dictionary +
+
+ +
Enable application services within a security policy
+
+
+ advanced_anti_malware_policy + +
+ string +
+
+ +
Specify advanced_anti_malware policy name
+
+
+ application_firewalls + +
+ list + / elements=dictionary +
+
+ +
Specify the rule sets configured as part of application firewall to be applied to the permitted traffic
+
+
+ rule_set + +
+ string +
+
+ +
name of rule set to use
+
+
+ application_traffic_control_rule_set + +
+ string +
+
+ +
Specify the rule set configured as part of AppQoS, application_aware quality of service, to be applied to the permitted traffic
+
+
+ gprs_gtp_profile + +
+ string +
+
+ +
Specify GPRS tunneling protocol profile name
+
+
+ gprs_sctp_profile + +
+ string +
+
+ +
Specify GPRS stream control protocol profile name
+
+
+ icap_redirect + +
+ string +
+
+ +
Specify icap redirect profile name
+
+
+ idp + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Intrusion Detection and Prevention (IDP)
+
+
+ idp_policy + +
+ string +
+
+ +
Specify IDP policy name
+
+
+ packet_capture + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Option to enable or disable packet capture
+
+
+ redirect_wx + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify the WX redirection needed for the packets that arrive from the LAN
+
+
+ reverse_redirect_wx + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify the WX redirection needed for the reverse flow of the packets that arrive from the WAN
+
+
+ security_intelligence + +
+ dictionary +
+
+ +
Specify the security intelligence feed post action
+
+
+ add_destination_identity_to_feed + +
+ string +
+
+ +
Add destination user identity to the security feed
+
+
+ add_destination_ip_to_feed + +
+ string +
+
+ +
Add the destination IP address to the security feed
+
+
+ add_source_identity_to_feed + +
+ string +
+
+ +
Add source user identity to the security feed
+
+
+ add_source_ip_to_feed + +
+ string +
+
+ +
Add the source IP address to the security feed
+
+
+ security_intelligence_policy + +
+ string +
+
+ +
Specify security_intelligence policy name
+
+
+ ssl_proxy + +
+ dictionary +
+
+ +
You can apply a redirect SSL proxy profile when a policy blocks HTTPS traffic with a reject action
+
+
+ enable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable SSL proxy
+
+
+ profile_name + +
+ string +
+
+ +
Name of SSL proxy profile
+
+
+ uac_policy + +
+ dictionary +
+
+ +
Enable Unified Access Control (UAC) for the security policy
+
+
+ captive_portal + +
+ string +
+
+ +
Specify the preconfigured security policy for captive portal on the Junos OS Enforcer to enable the captive portal feature
+
+
+ enable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable Unified Access Control (UAC)
+
+
+ utm_policy + +
+ string +
+
+ +
Specify UTM policy name
+
+
+ destination_address + +
+ string +
+
+
    Choices: +
  • drop-translated
  • +
  • drop-untranslated
  • +
+
+
Specify whether the traffic permitted by the security policy is limited to packets where the destination IP address has been translated by means of a destination NAT rule or to packets where the destination IP address has not been translated
+
+
+ firewall_authentication + +
+ dictionary +
+
+ +
Configure firewall authentication methods
+
+
+ pass_through + +
+ dictionary +
+
+ +
Configure pass-through firewall user authentication
+
+
+ access_profile + +
+ string +
+
+ +
Specify the name of the access profile
+
+
+ auth_only_browser + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Configure firewall authentication to ignore non-browser HTTP/HTTPS traffic
+
+
+ auth_user_agent + +
+ string +
+
+ +
Specify a user-agent value to be used to verify that the user's browser traffic is HTTP/HTTPS traffic
+
+
+ client_match + +
+ string +
+
+ +
Specify the name of the users or user groups in a profile who are allowed access by this policy
+
+
+ ssl_termination_profile + +
+ string +
+
+ +
Specify the SSL termination profile used for SSL offloading
+
+
+ web_redirect + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable redirecting an HTTP request to the device and redirecting the client system to a webpage for authentication
+
+
+ web_redirect_to_https + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Redirect unauthenticated HTTP requests to the internal HTTPS Web server of the device
+
+
+ push_to_identity_management + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
enables pushing to identity management devices
+
+
+ user_firewall + +
+ dictionary +
+
+ +
Configure user role firewall authentication, and map the source IP address to the username and its associated roles (groups)
+
+
+ access_profile + +
+ string +
+
+ +
Specify the name of the access profile to be used for authentication
+
+
+ auth_only_browser + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Configure firewall authentication to ignore non-browser HTTP/HTTPS traffic
+
+
+ auth_user_agent + +
+ string +
+
+ +
Specify a user-agent value to be used to verify that the user's browser traffic is HTTP/HTTPS traffic
+
+
+ domain + +
+ string +
+
+ +
Specify the name of the domain where firewall authentication occurs in the event that the Windows Management Instrumentation client (WMIC) is not available to get IP_to_user mapping for the integrated user firewall feature
+
+
+ ssl_termination_profile + +
+ string +
+
+ +
For HTTPS traffic, specify the name of the SSL termination profile used for SSL offloading
+
+
+ web_redirect + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable webpage redirection
+
+
+ web_redirect_to_https + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable redirection to HTTPS
+
+
+ web_authentication + +
+ list + / elements=string +
+
+ +
Specify that the policy allows access to users or user groups who have previously been authenticated by Web authentication
+
+
+ tcp_options + +
+ dictionary +
+
+ +
Specify the TCP options for each policy You can configure sync and sequence checks for each policy based on your requirements, and, because each policy has two directions, you can configure a TCP MSS value for both directions or for just one direction
+
+
+ initial_tcp_mss + +
+ integer +
+
+ +
Configure the TCP maximum segment size (MSS) for packets that arrive at the ingress interface (initial direction), match a specific policy, and for which a session is created
+
+
+ reverse_tcp_mss + +
+ integer +
+
+ +
Configure the TCP maximum segment size (MSS) for packets that match a specific policy and travel in the reverse direction of a session
+
+
+ sequence_check_required + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable sequence check per policy The sequence_check_required value overrides the global value no_sequence_check
+
+
+ syn_check_required + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable sync check per policy The syn_check_required value overrides the global value no_syn_check
+
+
+ window_scale + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable window_scale per policy
+
+
+ tunnel + +
+ dictionary +
+
+ +
Encapsulate outgoing IP packets and decapsulate incoming IP packets
+
+
+ ipsec_vpn + +
+ string +
+
+ +
name of the ipsec policy
+
+
+ pair_policy + +
+ string +
+
+ +
name of the pair policy
+
+
+ reject + +
+ dictionary +
+
+ +
Block the service at the firewall The device drops the packet and sends a TCP reset (RST) segment to the source host for TCP traffic and an ICMP "destination unreachable, port unreachable" message (type 3, code 3) for UDP traffic
+
+
+ enable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable rejection of packets based on match criteria
+
+
+ profile + +
+ string +
+
+ +
You can chose to provide a notification to the clients or redirect client request to an informative Web page when a policy blocks HTTP or HTTPS traffic with a deny or reject action
+
+
+ ssl_proxy + +
+ dictionary +
+
+ +
You can apply a redirect SSL proxy profile when a policy blocks HTTPS traffic with a reject action When you apply am SSL proxy profile, SSL proxy decrypts the traffic and application identification functionality identifies the application
+
+
+ enable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable SSL proxy
+
+
+ profile_name + +
+ string +
+
+ +
Name of SSL proxy profile
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed
+
The value of this option should be the output received from the JunOS device by executing the command show configuration security policies
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • rendered
  • +
  • gathered
  • +
  • parsed
  • +
+
+
The state the configuration should be left in
+
The states rendered, gathered and parsed does not perform any change on the device
+
The state rendered will transform the configuration in config option to platform specific CLI commands which will be returned in the rendered key within the result For state rendered active connection to remote host is not required
+
The state replaced will replace the running configuration with the provided configuration
+
The state replaced and state overridden have the same behaviour
+
The state 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 gathered key within the result
+
The state parsed reads the configuration from running_config option and transforms it into JSON format as per the resource module parameters and the value is returned in the parsed key within the result The value of running_config option should be the same format as the output of command show security policies detail executed on device For state parsed active connection to remote host is not required
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed + - This module works with connection ``netconf`` + - See `the Junos OS Platform Options `_ + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # vagrant@vsrx> show security policies + # Default policy: deny-all + # Pre ID default policy: permit-all + # Global policies: + # Policy: test_glob, State: enabled, Index: 4, Scope Policy: 0, Sequence number: 1 + # From zones: any + # To zones: any + # Source addresses: any-ipv4 + # Destination addresses: any-ipv4 + # Applications: any + # Action: deny + # + # vagrant@vsrx> show security zones + # + # Security zone: one + # Send reset for non-SYN session TCP packets: Off + # Policy configurable: Yes + # Interfaces bound: 1 + # Interfaces: + # ge-0/0/0.0 + # + # Security zone: three + # Send reset for non-SYN session TCP packets: Off + # Policy configurable: Yes + # Interfaces bound: 1 + # Interfaces: + # ge-0/0/2.0 + # + # Security zone: two + # Send reset for non-SYN session TCP packets: Off + # Policy configurable: Yes + # Interfaces bound: 1 + # Interfaces: + # ge-0/0/1.0 + # + # Security zone: junos-host + # Send reset for non-SYN session TCP packets: Off + # Policy configurable: Yes + # Interfaces bound: 0 + # Interfaces: + # + - junipernetworks.junos.junos_security_policies: + config: + from_zones: + - name: one + to_zones: + - name: two + policies: + - match: + application: + names: + - junos-dhcp-relay + - junos-finger + destination_address: + addresses: + - a2 + - a4 + destination_address_excluded: true + dynamic_application: + names: + - any + source_address: + addresses: + - a1 + - a3 + source_address_excluded: true + source_end_user_profile: test_end_user_profile + source_identity: + unknown_user: true + url_category: + names: + - Enhanced_Web_Chat + name: test_policy_1 + then: + count: true + deny: true + log: session-close + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + addresses: + - a1 + name: test_policy_2 + then: + reject: + enable: true + profile: test_dyn_app + ssl_proxy: + enable: true + profile_name: SECURITY-SSL-PROXY + - name: three + policies: + - match: + application: + any: true + destination_address: + addresses: + - a2 + source_address: + addresses: + - a1 + name: test_policy_3 + then: + permit: + application_services: + application_traffic_control_rule_set: test_traffic_control + gprs_gtp_profile: gtp1 + icap_redirect: test_icap + reverse_redirect_wx: 'True' + uac_policy: + enable: true + firewall_authentication: + push_to_identity_management: true + web_authentication: + - FWClient1 + tcp_options: + initial_tcp_mss: 64 + window_scale: true + global: + policies: + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any_ipv6: true + name: test_glob_1 + then: + deny: true + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any_ipv6: true + name: test_glob_2 + then: + deny: true + state: merged + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "from_zones": [ + # { + # "name": "one", + # "to_zones": [ + # { + # "name": "two", + # "policies": [ + # { + # "match": { + # "application": { + # "names": [ + # "junos-dhcp-relay", + # "junos-finger" + # ] + # }, + # "destination_address": { + # "addresses": [ + # "a2", + # "a4" + # ] + # }, + # "destination_address_excluded": true, + # "dynamic_application": { + # "names": [ + # "any" + # ] + # }, + # "source_address": { + # "addresses": [ + # "a1", + # "a3" + # ] + # }, + # "source_address_excluded": true, + # "source_end_user_profile": "test_end_user_profile", + # "source_identity": { + # "unknown_user": true + # }, + # "url_category": { + # "names": [ + # "Enhanced_Web_Chat" + # ] + # } + # }, + # "name": "test_policy_1", + # "then": { + # "count": true, + # "deny": true, + # "log": "session-close" + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "addresses": [ + # "a1" + # ] + # } + # }, + # "name": "test_policy_2", + # "then": { + # "reject": { + # "enable": true, + # "profile": "test_dyn_app", + # "ssl_proxy": { + # "enable": true, + # "profile_name": "SECURITY-SSL-PROXY" + # } + # } + # } + # } + # ] + # }, + # { + # "name": "three", + # "policies": [ + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "addresses": [ + # "a2" + # ] + # }, + # "source_address": { + # "addresses": [ + # "a1" + # ] + # } + # }, + # "name": "test_policy_3", + # "then": { + # "permit": { + # "application_services": { + # "application_traffic_control_rule_set": "test_traffic_control", + # "gprs_gtp_profile": "gtp1", + # "icap_redirect": "test_icap", + # "reverse_redirect_wx": "True", + # "uac_policy": { + # "enable": true + # } + # }, + # "firewall_authentication": { + # "push_to_identity_management": true, + # "web_authentication": [ + # "FWClient1" + # ] + # }, + # "tcp_options": { + # "initial_tcp_mss": 64, + # "window_scale": true + # } + # } + # } + # } + # ] + # } + # ] + # } + # ], + # "global": { + # "policies": [ + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv4": true + # }, + # "source_address": { + # "any_ipv4": true + # } + # }, + # "name": "test_glob", + # "then": { + # "deny": true + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any_ipv6": true + # } + # }, + # "name": "test_glob_1", + # "then": { + # "deny": true + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any_ipv6": true + # } + # }, + # "name": "test_glob_2", + # "then": { + # "deny": true + # } + # } + # ] + # } + # }, + # "before": { + # "global": { + # "policies": [ + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv4": true + # }, + # "source_address": { + # "any_ipv4": true + # } + # }, + # "name": "test_glob", + # "then": { + # "deny": true + # } + # } + # ] + # } + # }, + # "changed": true, + # "commands": " + # + # + # one + # two + # + # test_policy_1 + # + # a1 + # a3 + # + # a2 + # a4 + # + # junos-dhcp-relay + # junos-finger + # test_end_user_profile + # unknown-user + # Enhanced_Web_Chat + # any + # + # + # + # + # + # + # + # + # + # + # test_policy_2 + # + # a1 + # any-ipv6 + # any + # + # + # + # test_dyn_app + # + # SECURITY-SSL-PROXY + # + # + # + # + # + # + # one + # three + # + # test_policy_3 + # + # a1 + # a2 + # any + # + # + # + # + # + # test_traffic_control + # + # gtp1 + # test_icap + # + # + # + # + # + # + # FWClient1 + # + # + # + # 64 + # + # + # + # + # + # + # + # + # test_glob_1 + # + # any-ipv6 + # any-ipv6 + # any + # + # + # + # + # + # + # test_glob_2 + # + # any-ipv6 + # any-ipv6 + # any + # + # + # + # + # + # + # + # + # " + # After state + # ----------- + # + # vagrant@vsrx> show security policies + # Default policy: deny-all + # Pre ID default policy: permit-all + # From zone: one, To zone: two + # Policy: test_policy_1, State: enabled, Index: 5, Scope Policy: 0, Sequence number: 1 + # Source addresses(excluded): a1, a3 + # Destination addresses(excluded): a2, a4 + # Source-end-user-profile: test_end_user_profile(1) + # Applications: junos-dhcp-relay, junos-finger + # Dynamic Applications: any + # Url-category: Enhanced_Web_Chat + # Source identities: unknown-user + # Action: deny, log, count + # Policy: test_policy_2, State: enabled, Index: 6, Scope Policy: 0, Sequence number: 2 + # Source addresses: a1 + # Destination addresses: any-ipv6 + # Applications: any + # Action: reject + # dynapp-redir-profile: test_dyn_app(1) + # From zone: one, To zone: three + # Policy: test_policy_3, State: enabled, Index: 7, Scope Policy: 0, Sequence number: 1 + # Source addresses: a1 + # Destination addresses: a2 + # Applications: any + # Action: permit, firewall authentication, application services, unified access control + # Application traffic control: test_traffic_control + # Global policies: + # Policy: test_glob, State: enabled, Index: 4, Scope Policy: 0, Sequence number: 1 + # From zones: any + # To zones: any + # Source addresses: any-ipv4 + # Destination addresses: any-ipv4 + # Applications: any + # Action: deny + # Policy: test_glob_1, State: enabled, Index: 8, Scope Policy: 0, Sequence number: 2 + # From zones: any + # To zones: any + # Source addresses: any-ipv6 + # Destination addresses: any-ipv6 + # Applications: any + # Action: deny + # Policy: test_glob_2, State: enabled, Index: 9, Scope Policy: 0, Sequence number: 3 + # From zones: any + # To zones: any + # Source addresses: any-ipv6 + # Destination addresses: any-ipv6 + # Applications: any + # Action: deny + + + # Using Replaced + # Before state + # ------------ + # + # vagrant@vsrx> show security policies + # Default policy: deny-all + # Pre ID default policy: permit-all + # From zone: one, To zone: two + # Policy: test_policy_1, State: enabled, Index: 5, Scope Policy: 0, Sequence number: 1 + # Source addresses(excluded): a1, a3 + # Destination addresses(excluded): a2, a4 + # Source-end-user-profile: test_end_user_profile(1) + # Applications: junos-dhcp-relay, junos-finger + # Dynamic Applications: any + # Url-category: Enhanced_Web_Chat + # Source identities: unknown-user + # Action: deny, log, count + # Policy: test_policy_2, State: enabled, Index: 6, Scope Policy: 0, Sequence number: 2 + # Source addresses: a1 + # Destination addresses: any-ipv6 + # Applications: any + # Action: reject + # dynapp-redir-profile: test_dyn_app(1) + # From zone: one, To zone: three + # Policy: test_policy_3, State: enabled, Index: 7, Scope Policy: 0, Sequence number: 1 + # Source addresses: a1 + # Destination addresses: a2 + # Applications: any + # Action: permit, firewall authentication, application services, unified access control + # Application traffic control: test_traffic_control + # Global policies: + # Policy: test_glob, State: enabled, Index: 4, Scope Policy: 0, Sequence number: 1 + # From zones: any + # To zones: any + # Source addresses: any-ipv4 + # Destination addresses: any-ipv4 + # Applications: any + # Action: deny + # Policy: test_glob_1, State: enabled, Index: 8, Scope Policy: 0, Sequence number: 2 + # From zones: any + # To zones: any + # Source addresses: any-ipv6 + # Destination addresses: any-ipv6 + # Applications: any + # Action: deny + # Policy: test_glob_2, State: enabled, Index: 9, Scope Policy: 0, Sequence number: 3 + # From zones: any + # To zones: any + # Source addresses: any-ipv6 + # Destination addresses: any-ipv6 + # Applications: any + # Action: deny + # + - junipernetworks.junos.junos_security_policies: + config: + global: + policies: + - description: test update + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any: true + name: test_glob_3 + then: + deny: true + state: replaced + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "global": { + # "policies": [ + # { + # "description": "test update", + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any": true + # } + # }, + # "name": "test_glob_3", + # "then": { + # "deny": true + # } + # } + # ] + # } + # }, + # "before": { + # "from_zones": [ + # { + # "name": "one", + # "to_zones": [ + # { + # "name": "two", + # "policies": [ + # { + # "match": { + # "application": { + # "names": [ + # "junos-dhcp-relay", + # "junos-finger" + # ] + # }, + # "destination_address": { + # "addresses": [ + # "a2", + # "a4" + # ] + # }, + # "destination_address_excluded": true, + # "dynamic_application": { + # "names": [ + # "any" + # ] + # }, + # "source_address": { + # "addresses": [ + # "a1", + # "a3" + # ] + # }, + # "source_address_excluded": true, + # "source_end_user_profile": "test_end_user_profile", + # "source_identity": { + # "unknown_user": true + # }, + # "url_category": { + # "names": [ + # "Enhanced_Web_Chat" + # ] + # } + # }, + # "name": "test_policy_1", + # "then": { + # "count": true, + # "deny": true, + # "log": "session-close" + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "addresses": [ + # "a1" + # ] + # } + # }, + # "name": "test_policy_2", + # "then": { + # "reject": { + # "enable": true, + # "profile": "test_dyn_app", + # "ssl_proxy": { + # "enable": true, + # "profile_name": "SECURITY-SSL-PROXY" + # } + # } + # } + # } + # ] + # }, + # { + # "name": "three", + # "policies": [ + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "addresses": [ + # "a2" + # ] + # }, + # "source_address": { + # "addresses": [ + # "a1" + # ] + # } + # }, + # "name": "test_policy_3", + # "then": { + # "permit": { + # "application_services": { + # "application_traffic_control_rule_set": "test_traffic_control", + # "gprs_gtp_profile": "gtp1", + # "icap_redirect": "test_icap", + # "reverse_redirect_wx": "True", + # "uac_policy": { + # "enable": true + # } + # }, + # "firewall_authentication": { + # "push_to_identity_management": true, + # "web_authentication": [ + # "FWClient1" + # ] + # }, + # "tcp_options": { + # "initial_tcp_mss": 64, + # "window_scale": true + # } + # } + # } + # } + # ] + # } + # ] + # } + # ], + # "global": { + # "policies": [ + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv4": true + # }, + # "source_address": { + # "any_ipv4": true + # } + # }, + # "name": "test_glob", + # "then": { + # "deny": true + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any_ipv6": true + # } + # }, + # "name": "test_glob_1", + # "then": { + # "deny": true + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any_ipv6": true + # } + # }, + # "name": "test_glob_2", + # "then": { + # "deny": true + # } + # } + # ] + # } + # }, + # "changed": true, + # "commands": " + # + # + # + # + # test_glob_3 + # test update + # + # any + # any-ipv6 + # any + # + # + # + # + # + # + # + # " + # } + # After state + # ----------- + # + # vagrant@vsrx> show security policies + # Default policy: deny-all + # Pre ID default policy: permit-all + # Global policies: + # Policy: test_glob_3, State: enabled, Index: 10, Scope Policy: 0, Sequence number: 1 + # From zones: any + # To zones: any + # Source addresses: any + # Destination addresses: any-ipv6 + # Applications: any + # Action: deny + + + # Using overridden + # + # Before state + # ------------ + # + # vagrant@vsrx> show security policies + # Default policy: deny-all + # Pre ID default policy: permit-all + # From zone: one, To zone: two + # Policy: test_policy_1, State: enabled, Index: 5, Scope Policy: 0, Sequence number: 1 + # Source addresses(excluded): a1, a3 + # Destination addresses(excluded): a2, a4 + # Source-end-user-profile: test_end_user_profile(1) + # Applications: junos-dhcp-relay, junos-finger + # Dynamic Applications: any + # Url-category: Enhanced_Web_Chat + # Source identities: unknown-user + # Action: deny, log, count + # Policy: test_policy_2, State: enabled, Index: 6, Scope Policy: 0, Sequence number: 2 + # Source addresses: a1 + # Destination addresses: any-ipv6 + # Applications: any + # Action: reject + # dynapp-redir-profile: test_dyn_app(1) + # From zone: one, To zone: three + # Policy: test_policy_3, State: enabled, Index: 7, Scope Policy: 0, Sequence number: 1 + # Source addresses: a1 + # Destination addresses: a2 + # Applications: any + # Action: permit, firewall authentication, application services, unified access control + # Application traffic control: test_traffic_control + # Global policies: + # Policy: test_glob, State: enabled, Index: 4, Scope Policy: 0, Sequence number: 1 + # From zones: any + # To zones: any + # Source addresses: any-ipv4 + # Destination addresses: any-ipv4 + # Applications: any + # Action: deny + # Policy: test_glob_1, State: enabled, Index: 8, Scope Policy: 0, Sequence number: 2 + # From zones: any + # To zones: any + # Source addresses: any-ipv6 + # Destination addresses: any-ipv6 + # Applications: any + # Action: deny + # Policy: test_glob_2, State: enabled, Index: 9, Scope Policy: 0, Sequence number: 3 + # From zones: any + # To zones: any + # Source addresses: any-ipv6 + # Destination addresses: any-ipv6 + # Applications: any + # Action: deny + # + - junipernetworks.junos.junos_security_policies: + config: + global: + policies: + - description: test update + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any: true + name: test_glob_3 + then: + deny: true + state: overridden + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "global": { + # "policies": [ + # { + # "description": "test update", + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any": true + # } + # }, + # "name": "test_glob_3", + # "then": { + # "deny": true + # } + # } + # ] + # } + # }, + # "before": { + # "from_zones": [ + # { + # "name": "one", + # "to_zones": [ + # { + # "name": "two", + # "policies": [ + # { + # "match": { + # "application": { + # "names": [ + # "junos-dhcp-relay", + # "junos-finger" + # ] + # }, + # "destination_address": { + # "addresses": [ + # "a2", + # "a4" + # ] + # }, + # "destination_address_excluded": true, + # "dynamic_application": { + # "names": [ + # "any" + # ] + # }, + # "source_address": { + # "addresses": [ + # "a1", + # "a3" + # ] + # }, + # "source_address_excluded": true, + # "source_end_user_profile": "test_end_user_profile", + # "source_identity": { + # "unknown_user": true + # }, + # "url_category": { + # "names": [ + # "Enhanced_Web_Chat" + # ] + # } + # }, + # "name": "test_policy_1", + # "then": { + # "count": true, + # "deny": true, + # "log": "session-close" + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "addresses": [ + # "a1" + # ] + # } + # }, + # "name": "test_policy_2", + # "then": { + # "reject": { + # "enable": true, + # "profile": "test_dyn_app", + # "ssl_proxy": { + # "enable": true, + # "profile_name": "SECURITY-SSL-PROXY" + # } + # } + # } + # } + # ] + # }, + # { + # "name": "three", + # "policies": [ + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "addresses": [ + # "a2" + # ] + # }, + # "source_address": { + # "addresses": [ + # "a1" + # ] + # } + # }, + # "name": "test_policy_3", + # "then": { + # "permit": { + # "application_services": { + # "application_traffic_control_rule_set": "test_traffic_control", + # "gprs_gtp_profile": "gtp1", + # "icap_redirect": "test_icap", + # "reverse_redirect_wx": "True", + # "uac_policy": { + # "enable": true + # } + # }, + # "firewall_authentication": { + # "push_to_identity_management": true, + # "web_authentication": [ + # "FWClient1" + # ] + # }, + # "tcp_options": { + # "initial_tcp_mss": 64, + # "window_scale": true + # } + # } + # } + # } + # ] + # } + # ] + # } + # ], + # "global": { + # "policies": [ + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv4": true + # }, + # "source_address": { + # "any_ipv4": true + # } + # }, + # "name": "test_glob", + # "then": { + # "deny": true + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any_ipv6": true + # } + # }, + # "name": "test_glob_1", + # "then": { + # "deny": true + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any_ipv6": true + # } + # }, + # "name": "test_glob_2", + # "then": { + # "deny": true + # } + # } + # ] + # } + # }, + # "changed": true, + # "commands": " + # + # + # + # + # test_glob_3 + # test update + # + # any + # any-ipv6 + # any + # + # + # + # + # + # + # + # " + # } + # After state + # ----------- + # + # vagrant@vsrx> show security policies + # Default policy: deny-all + # Pre ID default policy: permit-all + # Global policies: + # Policy: test_glob_3, State: enabled, Index: 10, Scope Policy: 0, Sequence number: 1 + # From zones: any + # To zones: any + # Source addresses: any + # Destination addresses: any-ipv6 + # Applications: any + # Action: deny + + + # Using deleted + # + # Before state + # ------------ + # + # vagrant@vsrx> show security policies + # Default policy: deny-all + # Pre ID default policy: permit-all + # Global policies: + # Policy: test_glob_3, State: enabled, Index: 10, Scope Policy: 0, Sequence number: 1 + # From zones: any + # To zones: any + # Source addresses: any + # Destination addresses: any-ipv6 + # Applications: any + # Action: deny + # + - junipernetworks.junos.junos_security_policies: + config: + state: deleted + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # "after": {}, + # "before": { + # "global": { + # "policies": [ + # { + # "description": "test update", + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any": true + # } + # }, + # "name": "test_glob_3", + # "then": { + # "deny": true + # } + # } + # ] + # } + # }, + # "changed": true, + # "commands": " + # " + # + # After state + # ----------- + # + # vagrant@vsrx> show security policies + # Default policy: deny-all + # Pre ID default policy: permit-all + + + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S3.1 + # + # + # + # + # test_ssl_term + # SECURITY-cert + # + # + # + # + # SECURITY-SSL-PROXY + # SECURITY-cert + # + # + # + # + # + # test_icap + # + # test_icap_server + # 10.10.10.11 + # + # + # + # + # + # + # + # test_end_user_profile + # test_domain + # + # device-identity + # Windows + # + # + # + # + # + # + # + # + # global + #
+ # a1 + # 200.0.113.0/24 + #
+ #
+ # a2 + # 201.0.113.0/24 + #
+ #
+ # a3 + # 202.0.113.0/24 + #
+ #
+ # a4 + # 203.0.113.0/24 + #
+ #
+ # + # + # test_dyn_app + # + # + # + # hello_world + # + # + # + # + # + # + # + # one + # two + # + # test_policy_1 + # + # a1 + # a3 + # a2 + # a4 + # + # + # junos-dhcp-relay + # junos-finger + # authenticated-user + # unknown-user + # + # test_end_user_profile + # + # any + # Enhanced_Web_Chat + # + # + # + # + # + # + # + # + # + # + # test_policy_2 + # + # a1 + # any-ipv6 + # any + # + # + # + # test_dyn_app + # + # SECURITY-SSL-PROXY + # + # + # + # + # + # + # one + # three + # + # test_policy_3 + # + # a1 + # a2 + # any + # + # + # + # + # + # FWClient1 + # + # + # + # + # + # + # + # gtp1 + # + # test_icap + # + # test_traffic_control + # + # + # + # + # 64 + # + # + # + # + # + # + # + # + # test_glob_1 + # + # any-ipv6 + # any-ipv6 + # any + # + # + # + # + # + # + # test_glob_2 + # + # any-ipv6 + # any-ipv6 + # any + # + # + # + # + # + # + # + # + # + # one + # + # ge-0/0/0.0 + # + # + # + # two + # + # ge-0/0/1.0 + # + # + # + # three + # + # ge-0/0/2.0 + # + # + # + # + # + # + # gtp1 + # + # + # + #
+ # + # + # ge-0/0/0 + # + # 0 + # + # + #
+ # 200.0.113.1/24 + #
+ #
+ #
+ #
+ #
+ # + # ge-0/0/1 + # + # 0 + # + # + #
+ # 201.0.113.1/24 + #
+ #
+ #
+ #
+ #
+ # + # ge-0/0/2 + # + # 0 + # + # + #
+ # 202.0.113.1/24 + #
+ #
+ #
+ #
+ #
+ # + # fxp0 + # + # 0 + # + # + # + # + # + # + # + #
+ # + # + # + # test_traffic_control + # + # test_rule + # + # + # + # + # + # + # + # + # + # + # + # + # WEBAUTH + # + # FWClient1 + # + # $9$kq5Ftu1cSe + # + # + # + # + # + # WEBAUTH + # + # + # + #
+ # + #
+ # + - name: Parse NTP global running config + junipernetworks.junos.junos_security_policies: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # "parsed": { + # "from_zones": [ + # { + # "name": "one", + # "to_zones": [ + # { + # "name": "two", + # "policies": [ + # { + # "match": { + # "application": { + # "names": [ + # "junos-dhcp-relay", + # "junos-finger" + # ] + # }, + # "destination_address": { + # "addresses": [ + # "a2", + # "a4" + # ] + # }, + # "destination_address_excluded": true, + # "dynamic_application": { + # "names": [ + # "any" + # ] + # }, + # "source_address": { + # "addresses": [ + # "a1", + # "a3" + # ] + # }, + # "source_address_excluded": true, + # "source_end_user_profile": "test_end_user_profile", + # "source_identity": { + # "unknown_user": true + # }, + # "url_category": { + # "names": [ + # "Enhanced_Web_Chat" + # ] + # } + # }, + # "name": "test_policy_1", + # "then": { + # "count": true, + # "deny": true, + # "log": "session-close" + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "addresses": [ + # "a1" + # ] + # } + # }, + # "name": "test_policy_2", + # "then": { + # "reject": { + # "enable": true, + # "profile": "test_dyn_app", + # "ssl_proxy": { + # "enable": true, + # "profile_name": "SECURITY-SSL-PROXY" + # } + # } + # } + # } + # ] + # }, + # { + # "name": "three", + # "policies": [ + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "addresses": [ + # "a2" + # ] + # }, + # "source_address": { + # "addresses": [ + # "a1" + # ] + # } + # }, + # "name": "test_policy_3", + # "then": { + # "permit": { + # "application_services": { + # "application_traffic_control_rule_set": "test_traffic_control", + # "gprs_gtp_profile": "gtp1", + # "icap_redirect": "test_icap", + # "reverse_redirect_wx": "True", + # "uac_policy": { + # "enable": true + # } + # }, + # "firewall_authentication": { + # "push_to_identity_management": true, + # "web_authentication": [ + # "FWClient1" + # ] + # }, + # "tcp_options": { + # "initial_tcp_mss": 64, + # "window_scale": true + # } + # } + # } + # } + # ] + # } + # ] + # } + # ], + # "global": { + # "policies": [ + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any_ipv6": true + # } + # }, + # "name": "test_glob_1", + # "then": { + # "deny": true + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any_ipv6": true + # } + # }, + # "name": "test_glob_2", + # "then": { + # "deny": true + # } + # } + # ] + # } + # } + + + # Using gathered + # + # Before state + # ------------ + # + # vagrant@vsrx> show security policies + # Default policy: deny-all + # Pre ID default policy: permit-all + # From zone: one, To zone: two + # Policy: test_policy_1, State: enabled, Index: 4, Scope Policy: 0, Sequence number: 1 + # Source addresses(excluded): a1, a3 + # Destination addresses(excluded): a2, a4 + # Source-end-user-profile: test_end_user_profile(1) + # Applications: junos-dhcp-relay, junos-finger + # Dynamic Applications: any + # Url-category: Enhanced_Web_Chat + # Source identities: authenticated-user, unknown-user + # Action: deny, log, count + # Policy: test_policy_2, State: enabled, Index: 5, Scope Policy: 0, Sequence number: 2 + # Source addresses: a1 + # Destination addresses: any-ipv6 + # Applications: any + # Action: reject + # dynapp-redir-profile: test_dyn_app(1) + # From zone: one, To zone: three + # Policy: test_policy_3, State: enabled, Index: 6, Scope Policy: 0, Sequence number: 1 + # Source addresses: a1 + # Destination addresses: a2 + # Applications: any + # Action: permit, drop-untranslated, firewall authentication, application services, unified access control + # Application traffic control: test_traffic_control + # Global policies: + # Policy: test_glob_1, State: enabled, Index: 7, Scope Policy: 0, Sequence number: 1 + # From zones: any + # To zones: any + # Source addresses: any-ipv6 + # Destination addresses: any-ipv6 + # Applications: any + # Action: deny + # Policy: test_glob_2, State: enabled, Index: 8, Scope Policy: 0, Sequence number: 2 + # From zones: any + # To zones: any + # Source addresses: any-ipv6 + # Destination addresses: any-ipv6 + # Applications: any + # Action: deny + # + - junipernetworks.junos.junos_security_policies: + state: gathered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # "changed": false, + # "gathered": { + # "from_zones": [ + # { + # "name": "one", + # "to_zones": [ + # { + # "name": "two", + # "policies": [ + # { + # "match": { + # "application": { + # "names": [ + # "junos-dhcp-relay", + # "junos-finger" + # ] + # }, + # "destination_address": { + # "addresses": [ + # "a2", + # "a4" + # ] + # }, + # "destination_address_excluded": true, + # "dynamic_application": { + # "names": [ + # "any" + # ] + # }, + # "source_address": { + # "addresses": [ + # "a1", + # "a3" + # ] + # }, + # "source_address_excluded": true, + # "source_end_user_profile": "test_end_user_profile", + # "source_identity": { + # "unknown_user": true + # }, + # "url_category": { + # "names": [ + # "Enhanced_Web_Chat" + # ] + # } + # }, + # "name": "test_policy_1", + # "then": { + # "count": true, + # "deny": true, + # "log": "session-close" + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "addresses": [ + # "a1" + # ] + # } + # }, + # "name": "test_policy_2", + # "then": { + # "reject": { + # "enable": true, + # "profile": "test_dyn_app", + # "ssl_proxy": { + # "enable": true, + # "profile_name": "SECURITY-SSL-PROXY" + # } + # } + # } + # } + # ] + # }, + # { + # "name": "three", + # "policies": [ + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "addresses": [ + # "a2" + # ] + # }, + # "source_address": { + # "addresses": [ + # "a1" + # ] + # } + # }, + # "name": "test_policy_3", + # "then": { + # "permit": { + # "application_services": { + # "application_traffic_control_rule_set": "test_traffic_control", + # "gprs_gtp_profile": "gtp1", + # "icap_redirect": "test_icap", + # "reverse_redirect_wx": "True", + # "uac_policy": { + # "enable": true + # } + # }, + # "firewall_authentication": { + # "push_to_identity_management": true, + # "web_authentication": [ + # "FWClient1" + # ] + # }, + # "tcp_options": { + # "initial_tcp_mss": 64, + # "window_scale": true + # } + # } + # } + # } + # ] + # } + # ] + # } + # ], + # "global": { + # "policies": [ + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any_ipv6": true + # } + # }, + # "name": "test_glob_1", + # "then": { + # "deny": true + # } + # }, + # { + # "match": { + # "application": { + # "any": true + # }, + # "destination_address": { + # "any_ipv6": true + # }, + # "source_address": { + # "any_ipv6": true + # } + # }, + # "name": "test_glob_2", + # "then": { + # "deny": true + # } + # } + # ] + # } + # } + # } + + + # Using rendered + # + # Before state + # ------------ + # + - junipernetworks.junos.junos_security_policies: + config: + global: + policies: + - description: test update + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any: true + name: test_glob_3 + then: + deny: true + state: rendered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "rendered": " + # + # + # + # test_glob_3 + # test update + # + # any + # any-ipv6 + # any + # + # + # + # + # + # + # + # " + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration after module execution.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ before + +
+ dictionary +
+
when state is merged, replaced, overridden or deleted +
The configuration prior to the module execution.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ commands + +
+ list +
+
when state is merged, replaced, overridden or deleted +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<rpc-reply> <configuration> <security> <policies> <global> <policy> <name>test_glob_1</name> <match> <source-address>any-ipv6</source-address> <destination-address>any-ipv6</destination-address> <application>any</application> </match> <then> <deny /> </then> </policy> </global> </policies> </security> </configuration> </rpc-reply>']
+
+
+ gathered + +
+ dictionary +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ dictionary +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ dictionary +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['<rpc-reply> <configuration> <security> <policies> <global> <policy> <name>test_glob_1</name> <match> <source-address>any-ipv6</source-address> <destination-address>any-ipv6</destination-address> <application>any</application> </match> <then> <deny /> </then> </policy> </global> </policies> </security> </configuration> </rpc-reply>']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Pranav Bhatt (@pranav-bhatt) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_security_zones_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_security_zones_module.rst new file mode 100644 index 00000000..cf06a1f4 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_security_zones_module.rst @@ -0,0 +1,2842 @@ +.. _junipernetworks.junos.junos_security_zones_module: + + +****************************************** +junipernetworks.junos.junos_security_zones +****************************************** + +**Manage security zones on Juniper JUNOS devices** + + +Version added: 2.9.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module provides declarative management of security zones on Juniper JUNOS devices + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
Dictionary of security zone parameters
+
+
+ functional_zone_management + +
+ dictionary +
+
+ +
Functional zone to configure host for out of band management interfaces
+
+
+ description + +
+ string +
+
+ +
Text description of zone
+
+
+ host_inbound_traffic + +
+ dictionary +
+
+ +
Allowed system services & protocols
+
+
+ protocols + +
+ list + / elements=dictionary +
+
+ +
Protocol type of incoming traffic to accept
+
+
+ except + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disallow the specified protocol traffic
+
+
+ name + +
+ string +
+
+ +
Type of incoming protocol to accept
+
+
+ system_services + +
+ list + / elements=dictionary +
+
+ +
Type of incoming system-service traffic to accept
+
+
+ except + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disallow the specified incoming system-service traffic
+
+
+ name + +
+ string +
+
+ +
Type of incoming system-service traffic to accept
+
+
+ interfaces + +
+ list + / elements=string +
+
+ +
Interfaces that are part of this zone
+
+
+ screen + +
+ string +
+
+ +
Name of ids option object applied to the zone
+
+
+ zones + +
+ list + / elements=dictionary +
+
+ +
Security zones
+
+
+ address_book + +
+ dictionary +
+
+ +
Address book entries
+
+
+ address_sets + +
+ list + / elements=dictionary +
+
+ +
Define security address sets
+
+
+ address_sets + +
+ list + / elements=string +
+
+ +
Define an address-set name
+
+
+ addresses + +
+ list + / elements=string +
+
+ +
Addresses to be included in this set
+
+
+ description + +
+ string +
+
+ +
Text description of address set
+
+
+ name + +
+ string +
+
+ +
Name of address set
+
+
+ addresses + +
+ list + / elements=dictionary +
+
+ +
Define security addresses
+
+
+ description + +
+ string +
+
+ +
Text description of address
+
+
+ dns_name + +
+ dictionary +
+
+ +
DNS address name
+
+
+ ipv4_only + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
IPv4 dns address
+
+
+ ipv6_only + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
IPv6 dns address
+
+
+ name + +
+ string +
+
+ +
Fully qualified hostname
+
+
+ ip_prefix + +
+ string +
+
+ +
Numeric IPv4 or IPv6 address with prefix
+
+
+ name + +
+ string +
+
+ +
Name of address
+
+
+ range_address + +
+ dictionary +
+
+ +
Address range
+
+
+ from + +
+ string +
+
+ +
Start of address range
+
+
+ to + +
+ string +
+
+ +
End of address range
+
+
+ wildcard_address + +
+ string +
+
+ +
Numeric IPv4 wildcard address with in the form of a.d.d.r/netmask
+
+
+ advance_policy_based_routing_profile + +
+ string +
+
+ +
Enable Advance Policy Based Routing on this zone
+
+
+ advanced_connection_tracking + +
+ dictionary +
+
+ +
Enable Advance Policy Based Routing on this zone
+
+
+ mode + +
+ string +
+
+
    Choices: +
  • allow-any-host
  • +
  • allow-target-host
  • +
  • allow-target-host-port
  • +
+
+
Set connection tracking mode
+
+
+ timeout + +
+ integer +
+
+ +
Timeout value in seconds for advanced-connection-tracking table for this zone
+
+
+ track_all_policies_to_this_zone + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Mandate all policies with to-zone set to this zone to do connection track table lookup
+
+
+ application_tracking + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable Application tracking support for this zone
+
+
+ description + +
+ string +
+
+ +
Text description of zone
+
+
+ enable_reverse_reroute + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable Reverse route lookup when there is change in ingress interface
+
+
+ host_inbound_traffic + +
+ dictionary +
+
+ +
Allowed system services & protocols
+
+
+ protocols + +
+ list + / elements=dictionary +
+
+ +
Protocol type of incoming traffic to accept
+
+
+ except + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disallow the specified protocol traffic
+
+
+ name + +
+ string +
+
+ +
Type of incoming protocol to accept
+
+
+ system_services + +
+ list + / elements=dictionary +
+
+ +
Type of incoming system-service traffic to accept
+
+
+ except + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disallow the specified incoming system-service traffic
+
+
+ name + +
+ string +
+
+ +
Type of incoming system-service traffic to accept
+
+
+ interfaces + +
+ list + / elements=string +
+
+ +
Interfaces that are part of this zone
+
+
+ name + +
+ string +
+
+ +
Name of the security zone
+
+
+ screen + +
+ string +
+
+ +
Name of ids option object applied to the zone
+
+
+ source_identity_log + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Show user and group info in session log for this zone
+
+
+ tcp_rst + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Send RST for NON-SYN packet not matching TCP session
+
+
+ unidirectional_session_refreshing + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable unidirectional session refreshing on this zone
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the JunOS device by executing the command show security policies.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • rendered
  • +
  • gathered
  • +
  • parsed
  • +
+
+
The state the configuration should be left in
+
The states rendered, gathered and parsed does not perform any change on the device.
+
The state rendered will transform the configuration in config option to platform specific CLI commands which will be returned in the rendered key within the result. For state rendered active connection to remote host is not required. behaviour for this module.
+
The state 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 gathered key within the result.
+
The state parsed reads the configuration from running_config option and transforms it into JSON format as per the resource module parameters and the value is returned in the parsed key within the result. The value of running_config option should be the same format as the output of command show security policies detail executed on device. For state parsed active connection to remote host is not required.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. + - See `the Junos OS Platform Options `_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # vagrant@vsrx# show security zones + # + # [edit] + # vagrant@vsrx# show security zones + # + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_security_zones: &merged + config: + functional_zone_management: + description: test description + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + security_zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true + state: merged + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "functional_zone_management": { + # "description": "test description", + # "host_inbound_traffic": { + # "protocols": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "bgp" + # } + # ], + # "system_services": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "dhcp" + # } + # ] + # }, + # "interfaces": [ + # "ge-0/0/1.0", + # "ge-0/0/2.0" + # ], + # "screen": "test_screen" + # }, + # "security_zones": [ + # { + # "address_book": { + # "address_sets": [ + # { + # "addresses": [ + # "test_adr1", + # "test_adr2" + # ], + # "name": "test_adrset1" + # }, + # { + # "addresses": [ + # "test_adr3", + # "test_adr4" + # ], + # "name": "test_adrset2" + # }, + # { + # "address_sets": [ + # "test_adrset1", + # "test_adrset2" + # ], + # "addresses": [ + # "test_adr5" + # ], + # "description": "test description", + # "name": "test_adrset3" + # } + # ], + # "addresses": [ + # { + # "description": "test desc", + # "ip_prefix": "10.0.0.0/24", + # "name": "test_adr1" + # }, + # { + # "dns_name": { + # "ipv6_only": true, + # "name": "1.1.1.1" + # }, + # "name": "test_adr2" + # }, + # { + # "name": "test_adr3", + # "range_address": { + # "from": "10.2.0.1", + # "to": "10.2.0.2" + # } + # }, + # { + # "name": "test_adr4", + # "wildcard_address": "10.3.0.1/24" + # }, + # { + # "description": "test desc", + # "ip_prefix": "10.1.0.0/24", + # "name": "test_adr5" + # } + # ] + # }, + # "advance_policy_based_routing_profile": "test_profile", + # "application_tracking": true, + # "description": "test description", + # "enable_reverse_reroute": true, + # "host_inbound_traffic": { + # "protocols": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "bgp" + # } + # ], + # "system_services": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "dhcp" + # } + # ] + # }, + # "interfaces": [ + # "ge-0/0/3.0", + # "ge-0/0/4.0" + # ], + # "name": "test_sec_zone1", + # "screen": "test_screen", + # "source_identity_log": true, + # "tcp_rst": true + # } + # ] + # }, + # "before": {}, + # "changed": true, + # "commands": + # 't' + # 'est descriptionallbgpalldhcpge-0/0/1.0ge-0/0/2.0test_screentest_sec_zone1test_adr110.0.0.0/24test desctest_adr21.1.1.1test_adr310.2.0.110.2.0.2test_adr410.3.0.1/24test_adr510.1.0.0/24test desctest_adrset1test_adr1test' + # '_adr2test_adrset2test_adr3test_adr4test_adrset3test_adr5test_adrset1test_adrset2test descriptiontest_profiletest descriptionallbgpalldhcpge-0/0/3.0ge-0/0/4.0test_screen' + + # After state + # ----------- + # + # vagrant@vsrx# show system ntp + # functional-zone management { + # interfaces { + # ge-0/0/1.0; + # ge-0/0/2.0; + # } + # screen test_screen; + # host-inbound-traffic { + # system-services { + # all; + # dhcp { + # except; + # } + # } + # protocols { + # all; + # bgp { + # except; + # } + # } + # } + # description "test description"; + # } + # security-zone test_sec_zone1 { + # description "test description"; + # tcp-rst; + # address-book { + # address test_adr1 { + # description "test desc"; + # 10.0.0.0/24; + # } + # address test_adr2 { + # dns-name 1.1.1.1 { + # ipv6-only; + # } + # } + # address test_adr3 { + # range-address 10.2.0.1 { + # to { + # 10.2.0.2; + # } + # } + # } + # address test_adr4 { + # wildcard-address 10.3.0.1/24; + # } + # address test_adr5 { + # description "test desc"; + # 10.1.0.0/24; + # } + # address-set test_adrset1 { + # address test_adr1; + # address test_adr2; + # } + # address-set test_adrset2 { + # address test_adr3; + # address test_adr4; + # } + # address-set test_adrset3 { + # description "test description"; + # address test_adr5; + # address-set test_adrset1; + # address-set test_adrset2; + # } + # } + # screen test_screen; + # host-inbound-traffic { + # system-services { + # all; + # dhcp { + # except; + # } + # } + # protocols { + # all; + # bgp { + # except; + # } + # } + # } + # interfaces { + # ge-0/0/3.0; + # ge-0/0/4.0; + # } + # application-tracking; + # source-identity-log; + # advance-policy-based-routing-profile { + # test_profile; + # } + # enable-reverse-reroute; + # } + # + # + # Using Replaced + # Before state + # ------------ + # + # vagrant@vsrx# show security zones + # functional-zone management { + # interfaces { + # ge-0/0/1.0; + # ge-0/0/2.0; + # } + # screen test_screen; + # host-inbound-traffic { + # system-services { + # all; + # dhcp { + # except; + # } + # } + # protocols { + # all; + # bgp { + # except; + # } + # } + # } + # description "test description"; + # } + # security-zone test_sec_zone1 { + # description "test description"; + # tcp-rst; + # address-book { + # address test_adr1 { + # description "test desc"; + # 10.0.0.0/24; + # } + # address test_adr2 { + # dns-name 1.1.1.1 { + # ipv6-only; + # } + # } + # address test_adr3 { + # range-address 10.2.0.1 { + # to { + # 10.2.0.2; + # } + # } + # } + # address test_adr4 { + # wildcard-address 10.3.0.1/24; + # } + # address test_adr5 { + # description "test desc"; + # 10.1.0.0/24; + # } + # address-set test_adrset1 { + # address test_adr1; + # address test_adr2; + # } + # address-set test_adrset2 { + # address test_adr3; + # address test_adr4; + # } + # address-set test_adrset3 { + # description "test description"; + # address test_adr5; + # address-set test_adrset1; + # address-set test_adrset2; + # } + # } + # screen test_screen; + # host-inbound-traffic { + # system-services { + # all; + # dhcp { + # except; + # } + # } + # protocols { + # all; + # bgp { + # except; + # } + # } + # } + # interfaces { + # ge-0/0/3.0; + # ge-0/0/4.0; + # } + # application-tracking; + # source-identity-log; + # advance-policy-based-routing-profile { + # test_profile; + # } + # enable-reverse-reroute; + # } + # + # + + - name: Replaced running security zones configuration with provided configuration + junipernetworks.junos.junos_security_zones: + config: + functional_zone_management: + description: test description + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + state: replaced + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "functional_zone_management": { + # "description": "test description", + # "host_inbound_traffic": { + # "protocols": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "bgp" + # } + # ], + # "system_services": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "dhcp" + # } + # ] + # }, + # "interfaces": [ + # "ge-0/0/1.0", + # "ge-0/0/2.0" + # ], + # "screen": "test_screen" + # } + # }, + # "before": { + # "functional_zone_management": { + # "description": "test description", + # "host_inbound_traffic": { + # "protocols": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "bgp" + # } + # ], + # "system_services": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "dhcp" + # } + # ] + # }, + # "interfaces": [ + # "ge-0/0/1.0", + # "ge-0/0/2.0" + # ], + # "screen": "test_screen" + # }, + # "security_zones": [ + # { + # "address_book": { + # "address_sets": [ + # { + # "addresses": [ + # "test_adr1", + # "test_adr2" + # ], + # "name": "test_adrset1" + # }, + # { + # "addresses": [ + # "test_adr3", + # "test_adr4" + # ], + # "name": "test_adrset2" + # }, + # { + # "address_sets": [ + # "test_adrset1", + # "test_adrset2" + # ], + # "addresses": [ + # "test_adr5" + # ], + # "description": "test description", + # "name": "test_adrset3" + # } + # ], + # "addresses": [ + # { + # "description": "test desc", + # "ip_prefix": "10.0.0.0/24", + # "name": "test_adr1" + # }, + # { + # "dns_name": { + # "ipv6_only": true, + # "name": "1.1.1.1" + # }, + # "name": "test_adr2" + # }, + # { + # "name": "test_adr3", + # "range_address": { + # "from": "10.2.0.1", + # "to": "10.2.0.2" + # } + # }, + # { + # "name": "test_adr4", + # "wildcard_address": "10.3.0.1/24" + # }, + # { + # "description": "test desc", + # "ip_prefix": "10.1.0.0/24", + # "name": "test_adr5" + # } + # ] + # }, + # "advance_policy_based_routing_profile": "test_profile", + # "application_tracking": true, + # "description": "test description", + # "enable_reverse_reroute": true, + # "host_inbound_traffic": { + # "protocols": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "bgp" + # } + # ], + # "system_services": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "dhcp" + # } + # ] + # }, + # "interfaces": [ + # "ge-0/0/3.0", + # "ge-0/0/4.0" + # ], + # "name": "test_sec_zone1", + # "screen": "test_screen", + # "source_identity_log": true, + # "tcp_rst": true + # } + # ] + # }, + # "changed": true, + # "commands": + # 'test descriptionallbgpalldhcpge-0/0/1.0ge-0/0/2.0test_screen' + # + # + # After state + # ----------- + # + # vagrant@vsrx# show system ntp + # functional-zone management { + # interfaces { + # ge-0/0/1.0; + # ge-0/0/2.0; + # } + # screen test_screen; + # host-inbound-traffic { + # system-services { + # all; + # dhcp { + # except; + # } + # } + # protocols { + # all; + # bgp { + # except; + # } + # } + # } + # description "test description"; + # } + # + # + # Using overridden + # + # Before state + # ------------ + # + # vagrant@vsrx# show security zones + # functional-zone management { + # interfaces { + # ge-0/0/1.0; + # ge-0/0/2.0; + # } + # screen test_screen; + # host-inbound-traffic { + # system-services { + # all; + # dhcp { + # except; + # } + # } + # protocols { + # all; + # bgp { + # except; + # } + # } + # } + # description "test description"; + # } + # security-zone test_sec_zone1 { + # description "test description"; + # tcp-rst; + # address-book { + # address test_adr1 { + # description "test desc"; + # 10.0.0.0/24; + # } + # address test_adr2 { + # dns-name 1.1.1.1 { + # ipv6-only; + # } + # } + # address test_adr3 { + # range-address 10.2.0.1 { + # to { + # 10.2.0.2; + # } + # } + # } + # address test_adr4 { + # wildcard-address 10.3.0.1/24; + # } + # address test_adr5 { + # description "test desc"; + # 10.1.0.0/24; + # } + # address-set test_adrset1 { + # address test_adr1; + # address test_adr2; + # } + # address-set test_adrset2 { + # address test_adr3; + # address test_adr4; + # } + # address-set test_adrset3 { + # description "test description"; + # address test_adr5; + # address-set test_adrset1; + # address-set test_adrset2; + # } + # } + # screen test_screen; + # host-inbound-traffic { + # system-services { + # all; + # dhcp { + # except; + # } + # } + # protocols { + # all; + # bgp { + # except; + # } + # } + # } + # interfaces { + # ge-0/0/3.0; + # ge-0/0/4.0; + # } + # application-tracking; + # source-identity-log; + # advance-policy-based-routing-profile { + # test_profile; + # } + # enable-reverse-reroute; + # } + # + # + + - name: Override running security zones configuration with provided configuration + junipernetworks.junos.junos_security_zones: + config: + functional_zone_management: + description: test description + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + state: overridden + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "functional_zone_management": { + # "description": "test description", + # "host_inbound_traffic": { + # "protocols": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "bgp" + # } + # ], + # "system_services": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "dhcp" + # } + # ] + # }, + # "interfaces": [ + # "ge-0/0/1.0", + # "ge-0/0/2.0" + # ], + # "screen": "test_screen" + # } + # }, + # "before": { + # "functional_zone_management": { + # "description": "test description", + # "host_inbound_traffic": { + # "protocols": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "bgp" + # } + # ], + # "system_services": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "dhcp" + # } + # ] + # }, + # "interfaces": [ + # "ge-0/0/1.0", + # "ge-0/0/2.0" + # ], + # "screen": "test_screen" + # }, + # "security_zones": [ + # { + # "address_book": { + # "address_sets": [ + # { + # "addresses": [ + # "test_adr1", + # "test_adr2" + # ], + # "name": "test_adrset1" + # }, + # { + # "addresses": [ + # "test_adr3", + # "test_adr4" + # ], + # "name": "test_adrset2" + # }, + # { + # "address_sets": [ + # "test_adrset1", + # "test_adrset2" + # ], + # "addresses": [ + # "test_adr5" + # ], + # "description": "test description", + # "name": "test_adrset3" + # } + # ], + # "addresses": [ + # { + # "description": "test desc", + # "ip_prefix": "10.0.0.0/24", + # "name": "test_adr1" + # }, + # { + # "dns_name": { + # "ipv6_only": true, + # "name": "1.1.1.1" + # }, + # "name": "test_adr2" + # }, + # { + # "name": "test_adr3", + # "range_address": { + # "from": "10.2.0.1", + # "to": "10.2.0.2" + # } + # }, + # { + # "name": "test_adr4", + # "wildcard_address": "10.3.0.1/24" + # }, + # { + # "description": "test desc", + # "ip_prefix": "10.1.0.0/24", + # "name": "test_adr5" + # } + # ] + # }, + # "advance_policy_based_routing_profile": "test_profile", + # "application_tracking": true, + # "description": "test description", + # "enable_reverse_reroute": true, + # "host_inbound_traffic": { + # "protocols": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "bgp" + # } + # ], + # "system_services": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "dhcp" + # } + # ] + # }, + # "interfaces": [ + # "ge-0/0/3.0", + # "ge-0/0/4.0" + # ], + # "name": "test_sec_zone1", + # "screen": "test_screen", + # "source_identity_log": true, + # "tcp_rst": true + # } + # ] + # }, + # "changed": true, + # "commands": + # 'test descriptionallbgpalldhcpge-0/0/1.0ge-0/0/2.0test_screen' + # + # + # After state + # ----------- + # + # vagrant@vsrx# show system ntp + # functional-zone management { + # interfaces { + # ge-0/0/1.0; + # ge-0/0/2.0; + # } + # screen test_screen; + # host-inbound-traffic { + # system-services { + # all; + # dhcp { + # except; + # } + # } + # protocols { + # all; + # bgp { + # except; + # } + # } + # } + # description "test description"; + # } + # + # + # Using deleted + # + # Before state + # ------------ + # + # vagrant@vsrx# show security zones + # functional-zone management { + # interfaces { + # ge-0/0/1.0; + # ge-0/0/2.0; + # } + # screen test_screen; + # host-inbound-traffic { + # system-services { + # all; + # dhcp { + # except; + # } + # } + # protocols { + # all; + # bgp { + # except; + # } + # } + # } + # description "test description"; + # } + # + # + - name: Delete running security zones configuration + junipernetworks.junos.junos_security_zones: + config: + state: deleted + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": {}, + # "before": { + # "functional_zone_management": { + # "description": "test description", + # "host_inbound_traffic": { + # "protocols": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "bgp" + # } + # ], + # "system_services": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "dhcp" + # } + # ] + # }, + # "interfaces": [ + # "ge-0/0/1.0", + # "ge-0/0/2.0" + # ], + # "screen": "test_screen" + # } + # }, + # "changed": true, + # "commands": + # "" + # "" + # + # + # After state + # ----------- + # + # vagrant@vsrx# show security zones + # + # [edit] + # Using gathered + # + # Before state + # ------------ + # + # vagrant@vsrx# show system ntp + # functional-zone management { + # interfaces { + # ge-0/0/1.0; + # ge-0/0/2.0; + # } + # screen test_screen; + # host-inbound-traffic { + # system-services { + # all; + # dhcp { + # except; + # } + # } + # protocols { + # all; + # bgp { + # except; + # } + # } + # } + # description "test description"; + # } + # security-zone test_sec_zone1 { + # description "test description"; + # tcp-rst; + # address-book { + # address test_adr1 { + # description "test desc"; + # 10.0.0.0/24; + # } + # address test_adr2 { + # dns-name 1.1.1.1 { + # ipv6-only; + # } + # } + # address test_adr3 { + # range-address 10.2.0.1 { + # to { + # 10.2.0.2; + # } + # } + # } + # address test_adr4 { + # wildcard-address 10.3.0.1/24; + # } + # address test_adr5 { + # description "test desc"; + # 10.1.0.0/24; + # } + # address-set test_adrset1 { + # address test_adr1; + # address test_adr2; + # } + # address-set test_adrset2 { + # address test_adr3; + # address test_adr4; + # } + # address-set test_adrset3 { + # description "test description"; + # address test_adr5; + # address-set test_adrset1; + # address-set test_adrset2; + # } + # } + # screen test_screen; + # host-inbound-traffic { + # system-services { + # all; + # dhcp { + # except; + # } + # } + # protocols { + # all; + # bgp { + # except; + # } + # } + # } + # interfaces { + # ge-0/0/3.0; + # ge-0/0/4.0; + # } + # application-tracking; + # source-identity-log; + # advance-policy-based-routing-profile { + # test_profile; + # } + # enable-reverse-reroute; + # } + - name: Gather running security zones configuration + junipernetworks.junos.junos_security_zones: + state: gathered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "gathered": { + # "functional_zone_management": { + # "description": "test description", + # "host_inbound_traffic": { + # "protocols": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "bgp" + # } + # ], + # "system_services": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "dhcp" + # } + # ] + # }, + # "interfaces": [ + # "ge-0/0/1.0", + # "ge-0/0/2.0" + # ], + # "screen": "test_screen" + # }, + # "security_zones": [ + # { + # "address_book": { + # "address_sets": [ + # { + # "addresses": [ + # "test_adr1", + # "test_adr2" + # ], + # "name": "test_adrset1" + # }, + # { + # "addresses": [ + # "test_adr3", + # "test_adr4" + # ], + # "name": "test_adrset2" + # }, + # { + # "address_sets": [ + # "test_adrset1", + # "test_adrset2" + # ], + # "addresses": [ + # "test_adr5" + # ], + # "description": "test description", + # "name": "test_adrset3" + # } + # ], + # "addresses": [ + # { + # "description": "test desc", + # "ip_prefix": "10.0.0.0/24", + # "name": "test_adr1" + # }, + # { + # "dns_name": { + # "ipv6_only": true, + # "name": "1.1.1.1" + # }, + # "name": "test_adr2" + # }, + # { + # "name": "test_adr3", + # "range_address": { + # "from": "10.2.0.1", + # "to": "10.2.0.2" + # } + # }, + # { + # "name": "test_adr4", + # "wildcard_address": "10.3.0.1/24" + # }, + # { + # "description": "test desc", + # "ip_prefix": "10.1.0.0/24", + # "name": "test_adr5" + # } + # ] + # }, + # "advance_policy_based_routing_profile": "test_profile", + # "application_tracking": true, + # "description": "test description", + # "enable_reverse_reroute": true, + # "host_inbound_traffic": { + # "protocols": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "bgp" + # } + # ], + # "system_services": [ + # { + # "name": "all" + # }, + # { + # "except": true, + # "name": "dhcp" + # } + # ] + # }, + # "interfaces": [ + # "ge-0/0/3.0", + # "ge-0/0/4.0" + # ], + # "name": "test_sec_zone1", + # "screen": "test_screen", + # "source_identity_log": true, + # "tcp_rst": true + # } + # ] + # } + # "changed": false, + # + # + # Using rendered + # + # Before state + # ------------ + # + - name: Render xml for provided facts. + junipernetworks.junos.junos_security_zones: + config: + functional_zone_management: + description: test description + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + security_zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + - addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true + state: rendered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "rendered": + # 't' + # 'est descriptionallbgpalldhcpge-0/0/1.0ge-0/0/2.0test_screentest_sec_zone1test_adr110.0.0.0/24test desctest_adr21.1.1.1test_adr310.2.0.110.2.0.2test_adr410.3.0.1/24test_adr510.1.0.0/24test desctest_adrset1test_adr1test' + # '_adr2test_adrset2test_adr3test_adr4test_adrset3test_adr5test_adrset1test_adrset2test descriptiontest_profiletest descriptionallbgpalldhcpge-0/0/3.0ge-0/0/4.0test_screen' + # + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # + # + # + # test description + # + # + # all + # + # + # bgp + # + # + # + # all + # + # + # dhcp + # + # + # + # + # ge-0/0/1.0 + # + # + # ge-0/0/2.0 + # + # test_screen + # + # + # + # test_sec_zone1 + # + #
+ # test_adr1 + # 10.0.0.0/24 + # test desc + #
+ #
+ # test_adr2 + # + # 1.1.1.1 + # + # + #
+ #
+ # test_adr3 + # + # 10.2.0.1 + # + # 10.2.0.2 + # + # + #
+ #
+ # test_adr4 + # + # 10.3.0.1/24 + # + #
+ #
+ # test_adr5 + # 10.1.0.0/24 + # test desc + #
+ # + # test_adrset1 + #
+ # test_adr1 + #
+ #
+ # test_adr2 + #
+ #
+ # + # test_adrset2 + #
+ # test_adr3 + #
+ #
+ # test_adr4 + #
+ #
+ # + # test_adrset3 + #
+ # test_adr5 + #
+ # + # test_adrset1 + # + # + # test_adrset2 + # + # test description + #
+ #
+ # + # test_profile + # + # + # test description + # + # + # + # all + # + # + # bgp + # + # + # + # all + # + # + # dhcp + # + # + # + # + # ge-0/0/3.0 + # + # + # ge-0/0/4.0 + # + # test_screen + # + # + #
+ #
+ #
+ #
+ #
+ # + - name: Parse security zones running config + junipernetworks.junos.junos_security_zones: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # + # "parsed": { + # "functional_zone_management": { + # "description": "test description 2", + # "host_inbound_traffic": { + # "protocols": [{"name": "all"}, {"except": True, "name": "bgp"}, {"except": True, "name": "bfd"}], + # "system_services": [{"name": "all"}, {"except": True, "name": "dhcp"}, {"except": True, "name": "dhcpv6"}], + # }, + # "interfaces": ["ge-0/0/1.0", "ge-0/0/2.0"], + # "screen": "test_screen", + # }, + # "security_zones": [ + # { + # "address_book": { + # "address_sets": [ + # {"addresses": ["test_adr1", "test_adr2"], "name": "test_adrset1"}, + # {"addresses": ["test_adr3", "test_adr4"], "name": "test_adrset2"}, + # { + # "address_sets": ["test_adrset1", "test_adrset2"], + # "addresses": ["test_adr5"], + # "description": "test description", + # "name": "test_adrset3", + # }, + # ], + # "addresses": [ + # {"description": "test desc", "ip_prefix": "10.0.0.0/24", "name": "test_adr1"}, + # {"dns_name": {"ipv6_only": True, "name": "1.1.1.1"}, "name": "test_adr2"}, + # {"name": "test_adr3", "range_address": {"from": "10.2.0.1", "to": "10.2.0.2"}}, + # {"name": "test_adr4", "wildcard_address": "10.3.0.1/24"}, + # {"description": "test desc", "ip_prefix": "10.1.0.0/24", "name": "test_adr5"}, + # ], + # }, + # "advance_policy_based_routing_profile": "test_profile", + # "application_tracking": True, + # "description": "test description", + # "enable_reverse_reroute": True, + # "host_inbound_traffic": { + # "protocols": [{"name": "all"}, {"except": True, "name": "bgp"}], + # "system_services": [{"name": "all"}, {"except": True, "name": "dhcp"}], + # }, + # "interfaces": ["ge-0/0/3.0", "ge-0/0/4.0"], + # "name": "test_sec_zone1", + # "screen": "test_screen", + # "source_identity_log": True, + # "tcp_rst": True, + # }, + # {"name": "test_sec_zone2", "source_identity_log": True, "tcp_rst": True}, + # ], + # } + # + # + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration after module execution.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ before + +
+ dictionary +
+
when state is merged, replaced, overridden, deleted or purged +
The configuration prior to the module execution.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ commands + +
+ list +
+
when state is merged, replaced, overridden, deleted or purged +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<rpc-reply> <configuration> <security> <policies> <global> <policy> <name>test_glob_1</name> <match> <source-address>any-ipv6</source-address> <destination-address>any-ipv6</destination-address> <application>any</application> </match> <then> <deny /> </then> </policy> </global> </policies> </security> </configuration> </rpc-reply>']
+
+
+ gathered + +
+ dictionary +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ dictionary +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ dictionary +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['<rpc-reply> <configuration> <security> <policies> <global> <policy> <name>test_glob_1</name> <match> <source-address>any-ipv6</source-address> <destination-address>any-ipv6</destination-address> <application>any</application> </match> <then> <deny /> </then> </policy> </global> </policies> </security> </configuration> </rpc-reply>']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Pranav Bhatt (@pranav-bhatt) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_snmp_server_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_snmp_server_module.rst new file mode 100644 index 00000000..35996ebf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_snmp_server_module.rst @@ -0,0 +1,6131 @@ +.. _junipernetworks.junos.junos_snmp_server_module: + + +*************************************** +junipernetworks.junos.junos_snmp_server +*************************************** + +**Manage SNMP server configuration on Junos devices.** + + +Version added: 2.9.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages SNMP server configuration on devices running Junos. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12.0) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
A dictionary of SNMP server configuration.
+
+
+ arp + +
+ dictionary +
+
+ +
Specify JVision arp setting.
+
+
+ host_name_resolution + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Enable host name resolution.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set JVision arp.
+
+
+ client_lists + +
+ list + / elements=dictionary +
+
+ +
Specify client list.
+
+
+ addresses + +
+ list + / elements=dictionary +
+
+ +
Specify list of addresses/prefixes.
+
+
+ address + +
+ string +
+
+ +
Specify address or prefix.
+
+
+ restrict + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Deny access.
+
+
+ name + +
+ string +
+
+ +
Specify client list name.
+
+
+ communities + +
+ list + / elements=dictionary +
+
+ +
Specify list of community string.
+
+
+ authorization + +
+ string +
+
+
    Choices: +
  • read-only
  • +
  • read-write
  • +
+
+
Specify Authorization type.
+
+
+ client_list_name + +
+ string +
+
+ +
Specify the name of client list or prefix list.
+
+
+ clients + +
+ list + / elements=dictionary +
+
+ +
Specify List of source address prefix ranges to accept.
+
+
+ address + +
+ string +
+
+ +
Specify address or prefix.
+
+
+ restrict + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Deny access.
+
+
+ logical_system + +
+ list + / elements=string +
+
+ +
Use logical-system name for v1/v2c clients.
+
+
+ name + +
+ string +
+
+ +
Specify name of the community.
+
+
+ routing_instances + +
+ list + / elements=dictionary +
+
+ +
Use routing-instance name for v1/v2c clients.
+
+
+ client_list_name + +
+ string +
+
+ +
Specify the name of client list or prefix list.
+
+
+ clients + +
+ list + / elements=dictionary +
+
+ +
Specify List of source address prefix ranges to accept.
+
+
+ address + +
+ string +
+
+ +
Specify address or prefix.
+
+
+ restrict + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Deny access.
+
+
+ name + +
+ string +
+
+ +
Specify routing-instances.
+
+
+ view + +
+ string +
+
+ +
Specify view name.
+
+
+ contact + +
+ string +
+
+ +
Specify contact information for administrator.
+
+
+ customization + +
+ dictionary +
+
+ +
Customize SNMP behaviour based on knob.
+
+
+ ether_stats_ifd_only + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
To stop exposing IFLs as part of etherStatsTable.
+
+
+ description + +
+ string +
+
+ +
System description.
+
+
+ engine_id + +
+ dictionary +
+
+ +
Specify SNMPv3 engine ID
+
+
+ local + +
+ string +
+
+ +
Local engine ID.
+
+
+ use_default_ip_address + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Use default IP address for the engine ID.
+
+
+ use_mac_address + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Uses management interface MAC Address for the engine ID.
+
+
+ filter_duplicates + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Filter requests with duplicate source address/port and request ID.
+
+
+ filter_interfaces + +
+ dictionary +
+
+ +
List of interfaces that needs to be filtered.
+
+
+ all_internal_interfaces + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Filter all internal interfaces.
+
+
+ interfaces + +
+ list + / elements=string +
+
+ +
Specify filter specified interfaces.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set filter-interfaces.
+
+
+ health_monitor + +
+ dictionary +
+
+ +
Specify health monitoring configuration.
+
+
+ falling_threshold + +
+ integer +
+
+ +
Falling threshold applied to all monitored objects.
+
+
+ idp + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
IDP health monitor configuration.
+
+
+ interval + +
+ integer +
+
+ +
Interval between samples.
+
+
+ rising_threshold + +
+ integer +
+
+ +
Rising threshold applied to all monitored objects.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set health-monitor configuration.
+
+
+ if_count_with_filter_interfaces + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Filter interfaces config for ifNumber and ipv6Interfaces.
+
+
+ interfaces + +
+ list + / elements=string +
+
+ +
Restrict SNMP requests to interfaces.
+
+
+ location + +
+ string +
+
+ +
Specify physical location of system.
+
+
+ logical_system_trap_filter + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allow only logical-system specific traps.
+
+
+ name + +
+ string +
+
+ +
System name override.
+
+
+ nonvolatile + +
+ dictionary +
+
+ +
Configure the handling of nonvolatile SNMP Set requests.
+
+
+ commit_delay + +
+ integer +
+
+ +
Delay between affirmative SNMP Set reply and start of commit (seconds).
+
+
+ proxies + +
+ list + / elements=dictionary +
+
+ +
SNMP proxy configuration.
+
+
+ device_name + +
+ string +
+
+ +
Satellite/Proxied Device name or IP address.
+
+
+ logical_system + +
+ list + / elements=string +
+
+ +
Use logical-system name for v1/v2c clients.
+
+
+ name + +
+ string +
+
+ +
Specify proxy name.
+
+
+ routing_instances + +
+ list + / elements=dictionary +
+
+ +
Use routing-instance name for v1/v2c clients.
+
+
+ client_list_name + +
+ string +
+
+ +
Specify the name of client list or prefix list.
+
+
+ clients + +
+ list + / elements=dictionary +
+
+ +
Specify List of source address prefix ranges to accept.
+
+
+ address + +
+ string +
+
+ +
Specify address or prefix.
+
+
+ restrict + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Deny access.
+
+
+ name + +
+ string +
+
+ +
Specify routing-instances.
+
+
+ version_v1 + +
+ dictionary +
+
+ +
Specify For v1 proxy configuration define snmp-community.
+
+
+ no_default_comm_to_v3_config + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify No default snmp-community and v3 configuration.
+
+
+ snmp_community + +
+ string +
+
+ +
Specify community name.
+
+
+ version_v2c + +
+ dictionary +
+
+ +
For v2c proxy configuration define snmp-community.
+
+
+ no_default_comm_to_v3_config + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify No default snmp-community and v3 configuration.
+
+
+ snmp_community + +
+ string +
+
+ +
Specify community name.
+
+
+ version_v3 + +
+ dictionary +
+
+ +
For v3 proxy configuration define security-name.
+
+
+ context + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
pecify context name associated to this security-name.
+
+
+ security_name + +
+ string +
+
+ +
Specify v3 security-name.
+
+
+ rmon + +
+ dictionary +
+
+ +
Specify Remote Monitoring configuration.
+
+
+ alarms + +
+ list + / elements=dictionary +
+
+ +
RMON alarm entries.
+
+
+ description + +
+ string +
+
+ +
General description of alarm (stored in alarmOwner).
+
+
+ falling_event_index + +
+ integer +
+
+ +
Event triggered after falling threshold is crossed.
+
+
+ falling_threshold + +
+ integer +
+
+ +
Specify falling-threshold.
+
+
+ falling_threshold_interval + +
+ integer +
+
+ +
Interval between samples during falling-threshold test.
+
+
+ id + +
+ string +
+
+ +
Specify alarm ID.
+
+
+ interval + +
+ integer +
+
+ +
Interval between samples.
+
+
+ request_type + +
+ string +
+
+
    Choices: +
  • get-next-request
  • +
  • get-request
  • +
  • walk-request
  • +
+
+
Type of SNMP request to issue for alarm.
+
+
+ rising_event_index + +
+ integer +
+
+ +
Event triggered after rising threshold is crossed.
+
+
+ rising_threshold + +
+ integer +
+
+ +
The rising threshold.
+
+
+ sample_type + +
+ string +
+
+
    Choices: +
  • absolute-value
  • +
  • delta-value
  • +
+
+
Method of sampling the selected variable.
+
+
+ startup_alarm + +
+ string +
+
+
    Choices: +
  • falling-alarm
  • +
  • rising-alarm
  • +
  • rising-or-falling-alarm
  • +
+
+
The alarm that may be sent upon entry startup.
+
+
+ syslog_subtag + +
+ string +
+
+ +
Tag to be added to syslog messages.
+
+
+ variable + +
+ string +
+
+ +
OID of MIB variable to be monitored.
+
+
+ events + +
+ list + / elements=dictionary +
+
+ +
RMON event entries.
+
+
+ community + +
+ string +
+
+ +
The community (trap group) for outgoing traps.
+
+
+ description + +
+ string +
+
+ +
General description of event.
+
+
+ id + +
+ integer +
+
+ +
Specify event ID.
+
+
+ type + +
+ string +
+
+
    Choices: +
  • log
  • +
  • log-and-trap
  • +
  • none
  • +
  • snmptrap
  • +
+
+
The type of notification for this event.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set Remote monitoring configuration.
+
+
+ routing_instance_access + +
+ dictionary +
+
+ +
SNMP routing-instance options.
+
+
+ access_lists + +
+ list + / elements=string +
+
+ +
Allow/Deny SNMP access to routing-instances.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set routing_instance_access.
+
+
+ snmp_v3 + +
+ dictionary +
+
+ +
SNMPv3 configuration information.
+
+
+ notify + +
+ list + / elements=dictionary +
+
+ +
Used to select management targets for notifications as well as the type of notifications.
+
+
+ name + +
+ string +
+
+ +
Specify notify name.
+
+
+ tag + +
+ string +
+
+ +
Notifications will be sent to all targets configured with this tag.
+
+
+ type + +
+ string +
+
+ +
Notification type.
+
+
+ notify_filter + +
+ list + / elements=dictionary +
+
+ +
Filters to apply to SNMP notifications.
+
+
+ name + +
+ string +
+
+ +
Specify notify filter name.
+
+
+ oids + +
+ list + / elements=dictionary +
+
+ +
OID to include/exclude from notify filter.
+
+
+ exclude + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Exclude this OID from the notify filtered.
+
+
+ include + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Include this OID in the notify filter.
+
+
+ oid + +
+ string +
+
+ +
Specify OID.
+
+
+ snmp_community + +
+ list + / elements=dictionary +
+
+ +
SNMP community and view-based access control model configuration.
+
+
+ community_index + +
+ string +
+
+ +
Unique index value in this community table entry.
+
+
+ community_name + +
+ string +
+
+ +
SNMPv1/v2c community name (default is same as community-index).
+
+
+ context + +
+ string +
+
+ +
Context used when performing access control.
+
+
+ security_name + +
+ string +
+
+ +
Security name used when performing access control.
+
+
+ tag + +
+ string +
+
+ +
Tag identifier for set of targets allowed to use this community string.
+
+
+ target_addresses + +
+ list + / elements=dictionary +
+
+ +
Identifies notification targets as well as allowed management stations.
+
+
+ address + +
+ string +
+
+ +
SNMP target address.
+
+
+ address_mask + +
+ string +
+
+ +
Mask range of addresses for community string access control.
+
+
+ logical_system + +
+ string +
+
+ +
Logical-system name for trap destination.
+
+
+ name + +
+ string +
+
+ +
SNMP target address name.
+
+
+ port + +
+ integer +
+
+ +
SNMP target port number.
+
+
+ retry_count + +
+ integer +
+
+ +
Maximum retry count for confirmed SNMP notifications.
+
+
+ routing_instance + +
+ string +
+
+ +
Routing instance for trap destination.
+
+
+ tag_list + +
+ string +
+
+ +
SNMP tag list used to select target addresses.
+
+
+ target_parameters + +
+ string +
+
+ +
SNMPv3 target parameter name in the target parameters table.
+
+
+ timeout + +
+ integer +
+
+ +
Acknowledgment timeout for confirmed SNMP notifications (seconds).
+
+
+ target_parameters + +
+ list + / elements=dictionary +
+
+ +
SNMPv3 target parameter name in the target parameters table.
+
+
+ name + +
+ string +
+
+ +
SNMPv3 target parameters name.
+
+
+ notify_filter + +
+ string +
+
+ +
Notify filter with filter name to apply to notifications.
+
+
+ parameters + +
+ dictionary +
+
+ +
Parameters used when sending notifications.
+
+
+ message_processing_model + +
+ string +
+
+
    Choices: +
  • v1
  • +
  • v2c
  • +
  • v3
  • +
+
+
The message processing model to be used when generating SNMP notifications.
+
+
+ security_level + +
+ string +
+
+
    Choices: +
  • authentication
  • +
  • none
  • +
  • privacy
  • +
+
+
Security-level used when generating SNMP notifications.
+
+
+ security_model + +
+ string +
+
+
    Choices: +
  • usm
  • +
  • v1
  • +
  • v2c
  • +
+
+
Security-model used when generating SNMP notifications.
+
+
+ security_name + +
+ string +
+
+ +
Security name used when generating SNMP notifications.
+
+
+ usm + +
+ dictionary +
+
+ +
User-based security model (USM) information.
+
+
+ local_engine + +
+ dictionary +
+
+ +
Local engine user configuration.
+
+
+ users + +
+ list + / elements=dictionary +
+
+ +
SNMPv3 USM user information.
+
+
+ authentication_md5 + +
+ dictionary +
+
+ +
Configure MD5 authentication.
+
+
+ key + +
+ string +
+
+ +
Encrypted key used for user authentication.
+
+
+ password + +
+ string +
+
+ +
User's authentication password
+
+
+ authentication_none + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set no authentication for the user.
+
+
+ authentication_sha + +
+ dictionary +
+
+ +
Configure SHA authentication.
+
+
+ key + +
+ string +
+
+ +
Encrypted key used for user authentication.
+
+
+ password + +
+ string +
+
+ +
User's authentication password
+
+
+ name + +
+ string +
+
+ +
User name.
+
+
+ privacy_3des + +
+ dictionary +
+
+ +
Configure Triple DES privacy.
+
+
+ key + +
+ string +
+
+ +
Encrypted key used for user privacy.
+
+
+ password + +
+ string +
+
+ +
User's privacy password
+
+
+ privacy_aes128 + +
+ dictionary +
+
+ +
Configure AES128 privacy.
+
+
+ key + +
+ string +
+
+ +
Encrypted key used for user privacy.
+
+
+ password + +
+ string +
+
+ +
User's privacy password
+
+
+ privacy_des + +
+ dictionary +
+
+ +
Configure DES privacy.
+
+
+ key + +
+ string +
+
+ +
Encrypted key used for user privacy.
+
+
+ password + +
+ string +
+
+ +
User's privacy password
+
+
+ privacy_none + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set no privacy for the user.
+
+
+ remote_engine + +
+ list + / elements=dictionary +
+
+ +
Remote engine user configuration.
+
+
+ id + +
+ string +
+
+ +
Remote engine id.
+
+
+ users + +
+ list + / elements=dictionary +
+
+ +
SNMPv3 USM user information.
+
+
+ authentication_md5 + +
+ dictionary +
+
+ +
Configure MD5 authentication.
+
+
+ key + +
+ string +
+
+ +
Encrypted key used for user authentication.
+
+
+ password + +
+ string +
+
+ +
User's authentication password
+
+
+ authentication_none + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set no authentication for the user.
+
+
+ authentication_sha + +
+ dictionary +
+
+ +
Configure SHA authentication.
+
+
+ key + +
+ string +
+
+ +
Encrypted key used for user authentication.
+
+
+ password + +
+ string +
+
+ +
User's authentication password
+
+
+ name + +
+ string +
+
+ +
User name.
+
+
+ privacy_3des + +
+ dictionary +
+
+ +
Configure Triple DES privacy.
+
+
+ key + +
+ string +
+
+ +
Encrypted key used for user privacy.
+
+
+ password + +
+ string +
+
+ +
User's privacy password
+
+
+ privacy_aes128 + +
+ dictionary +
+
+ +
Configure AES128 privacy.
+
+
+ key + +
+ string +
+
+ +
Encrypted key used for user privacy.
+
+
+ password + +
+ string +
+
+ +
User's privacy password
+
+
+ privacy_des + +
+ dictionary +
+
+ +
Configure DES privacy.
+
+
+ key + +
+ string +
+
+ +
Encrypted key used for user privacy.
+
+
+ password + +
+ string +
+
+ +
User's privacy password
+
+
+ privacy_none + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set no privacy for the user.
+
+
+ subagent + +
+ dictionary +
+
+ +
SNMP subagent configuration.
+
+
+ tcp + +
+ dictionary +
+
+ +
Allow SNMP subagent tcp connection.
+
+
+ routing_instances_default + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify routing-instance name for tcp connection.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set SNMP subagent TCP.
+
+
+ traceoptions + +
+ dictionary +
+
+ +
Configure trace options for SNMP.
+
+
+ file + +
+ dictionary +
+
+ +
Specify trace file options.
+
+
+ files + +
+ integer +
+
+ +
Specify maximum number of trace files.
+
+
+ match + +
+ string +
+
+ +
Regular expression for lines to be logged.
+
+
+ no_world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Don't allow any user to read the log file.
+
+
+ size + +
+ integer +
+
+ +
Specify maximum trace file size.
+
+
+ world_readable + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Allow any user to read the log file.
+
+
+ flag + +
+ dictionary +
+
+ +
Specify flag traceoptions.
+
+
+ all + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace everything.
+
+
+ general + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace general events.
+
+
+ interface_stats + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace interface statistics (logical and physical).
+
+
+ nonvolatile_sets + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Nonvolatile SNMP set request handling.
+
+
+ pdu + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Dump SNMP request/response packets.
+
+
+ protocol_timeouts + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace SNMP request timeouts.
+
+
+ routing_socket + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace routing socket calls.
+
+
+ subagent + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace master-agent interations with sub-agents.
+
+
+ timer + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace internal timer events.
+
+
+ varbind_error + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Trace varbind errors.
+
+
+ memory_trace + +
+ dictionary +
+
+ +
Memory tracing information.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
set memory traceoptions.
+
+
+ size + +
+ integer +
+
+ +
Specify Memory size reserved for tracing.
+
+
+ no_remote_trace + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Disable remote tracing.
+
+
+ trap_groups + +
+ list + / elements=dictionary +
+
+ +
Specify SNMP trap options.
+
+
+ categories + +
+ dictionary +
+
+ +
Specify Trap categories.
+
+
+ authentication + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify Authentication failures.
+
+
+ chassis + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify Chassis or environment notifications.
+
+
+ chassis_cluster + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify Clustering notifications.
+
+
+ configuration + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Configuration notifications.
+
+
+ dot3oam_events + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specify 802.3ah notifications.
+
+
+ link + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Link up-down transitions.
+
+
+ otn_alarms + +
+ dictionary +
+
+ +
OTN alarm trap subcategories.
+
+
+ oc_lof + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Loss of frame alarm notifications.
+
+
+ oc_lom + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Loss of multiframe alarm notification.
+
+
+ oc_los + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Loss of signal alarm notification.
+
+
+ odu_ais + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Alarm indication signal alarm notification.
+
+
+ odu_bbe_threshold + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Background block error threshold alarm notification.
+
+
+ odu_bdi + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Backward defect indication alarm notification.
+
+
+ odu_bdodu_es_threshold + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Errored Second threshold alarm notification.
+
+
+ odu_lck + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Locked alarm notification.
+
+
+ odu_oci + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Open connection indicator alarm notifications.
+
+
+ odu_rx_aps_change + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Receive APS change notifications.
+
+
+ odu_sd + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Signal degrade alarm notifications.
+
+
+ odu_ses_threshold + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Severely Errored Second threshold alarm notification.
+
+
+ odu_sf + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Signal fail alarm notification.
+
+
+ odu_ttim + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Trace identification mismatch alarm notification.
+
+
+ odu_uas_threshold + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Unavailable Second threshold alarm notification.
+
+
+ opu_ptm + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
ODU Payload Type Mismatch alarm notification.
+
+
+ otu_ais + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
OTU Alarm indication signal alarm notification.
+
+
+ otu_bbe_threshold + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
OTU Background block error threshold alarm notification.
+
+
+ otu_bdi + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
OTU Backward defect indication alarm notification.
+
+
+ otu_es_threshold + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
OTU Errored Second threshold alarm notification.
+
+
+ otu_fec_deg + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
OTU Fec degraded errors alarm notification.
+
+
+ otu_fec_exe + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
OTU Fec excessive errors alarm notification.
+
+
+ otu_iae + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
OTU Incoming alignment error alarm notification.
+
+
+ otu_sd + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
OTU Signal degrade alarm notification.
+
+
+ otu_ses_threshold + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
OTU Severely Errored Second threshold alarm notification.
+
+
+ otu_sf + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
OTU Signal fail alarm notification.
+
+
+ otu_ttim + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
OTU Trace identification mismatch alarm notification.
+
+
+ otu_uas_threshold + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
OTU Unavailable Second threshold alarm notification.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set otn_alarms.
+
+
+ wavelength_lock + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Wavelength lock alarm notification.
+
+
+ remote_operations + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Remote operations.
+
+
+ rmon_alarm + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
RMON rising and falling alarms.
+
+
+ routing + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Routing protocol notifications.
+
+
+ services + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Services notifications.
+
+
+ startup + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
System warm and cold starts.
+
+
+ vrrp_events + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
VRRP notifications.
+
+
+ destination_port + +
+ integer +
+
+ +
SNMP trap receiver port number
+
+
+ logical_system + +
+ list + / elements=string +
+
+ +
Use logical-system name for v1/v2c clients.
+
+
+ name + +
+ string +
+
+ +
Specify trap group name.
+
+
+ routing_instance + +
+ string +
+
+ +
Routing instance for trap destination.
+
+
+ targets + +
+ list + / elements=string +
+
+ +
Targets for trap messages
+
+
+ version + +
+ string +
+
+
    Choices: +
  • all
  • +
  • v1
  • +
  • v2
  • +
+
+
SNMP version.
+
+
+ trap_options + +
+ dictionary +
+
+ +
SNMP trap options.
+
+
+ agent_address + +
+ dictionary +
+
+ +
Agent address for v1 trap PDUs.
+
+
+ outgoing_interface + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Use address on outgoing interfaces.
+
+
+ context_oid + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Add context oid in varbind of all traps at the end.
+
+
+ enterprise_oid + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Add snmpTrapEnterprise oid in varbind of all traps.
+
+
+ logical_system + +
+ list + / elements=string +
+
+ +
Use logical-system name for v1/v2c clients.
+
+
+ routing_instance + +
+ string +
+
+ +
Specify routing-instance.
+
+
+ set + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Set trap options.
+
+
+ source_address + +
+ dictionary +
+
+ +
IPv4/IPv6 source address for trap PDUs.
+
+
+ address + +
+ string +
+
+ +
Use specified address.
+
+
+ lowest_loopback + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Use lowest address on loopback interfaces.
+
+
+ views + +
+ list + / elements=dictionary +
+
+ +
Define MIB views.
+
+
+ name + +
+ string +
+
+ +
MIB view name.
+
+
+ oids + +
+ list + / elements=dictionary +
+
+ +
OID include/exclude list
+
+
+ exclude + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Exclude this OID from the view.
+
+
+ include + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Include this OID from the view.
+
+
+ oid + +
+ string +
+
+ +
OID to include or exclude from view.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show system snmp.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • deleted
  • +
  • overridden
  • +
  • parsed
  • +
  • gathered
  • +
  • rendered
  • +
+
+
The state the configuration should be left in.
+
Refer to examples for more details.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. + - See `the Junos OS Platform Options `_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # vagrant@vsrx# show routing-instances + # clv1 { + # description clv1; + # } + # clv2 { + # description clv2; + # } + - name: Merge provided SNMP configuration into running configuration. + junipernetworks.junos.junos_snmp_server: + config: + arp: + set: true + host_name_resolution: true + client_lists: # ATTR-----2 + - name: cl1 + addresses: + - address: "192.16.1.0/24" + - address: "192.16.2.0/24" + - address: "11.11.11.11" + restrict: true + - name: cl2 + addresses: + - address: "192.16.4.0/24" + routing_instance_access: # ATTR-----3 + set: true + access_lists: + - "clv1" + - "clv2" + state: merged + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "arp": { + # "host_name_resolution": true + # }, + # "client_lists": [ + # { + # "addresses": [ + # { + # "address": "192.16.1.0/24" + # }, + # { + # "address": "192.16.2.0/24" + # }, + # { + # "address": "11.11.11.11/32", + # "restrict": true + # } + # ], + # "name": "cl1" + # }, + # { + # "addresses": [ + # { + # "address": "192.16.4.0/24" + # } + # ], + # "name": "cl2" + # } + # ], + # "routing_instance_access": { + # "access_lists": [ + # "clv1", + # "clv2" + # ] + # } + # }, + # "before": {}, + # "changed": true, + # "commands": [ + # "" + # "cl1" + # "192.16.1.0/24" + # "192.16.2.0/24" + # "11.11.11.11" + # "cl2192.16.4.0/24" + # "clv1" + # "clv2" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show snmp + # client-list cl1 { + # 192.16.1.0/24; + # 192.16.2.0/24; + # 11.11.11.11/32 { + # restrict; + # } + # } + # client-list cl2 { + # 192.16.4.0/24; + # } + # routing-instance-access { + # access-list { + # clv1; + # clv2; + # } + # } + # arp { + # host-name-resolution; + # } + # vagrant@vsrx# show routing-instances + # clv1 { + # description clv1; + # } + # clv2 { + # description clv2; + # } + # + # Using Replaced + # Before state + # ------------ + # + # vagrant@vsrx# show snmp + # client-list cl1 { + # 192.16.1.0/24; + # 192.16.2.0/24; + # 11.11.11.11/32 { + # restrict; + # } + # } + # client-list cl2 { + # 192.16.4.0/24; + # } + # routing-instance-access { + # access-list { + # clv1; + # clv2; + # } + # } + # arp { + # host-name-resolution; + # } + # vagrant@vsrx# show routing-instances + # clv1 { + # description clv1; + # } + # clv2 { + # description clv2; + # } + + - name: Replaced running SNMP server configuration with provided configuration + junipernetworks.junos.junos_snmp_server: + config: + contact: "ansiblesupport11@redhat.com" + customization: + ether_stats_ifd_only: true + description: "Local SNMP Server" + engine_id: + local: "local1" + use_default_ip_address: true + use_mac_address: true + filter_duplicates: true + filter_interfaces: + set: true + all_internal_interfaces: true + interfaces: + - "eth1" + - "eth2" + state: replaced + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "contact": "ansiblesupport11@redhat.com", + # "customization": { + # "ether_stats_ifd_only": true + # }, + # "description": "Local SNMP Server", + # "engine_id": { + # "use_mac_address": true + # }, + # "filter_duplicates": true, + # "filter_interfaces": { + # "all_internal_interfaces": true, + # "interfaces": [ + # "eth1", + # "eth2" + # ] + # } + # }, + # "before": + # { + # "arp": { + # "host_name_resolution": true + # }, + # "client_lists": [ + # { + # "addresses": [ + # { + # "address": "192.16.1.0/24" + # }, + # { + # "address": "192.16.2.0/24" + # }, + # { + # "address": "11.11.11.11/32", + # "restrict": true + # } + # ], + # "name": "cl1" + # }, + # { + # "addresses": [ + # { + # "address": "192.16.4.0/24" + # } + # ], + # "name": "cl2" + # } + # ], + # "routing_instance_access": { + # "access_lists": [ + # "clv1", + # "clv2" + # ] + # } + # }, + # "changed": true, + # "commands": [ + # "", + # "", + # "" + # "ansiblesupport11@redhat.com" + # "Local SNMP Server" + # "local1" + # "" + # "eth1eth2" + # "" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show routing-instances + # clv1 { + # description clv1; + # } + # clv2 { + # description clv2; + # } + # vagrant@vsrx# show snmp + # description "Local SNMP Server"; + # contact "ansiblesupport11@redhat.com"; + # filter-interfaces { + # interfaces { + # eth1; + # eth2; + # } + # all-internal-interfaces; + # } + # filter-duplicates; + # engine-id { + # use-mac-address; + # } + # customization { + # ether-stats-ifd-only; + # } + + # Using overridden + # + # Before state + # ------------ + # + # vagrant@vsrx# show snmp + # client-list cl1 { + # 192.16.1.0/24; + # 192.16.2.0/24; + # 11.11.11.11/32 { + # restrict; + # } + # } + # client-list cl2 { + # 192.16.4.0/24; + # } + # routing-instance-access { + # access-list { + # clv1; + # clv2; + # } + # } + # arp { + # host-name-resolution; + # } + # vagrant@vsrx# show routing-instances + # clv1 { + # description clv1; + # } + # clv2 { + # description clv2; + # } + - name: Override running SNMP server configuration with provided configuration + junipernetworks.junos.junos_snmp_server: + config: + contact: "ansiblesupport11@redhat.com" + customization: + ether_stats_ifd_only: true + description: "Local SNMP Server" + engine_id: + local: "local1" + use_default_ip_address: true + use_mac_address: true + filter_duplicates: true + filter_interfaces: + set: true + all_internal_interfaces: true + interfaces: + - "eth1" + - "eth2" + state: overridden + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": { + # "contact": "ansiblesupport11@redhat.com", + # "customization": { + # "ether_stats_ifd_only": true + # }, + # "description": "Local SNMP Server", + # "engine_id": { + # "use_mac_address": true + # }, + # "filter_duplicates": true, + # "filter_interfaces": { + # "all_internal_interfaces": true, + # "interfaces": [ + # "eth1", + # "eth2" + # ] + # } + # }, + # "before": + # { + # "arp": { + # "host_name_resolution": true + # }, + # "client_lists": [ + # { + # "addresses": [ + # { + # "address": "192.16.1.0/24" + # }, + # { + # "address": "192.16.2.0/24" + # }, + # { + # "address": "11.11.11.11/32", + # "restrict": true + # } + # ], + # "name": "cl1" + # }, + # { + # "addresses": [ + # { + # "address": "192.16.4.0/24" + # } + # ], + # "name": "cl2" + # } + # ], + # "routing_instance_access": { + # "access_lists": [ + # "clv1", + # "clv2" + # ] + # } + # }, + # "changed": true, + # "commands": [ + # "", + # "", + # "" + # "ansiblesupport11@redhat.com" + # "Local SNMP Server" + # "local1" + # "" + # "eth1eth2" + # "" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show routing-instances + # clv1 { + # description clv1; + # } + # clv2 { + # description clv2; + # } + # vagrant@vsrx# show snmp + # description "Local SNMP Server"; + # contact "ansiblesupport11@redhat.com"; + # filter-interfaces { + # interfaces { + # eth1; + # eth2; + # } + # all-internal-interfaces; + # } + # filter-duplicates; + # engine-id { + # use-mac-address; + # } + # customization { + # ether-stats-ifd-only; + # } + # + # Using deleted + # + # Before state + # ------------ + # + # vagrant@vsrx# show routing-instances + # clv1 { + # description clv1; + # } + # clv2 { + # description clv2; + # } + # vagrant@vsrx# show snmp + # description "Local SNMP Server"; + # contact "ansiblesupport11@redhat.com"; + # filter-interfaces { + # interfaces { + # eth1; + # eth2; + # } + # all-internal-interfaces; + # } + # filter-duplicates; + # engine-id { + # use-mac-address; + # } + # customization { + # ether-stats-ifd-only; + # } + # + - name: Delete running SNMP server configuration + junipernetworks.junos.junos_snmp_server: + config: + state: deleted + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": {}, + # "before": { + # "contact": "ansiblesupport11@redhat.com", + # "customization": { + # "ether_stats_ifd_only": true + # }, + # "description": "Local SNMP Server", + # "engine_id": { + # "use_mac_address": true + # }, + # "filter_duplicates": true, + # "filter_interfaces": { + # "all_internal_interfaces": true, + # "interfaces": [ + # "eth1", + # "eth2" + # ] + # } + # }, + # "changed": true, + # "commands": [ + # "", + # "" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show routing-instances + # clv1 { + # description clv1; + # } + # clv2 { + # description clv2; + # } + # vagrant@vsrx# show snmp + # description "Local SNMP Server"; + # contact "ansiblesupport11@redhat.com"; + # filter-interfaces { + # interfaces { + # eth1; + # eth2; + # } + # all-internal-interfaces; + # } + # filter-duplicates; + # engine-id { + # use-mac-address; + # } + # customization { + # ether-stats-ifd-only; + # } + # + - name: Gather running SNMP server configuration + junipernetworks.junos.junos_snmp_server: + state: gathered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "gathered": { + # "contact": "ansiblesupport11@redhat.com", + # "customization": { + # "ether_stats_ifd_only": true + # }, + # "description": "Local SNMP Server", + # "engine_id": { + # "use_mac_address": true + # }, + # "filter_duplicates": true, + # "filter_interfaces": { + # "all_internal_interfaces": true, + # "interfaces": [ + # "eth1", + # "eth2" + # ] + # } + # }, + # "changed": false, + # Using rendered + # + # Before state + # ------------ + # + - name: Render xml for provided facts. + junipernetworks.junos.junos_snmp_server: + config: + arp: + set: true + host_name_resolution: true + routing_instance_access: # ATTR-----3 + set: true + access_lists: + - "clv1" + - "clv2" + state: rendered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "rendered": [ + # "" + # "" + # "clv1clv2" + # "" + # ] + # + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # + # + # cl1 + # + # 192.16.1.0/24 + # + # + # 192.16.2.0/24 + # + # + # 11.11.11.11/32 + # + # + # + # + # cl2 + # + # 192.16.4.0/24 + # + # + # + # + # clv1 + # + # + # clv2 + # + # + # + # + # + # + # + # + # + # + - name: Parse SNMP server running config + junipernetworks.junos.junos_snmp_server: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # + # "parsed": { + # "arp": { + # "host_name_resolution": true + # }, + # "client_lists": [ + # { + # "addresses": [ + # { + # "address": "192.16.1.0/24" + # }, + # { + # "address": "192.16.2.0/24" + # }, + # { + # "address": "11.11.11.11/32", + # "restrict": true + # } + # ], + # "name": "cl1" + # }, + # { + # "addresses": [ + # { + # "address": "192.16.4.0/24" + # } + # ], + # "name": "cl2" + # } + # ], + # "routing_instance_access": { + # "access_lists": [ + # "clv1", + # "clv2" + # ] + # } + # } + # + # + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ dictionary +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:arp><nc:host-name-resolution/></nc:arp><nc:routing-instance-access>"', '<nc:snmp xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Rohit Thakur (@rohitthakur2590) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_static_routes_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_static_routes_module.rst new file mode 100644 index 00000000..9d275e41 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_static_routes_module.rst @@ -0,0 +1,714 @@ +.. _junipernetworks.junos.junos_static_routes_module: + + +***************************************** +junipernetworks.junos.junos_static_routes +***************************************** + +**Static routes resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module provides declarative management of static routes on Juniper JUNOS devices + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) +- xmltodict (>=0.12) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
A dictionary of static routes options
+
+
+ address_families + +
+ list + / elements=dictionary +
+
+ +
Address family to use for the static routes
+
+
+ afi + +
+ string + / required +
+
+
    Choices: +
  • ipv4
  • +
  • ipv6
  • +
+
+
afi to use for the static routes
+
+
+ routes + +
+ list + / elements=dictionary +
+
+ +
Static route configuration
+
+
+ dest + +
+ string +
+
+ +
Static route destination including prefix
+
+
+ metric + +
+ integer +
+
+ +
Metric value for the static route
+
+
+ next_hop + +
+ list + / elements=dictionary +
+
+ +
Next hop to destination
+
+
+ forward_router_address + +
+ string +
+
+ +
List of next hops
+
+
+ vrf + +
+ string +
+
+ +
Virtual Routing and Forwarding (VRF) name
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show routing-options.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • rendered
  • +
  • parsed
  • +
+
+
The state the configuration should be left in
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the device being managed. + - This module works with connection ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - Tested against JunOS v18.4R1 + + + +Examples +-------- + +.. code-block:: yaml + + # Using deleted + + # Before state + # ------------ + # + # admin# show routing-options + # static { + # route 192.168.47.0/24 next-hop 172.16.1.2; + # route 192.168.16.0/24 next-hop 172.16.1.2; + # } + + - name: Delete provided configuration (default operation is merge) + junipernetworks.junos.junos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.16.0/24 + next_hop: + - forward_router_address: 172.16.1.2 + state: deleted + + # Task Output + # ----------- + # before: + # - address_families: + # - afi: ipv4 + # routes: + # - dest: 192.168.47.0/24 + # next_hop: + # - forward_router_address: 172.16.1.2 + # - dest: 192.168.16.0/24 + # next_hop: + # - forward_router_address: 172.16.1.2 + # commands: + # - '192.168.16.0/24' + # - '' + # after: + # - address_families: + # - afi: ipv4 + # routes: + # - dest: 192.168.47.0/24 + # next_hop: + # - forward_router_address: 172.16.1.2 + + # After state: + # ------------ + # + # admin# show routing-options + # static { + # route 192.168.47.0/24 next-hop 172.16.1.2; + # } + + # Using merged + + # Before state + # ------------ + # + # admin# show routing-options + # static { + # route 192.168.47.0/24 next-hop 172.16.1.2; + # } + + - name: Merge provided configuration with device configuration (default operation + is merge) + junipernetworks.junos.junos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.16.0/24 + next_hop: + - forward_router_address: 172.16.1.2 + state: merged + + # Task Output + # ----------- + # before: + # - address_families: + # - afi: ipv4 + # routes: + # - dest: 192.168.47.0/24 + # next_hop: + # - forward_router_address: 172.16.1.2 + # commands: + # - '192.168.16.0/24 + # 172.16.1.2' + # - '' + # after: + # - address_families: + # - afi: ipv4 + # routes: + # - dest: 192.168.47.0/24 + # next_hop: + # - forward_router_address: 172.16.1.2 + # - dest: 192.168.16.0/24 + # next_hop: + # - forward_router_address: 172.16.1.2 + # After state: + # ------------ + # + # admin# show routing-options + # static { + # route 192.168.47.0/24 next-hop 172.16.1.2; + # route 192.168.16.0/24 next-hop 172.16.1.2; + # } + + # Using overridden + + # Before state + # ------------ + # + # admin# show routing-options + # static { + # route 192.168.47.0/24 next-hop 172.16.1.2; + # route 192.168.16.0/24 next-hop 172.16.1.2; + # } + + - name: Override running configuration with provided configuration (default operation + is merge) + junipernetworks.junos.junos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.16.0/24 + next_hop: + - forward_router_address: 172.16.0.1 + state: overridden + # Task Output: + # ------------ + # before: + # - address_families: + # - afi: ipv4 + # routes: + # - dest: 192.168.47.0/24 + # next_hop: + # - forward_router_address: 172.16.1.2 + # - dest: 192.168.16.0/24 + # next_hop: + # - forward_router_address: 172.16.1.2 + # commands: + # - >- + # 192.168.47.0/24192.168.16.0/24192.168.16.0/24172.16.0.1 + # - '' + # after: + # - address_families: + # - afi: ipv4 + # routes: + # - dest: 192.168.16.0/24 + # next_hop: + # - forward_router_address: 172.16.0.1 + + # After state: + # ------------ + # + # admin# show routing-options + # static { + # route 192.168.16.0/24 next-hop 172.16.0.1; + # } + + # Using replaced + + # Before state + # ------------ + # + # admin# show routing-options + # static { + # route 192.168.47.0/24 next-hop 172.16.1.2; + # route 192.168.16.0/24 next-hop 172.16.1.2; + # } + + - name: Replace provided configuration with device configuration (default operation + is merge) + junipernetworks.junos.junos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.47.0/24 + next_hop: + - forward_router_address: 10.200.16.2 + state: replaced + + # Task Output: + # ------------ + # before: + # - address_families: + # - afi: ipv4 + # routes: + # - dest: 192.168.47.0/24 + # next_hop: + # - forward_router_address: 172.16.1.2 + # - dest: 192.168.16.0/24 + # next_hop: + # - forward_router_address: 172.16.1.2 + # commands: + # - >- + # 192.168.47.0/24192.168.47.0/2410.200.16.2 + # - '' + # after: + # - address_families: + # - afi: ipv4 + # routes: + # - dest: 192.168.16.0/24 + # next_hop: + # - forward_router_address: 172.16.1.2 + # - dest: 192.168.47.0/24 + # next_hop: + # - forward_router_address: 10.200.16.2 + + # After state: + # ------------ + # + # admin# show routing-options + # static { + # route 192.168.47.0/24 next-hop 10.200.16.2; + # route 192.168.16.0/24 next-hop 172.16.1.2; + # } + + # Using gathered to gather static route facts from the device + # Before state + # ------------ + # admin# show routing-options + # static { + # route 192.168.16.0/24 next-hop 172.16.1.2; + # route 192.168.47.0/24 next-hop 10.200.16.2; + # } + - name: Gather static routes facts from the device using junos_static_routes module + junipernetworks.junos.junos_static_routes: + state: gathered + + # Task output: + # ------------ + # gathered: + # - address_families: + # - afi: ipv4 + # routes: + # - dest: 192.168.16.0/24 + # next_hop: + # - forward_router_address: 172.16.1.2 + # - dest: 192.168.47.0/24 + # next_hop: + # - forward_router_address: 10.200.16.2 + + # Using rendered + + - name: Render platform specific commands (without connecting to the device) + junipernetworks.junos.junos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.16.0/24 + next_hop: + - forward_router_address: 172.16.1.2 + state: rendered + + # Task output: + # ------------ + # rendered: + # - '192.168.16.0/24 + # 172.16.1.2' + + # Using parsed + + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # + # + # 192.168.16.0/24 + # 172.16.1.2 + # 172.16.1.3 + # + # + # 192.168.47.0/24 + # 10.200.16.2 + # + # + # + # + # + + - name: Parsed running config (without connecting to the device) + junipernetworks.junos.junos_static_routes: + running_config: "{{ lookup('file', 'parsed.cfg') }}" + state: parsed + + # Task output: + # ------------ + # parsed: + # - address_families: + # - afi: ipv4 + # routes: + # - dest: 192.168.16.0/24 + # next_hop: + # - forward_router_address: '[''172.16.1.2'', ''172.16.1.3'']' + # - dest: 192.168.47.0/24 + # next_hop: + # - forward_router_address: 10.200.16.2 + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ string +
+
when changed +
The resulting configuration model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ string +
+
always +
The configuration prior to the model invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['command 1', 'command 2', 'command 3']
+
+
+ gathered + +
+ list +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ list +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ list +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Daniel Mellado (@dmellado) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_system_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_system_module.rst new file mode 100644 index 00000000..c7cdaa0f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_system_module.rst @@ -0,0 +1,228 @@ +.. _junipernetworks.junos.junos_system_module: + + +********************************** +junipernetworks.junos.junos_system +********************************** + +**Manage the system attributes on Juniper JUNOS devices** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module provides declarative management of node system attributes on Juniper JUNOS devices. It provides an option to configure host system parameters or remove those parameters from the device active configuration. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.5.2) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ active + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes ←
  • +
+
+
Specifies whether or not the configuration is active or deactivated
+
+
+ domain_name + +
+ string +
+
+ +
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 hostname to create a fully-qualified domain name.
+
+
+ domain_search + +
+ list + / elements=string +
+
+ +
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.
+
+
+ hostname + +
+ string +
+
+ +
Configure the device hostname parameter. This option takes an ASCII string value.
+
+
+ name_servers + +
+ list + / elements=string +
+
+ +
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 + +
+ string +
+
+
    Choices: +
  • present ←
  • +
  • absent
  • +
+
+
State of the configuration values in the device's current active configuration. When set to present, the values should be configured in the device active configuration and when set to absent the values should not be in the device active configuration
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. + - Recommended connection is ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - This module also works with ``local`` connections for legacy playbooks. + - For information on using CLI and netconf see the :ref:`Junos OS Platform Options guide ` + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` + - For more information on using Ansible to manage Juniper network devices see https://www.ansible.com/ansible-juniper. + + + +Examples +-------- + +.. code-block:: yaml + + - name: configure hostname and domain name + junipernetworks.junos.junos_system: + hostname: junos01 + domain_name: test.example.com + domain-search: + - ansible.com + - redhat.com + - juniper.net + + - name: remove configuration + junipernetworks.junos.junos_system: + state: absent + + - name: configure name servers + junipernetworks.junos.junos_system: + name_servers: + - 8.8.8.8 + - 8.8.4.4 + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + +
KeyReturnedDescription
+
+ diff.prepared + +
+ string +
+
when configuration is changed and diff option is enabled. +
Configuration difference before and after applying change.
+
+
Sample:
+
[edit system] + host-name test; + domain-name ansible.com; + domain-search redhat.com; [edit system name-server] + 172.26.1.1 { ... } + + 8.8.8.8;
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ganesh Nalawade (@ganeshrn) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_user_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_user_module.rst new file mode 100644 index 00000000..256362cf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_user_module.rst @@ -0,0 +1,447 @@ +.. _junipernetworks.junos.junos_user_module: + + +******************************** +junipernetworks.junos.junos_user +******************************** + +**Manage local user accounts on Juniper JUNOS devices** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages locally configured user accounts on remote network devices running the JUNOS operating system. It provides a set of arguments for creating, removing and updating locally defined accounts + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.5.2) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ active + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes ←
  • +
+
+
Specifies whether or not the configuration is active or deactivated
+
+
+ aggregate + +
+ list + / elements=dictionary +
+
+ +
The aggregate argument defines a list of users to be configured on the remote device. The list of users will be compared against the current users and only changes will be added or removed from the device configuration. This argument is mutually exclusive with the name argument.
+

aliases: users, collection
+
+
+ active + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specifies whether or not the configuration is active or deactivated
+
+
+ encrypted_password + +
+ string +
+
+ +
The encrypted_password argument set already hashed password for the user account on the remote system.
+
+
+ full_name + +
+ string +
+
+ +
The full_name argument provides the full name of the user account to be created on the remote device. This argument accepts any text string value.
+
+
+ name + +
+ string + / required +
+
+ +
The name argument defines the username of the user to be created on the system. This argument must follow appropriate usernaming conventions for the target device running JUNOS. This argument is mutually exclusive with the aggregate argument.
+
+
+ purge + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
The purge argument instructs the module to consider the users definition absolute. It will remove any previously configured users on the device with the exception of the current defined set of aggregate.
+
+
+ role + +
+ string +
+
+
    Choices: +
  • operator
  • +
  • read-only
  • +
  • super-user
  • +
  • unauthorized
  • +
+
+
The role argument defines the role of the user account on the remote system. User accounts can have more than one role configured.
+
+
+ sshkey + +
+ string +
+
+ +
The sshkey argument defines the public SSH key to be configured for the user account on the remote system. This argument must be a valid SSH key
+
+
+ state + +
+ string +
+
+
    Choices: +
  • present
  • +
  • absent
  • +
+
+
The state argument configures the state of the user definitions as it relates to the device operational configuration. When set to present, the user should be configured in the device active configuration and when set to absent the user should not be in the device active configuration
+
+
+ encrypted_password + +
+ string +
+
+ +
The encrypted_password argument set already hashed password for the user account on the remote system.
+
+
+ full_name + +
+ string +
+
+ +
The full_name argument provides the full name of the user account to be created on the remote device. This argument accepts any text string value.
+
+
+ name + +
+ string +
+
+ +
The name argument defines the username of the user to be created on the system. This argument must follow appropriate usernaming conventions for the target device running JUNOS. This argument is mutually exclusive with the aggregate argument.
+
+
+ purge + +
+ boolean +
+
+
    Choices: +
  • no ←
  • +
  • yes
  • +
+
+
The purge argument instructs the module to consider the users definition absolute. It will remove any previously configured users on the device with the exception of the current defined set of aggregate.
+
+
+ role + +
+ string +
+
+
    Choices: +
  • operator
  • +
  • read-only
  • +
  • super-user
  • +
  • unauthorized
  • +
+
+
The role argument defines the role of the user account on the remote system. User accounts can have more than one role configured.
+
+
+ sshkey + +
+ string +
+
+ +
The sshkey argument defines the public SSH key to be configured for the user account on the remote system. This argument must be a valid SSH key
+
+
+ state + +
+ string +
+
+
    Choices: +
  • present ←
  • +
  • absent
  • +
+
+
The state argument configures the state of the user definitions as it relates to the device operational configuration. When set to present, the user should be configured in the device active configuration and when set to absent the user should not be in the device active configuration
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. + - Recommended connection is ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - This module also works with ``local`` connections for legacy playbooks. + - For information on using CLI and netconf see the :ref:`Junos OS Platform Options guide ` + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` + - For more information on using Ansible to manage Juniper network devices see https://www.ansible.com/ansible-juniper. + + + +Examples +-------- + +.. code-block:: yaml + + - name: create new user account + junipernetworks.junos.junos_user: + name: ansible + role: super-user + sshkey: "{{ lookup('file', '~/.ssh/ansible.pub') }}" + state: present + + - name: remove a user account + junipernetworks.junos.junos_user: + name: ansible + state: absent + + - name: remove all user accounts except ansible + junipernetworks.junos.junos_user: + aggregate: + - name: ansible + purge: true + + - name: set user password + junipernetworks.junos.junos_user: + name: ansible + role: super-user + encrypted_password: "{{ 'my-password' | password_hash('sha512') }}" + state: present + + - name: Create list of users + junipernetworks.junos.junos_user: + aggregate: + - {name: test_user1, full_name: test_user2, role: operator, state: present} + - {name: test_user2, full_name: test_user2, role: read-only, state: present} + + - name: Delete list of users + junipernetworks.junos.junos_user: + aggregate: + - {name: test_user1, full_name: test_user2, role: operator, state: absent} + - {name: test_user2, full_name: test_user2, role: read-only, state: absent} + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + +
KeyReturnedDescription
+
+ diff.prepared + +
+ string +
+
when configuration is changed and diff option is enabled. +
Configuration difference before and after applying change.
+
+
Sample:
+
[edit system login] + user test-user { + uid 2005; + class read-only; + }
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Peter Sprygada (@privateip) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_vlans_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_vlans_module.rst new file mode 100644 index 00000000..d8f934c7 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_vlans_module.rst @@ -0,0 +1,570 @@ +.. _junipernetworks.junos.junos_vlans_module: + + +********************************* +junipernetworks.junos.junos_vlans +********************************* + +**VLANs resource module** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module creates and manages VLAN configurations on Junos OS. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.6.4) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ list + / elements=dictionary +
+
+ +
A dictionary of Vlan options
+
+
+ description + +
+ string +
+
+ +
Text description of VLANs
+
+
+ l3_interface + +
+ string +
+
+ +
Name of logical layer 3 interface.
+
+
+ name + +
+ string + / required +
+
+ +
Name of VLAN.
+
+
+ vlan_id + +
+ integer +
+
+ +
IEEE 802.1q VLAN identifier for VLAN (1..4094).
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the Junos device by executing the command show vlans.
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • parsed
  • +
  • rendered
  • +
+
+
The state of the configuration after module completion.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed + - Tested against Junos OS 18.4R1 + - This module works with connection ``netconf``. + - See `the Junos OS Platform Options `_. + + + +Examples +-------- + +.. code-block:: yaml + + # Using merged + # + # Before state + # ------------ + # + # vagrant@vsrx# show vlans + # + # [edit] + + - name: Merge provided Junos vlans config with running-config + junipernetworks.junos.junos_vlans: + config: + - name: vlan1 + vlan_id: 1 + - name: vlan2 + vlan_id: 2 + l3_interface: irb.12 + state: merged + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": [ + # { + # "name": "vlan1", + # "vlan_id": 1 + # }, + # { + # "l3_interface": "irb.12", + # "name": "vlan2", + # "vlan_id": 2 + # } + # ], + # "before": [], + # "changed": true, + # "commands": [ + # "" + # "vlan11" + # "vlan22irb.12" + # "" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show vlans + # vlan1 { + # vlan-id 1; + # } + # vlan2 { + # vlan-id 2; + # l3-interface irb.12; + # } + + # Using replaced + # + # Before state + # ------------ + # + # vagrant@vsrx# show vlans + # vlan1 { + # vlan-id 1; + # } + # vlan2 { + # vlan-id 2; + # l3-interface irb.12; + # } + + - name: Replace Junos vlans running-config with the provided config + junipernetworks.junos.junos_vlans: + config: + - name: vlan1 + vlan_id: 11 + l3_interface: irb.10 + + - name: vlan2 + vlan_id: 2 + state: replaced + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": [ + # { + # "l3_interface": "irb.10", + # "name": "vlan1", + # "vlan_id": 11 + # }, + # { + # "name": "vlan2", + # "vlan_id": 2 + # } + # ], + # "before": [ + # { + # "name": "vlan1", + # "vlan_id": 1 + # }, + # { + # "l3_interface": "irb.12", + # "name": "vlan2", + # "vlan_id": 2 + # } + # ], + # "changed": true, + # "commands": [ + # "" + # "vlan1" + # "vlan2" + # "vlan111" + # "irb.10" + # "vlan22" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show vlans + # vlan1 { + # vlan-id 11; + # l3-interface irb.10; + # } + # vlan2 { + # vlan-id 2; + # } + # + # Using overridden + # + # Before state + # ------------ + # + # vagrant@vsrx# show vlans + # vlan1 { + # vlan-id 11; + # l3-interface irb.10; + # } + # vlan2 { + # vlan-id 2; + # } + - name: Override Junos running-config with provided config + junipernetworks.junos.junos_vlans: + config: + - name: vlan3 + vlan_id: 3 + l3_interface: irb.13 + state: overridden + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": [ + # { + # "l3_interface": "irb.13", + # "name": "vlan3", + # "vlan_id": 3 + # } + # ], + # "before": [ + # { + # "l3_interface": "irb.10", + # "name": "vlan1", + # "vlan_id": 11 + # }, + # { + # "name": "vlan2", + # "vlan_id": 2 + # } + # ], + # "changed": true, + # "commands": [ + # "" + # "vlan1" + # "vlan2vlan33" + # "irb.13" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show vlans + # vlan3 { + # vlan-id 3; + # l3-interface irb.13; + # } + # + # Using deleted + # + # Before state + # ------------ + # + # vagrant@vsrx# show vlans + # vlan3 { + # vlan-id 3; + # l3-interface irb.13; + # } + - name: Delete specific vlan + junipernetworks.junos.junos_vlans: + config: + - name: vlan3 + state: deleted + # ------------------------- + # Module Execution Result + # ------------------------- + # "after": [], + # "changed": true, + # "commands": [ + # " + # "vlan3" + # ] + # After state + # ----------- + # + # vagrant@vsrx# show vlans + # vlan1 { + # vlan-id 11; + # l3-interface irb.10; + # } + # vlan2 { + # vlan-id 2; + # } + + + - name: Gather running vlans configuration + junipernetworks.junos.junos_vlans: + state: gathered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "gathered": [ + # { + # "l3_interface": "irb.10", + # "name": "vlan1", + # "vlan_id": 11 + # }, + # { + # "name": "vlan2", + # "vlan_id": 2 + # } + # ], + # "changed": false, + # + # Using rendered + # + # Before state + # ------------ + # + - name: Render xml for provided facts. + junipernetworks.junos.junos_vlans: + config: + - name: vlan1 + vlan_id: 1 + + - name: vlan2 + vlan_id: 2 + l3_interface: irb.12 + state: rendered + # + # ------------------------- + # Module Execution Result + # ------------------------- + # "rendered": [ + # "" + # "vlan11" + # "vlan22irb.12" + # "" + # ] + # Using parsed + # parsed.cfg + # ------------ + # + # + # + # 18.4R1-S2.4 + # + # + # vlan1 + # 1 + # + # + # vlan2 + # 2 + # irb.12 + # + # + # + # + + - name: Parse routing instance running config + junipernetworks.junos.junos_vlans: + running_config: "{{ lookup('file', './parsed.cfg') }}" + state: parsed + # + # + # ------------------------- + # Module Execution Result + # ------------------------- + # + # + # "parsed": [ + # { + # "name": "vlan1", + # "vlan_id": 1 + # }, + # { + # "l3_interface": "irb.12", + # "name": "vlan2", + # "vlan_id": 2 + # } + # ] + # + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ list +
+
when changed +
The configuration as structured data after module completion.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ before + +
+ list +
+
always +
The configuration as structured data prior to module invocation.
+
+
Sample:
+
The configuration returned will always be in the same format + of the parameters above.
+
+
+ commands + +
+ list +
+
always +
The set of commands pushed to the remote device.
+
+
Sample:
+
['<nc:vlans xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <nc:vlan><nc:name>vlan1</nc:name><nc:vlan-id>1</nc:vlan-id> </nc:vlan><nc:vlan><nc:name>vlan2</nc:name><nc:vlan-id>2</nc:vlan-id> <nc:l3-interface>irb.12</nc:l3-interface></nc:vlan></nc:vlans>', 'xml 2', 'xml 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Daniel Mellado (@dmellado) diff --git a/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_vrf_module.rst b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_vrf_module.rst new file mode 100644 index 00000000..b3cbc3a0 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/docs/junipernetworks.junos.junos_vrf_module.rst @@ -0,0 +1,465 @@ +.. _junipernetworks.junos.junos_vrf_module: + + +******************************* +junipernetworks.junos.junos_vrf +******************************* + +**Manage the VRF definitions on Juniper JUNOS devices** + + +Version added: 1.0.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module provides declarative management of VRF definitions on Juniper JUNOS devices. It allows playbooks to manage individual or the entire VRF collection. + + + +Requirements +------------ +The below requirements are needed on the host that executes this module. + +- ncclient (>=v0.5.2) + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ active + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes ←
  • +
+
+
Specifies whether or not the configuration is active or deactivated
+
+
+ aggregate + +
+ list + / elements=dictionary +
+
+ +
The set of VRF definition objects to be configured on the remote JUNOS 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 name argument.
+
+
+ active + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Specifies whether or not the configuration is active or deactivated
+
+
+ description + +
+ string +
+
+ +
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.
+
+
+ interfaces + +
+ list + / elements=string +
+
+ +
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.
+
+
+ name + +
+ string + / required +
+
+ +
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 aggregate argument
+
+
+ rd + +
+ list + / elements=string +
+
+ +
The router-distinguisher value uniquely identifies the VRF to routing processes on the remote IOS system. The RD value takes the form of A:B where A and B are both numeric values.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • present
  • +
  • absent
  • +
+
+
Configures the state of the VRF definition as it relates to the device operational configuration. When set to present, the VRF should be configured in the device active configuration and when set to absent the VRF should not be in the device active configuration
+
+
+ table_label + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes
  • +
+
+
Causes JUNOS to allocate a VPN label per VRF rather than per VPN FEC. This allows for forwarding of traffic to directly connected subnets, COS Egress filtering etc.
+
+
+ target + +
+ list + / elements=string +
+
+ +
It configures VRF target community configuration. The target value takes the form of target:A:B where A and B are both numeric values.
+
+
+ description + +
+ string +
+
+ +
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.
+
+
+ interfaces + +
+ list + / elements=string +
+
+ +
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.
+
+
+ name + +
+ string +
+
+ +
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 aggregate argument
+
+
+ rd + +
+ list + / elements=string +
+
+ +
The router-distinguisher value uniquely identifies the VRF to routing processes on the remote IOS system. The RD value takes the form of A:B where A and B are both numeric values.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • present ←
  • +
  • absent
  • +
+
+
Configures the state of the VRF definition as it relates to the device operational configuration. When set to present, the VRF should be configured in the device active configuration and when set to absent the VRF should not be in the device active configuration
+
+
+ table_label + +
+ boolean +
+
+
    Choices: +
  • no
  • +
  • yes ←
  • +
+
+
Causes JUNOS to allocate a VPN label per VRF rather than per VPN FEC. This allows for forwarding of traffic to directly connected subnets, COS Egress filtering etc.
+
+
+ target + +
+ list + / elements=string +
+
+ +
It configures VRF target community configuration. The target value takes the form of target:A:B where A and B are both numeric values.
+
+
+ + +Notes +----- + +.. note:: + - This module requires the netconf system service be enabled on the remote device being managed. + - Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4. + - Recommended connection is ``netconf``. See `the Junos OS Platform Options <../network/user_guide/platform_junos.html>`_. + - This module also works with ``local`` connections for legacy playbooks. + - For information on using CLI and netconf see the :ref:`Junos OS Platform Options guide ` + - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide ` + - For more information on using Ansible to manage Juniper network devices see https://www.ansible.com/ansible-juniper. + + + +Examples +-------- + +.. code-block:: yaml + + - name: Configure vrf configuration + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + state: present + + - name: Remove vrf configuration + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + state: absent + + - name: Deactivate vrf configuration + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + active: false + + - name: Activate vrf configuration + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + active: true + + - name: Create vrf using aggregate + junipernetworks.junos.junos_vrf: + aggregate: + - name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + - name: test-2 + description: test-vrf-2 + interfaces: + - ge-0/0/4 + - ge-0/0/5 + rd: 192.0.2.2:10 + target: target:65515:114 + state: present + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + +
KeyReturnedDescription
+
+ diff.prepared + +
+ string +
+
when configuration is changed and diff option is enabled. +
Configuration difference before and after applying change.
+
+
Sample:
+
[edit routing-instances] + test-1 { + description test-vrf-1; + instance-type vrf; + interface ge-0/0/2.0; + interface ge-0/0/3.0; + route-distinguisher 192.0.2.1:10; + vrf-target target:65514:113; + }
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Ganesh Nalawade (@ganeshrn) diff --git a/ansible_collections/junipernetworks/junos/galaxy.yml b/ansible_collections/junipernetworks/junos/galaxy.yml new file mode 100644 index 00000000..6dc8be82 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/galaxy.yml @@ -0,0 +1,14 @@ +--- +authors: + - Ansible Network Community (ansible-network) +dependencies: + "ansible.netcommon": ">=6.1.0" +license_file: LICENSE +name: junos +namespace: junipernetworks +description: Ansible Network Collection for Junipernetworks Junos devices. +readme: README.md +repository: https://github.com/ansible-collections/junipernetworks.junos +issues: https://github.com/ansible-collections/junipernetworks.junos/issues +tags: [juniper, junipernetworks, junos, networking, security, netconf] +version: 9.1.0 diff --git a/ansible_collections/junipernetworks/junos/meta/runtime.yml b/ansible_collections/junipernetworks/junos/meta/runtime.yml new file mode 100644 index 00000000..83b1fe21 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/meta/runtime.yml @@ -0,0 +1,92 @@ +--- +requires_ansible: ">=2.15.0" +plugin_routing: + action: + junos_facts: + redirect: juniper.device.junos_facts + modules: + acl_interfaces: + redirect: juniper.device.junos_acl_interfaces + acls: + redirect: juniper.device.junos_acls + banner: + redirect: juniper.device.junos_banner + command: + redirect: juniper.device.junos_command + config: + redirect: juniper.device.junos_config + junos_facts: + redirect: juniper.device.facts + interfaces: + redirect: juniper.device.junos_interfaces + l2_interfaces: + redirect: juniper.device.junos_l2_interfaces + l3_interfaces: + redirect: juniper.device.junos_l3_interfaces + lacp: + redirect: juniper.device.junos.junos_lacp + lacp_interfaces: + redirect: juniper.device.junos_lacp_interfaces + lag_interfaces: + redirect: juniper.device.junos_lag_interfaces + lldp_global: + redirect: juniper.device.junos_lldp_global + bgp_global: + redirect: juniper.device.junos_bgp_global + bgp_address_family: + redirect: juniper.device.junos_bgp_address_family + routing_instances: + redirect: juniper.device.junos_routing_instances + prefix_lists: + redirect: juniper.device.junos_prefix_lists + logging_global: + redirect: juniper.device.junos_logging_global + ntp_global: + redirect: juniper.device.junos_ntp_global + security_policies: + redirect: juniper.device.junos_security_policies + security_policies_global: + redirect: juniper.device.junos_security_policies_global + security_zones: + redirect: juniper.device.junos_security_zones + snmp_server: + redirect: juniper.device.junos_snmp_server + hostname: + redirect: juniper.device.junos_hostname + routing_options: + redirect: juniper.device.junos_routing_options + lldp_interfaces: + redirect: juniper.device.junos_lldp_interfaces + netconf: + redirect: juniper.device.junos_netconf + ospfv2: + redirect: juniper.device.junos_ospfv2 + ospfv3: + redirect: juniper.device.junos_ospfv3 + ospf_interfaces: + redirect: juniper.device.junos_ospf_interfaces + package: + redirect: juniper.device.junos_package + ping: + redirect: juniper.device.junos_ping + rpc: + redirect: juniper.device.junos_rpc + scp: + redirect: juniper.device.junos_scp + deprecation: + removal_date: "2025-01-01" + warning_text: See the plugin documentation for more details + junos_scp: + deprecation: + removal_date: "2025-01-01" + warning_text: See the plugin documentation for more details + static_routes: + redirect: juniper.device.junos_static_routes + system: + redirect: juniper.device.junos_system + user: + redirect: juniper.device.junos_user + vlans: + redirect: juniper.device.junos_vlans + vrf: + redirect: juniper.device.junos_vrf diff --git a/ansible_collections/junipernetworks/junos/meta/runtime.yml_bkp b/ansible_collections/junipernetworks/junos/meta/runtime.yml_bkp new file mode 100644 index 00000000..36570f39 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/meta/runtime.yml_bkp @@ -0,0 +1,89 @@ +--- +requires_ansible: ">=2.15.0" +plugin_routing: + modules: + acl_interfaces: + redirect: junipernetworks.junos.junos_acl_interfaces + acls: + redirect: junipernetworks.junos.junos_acls + banner: + redirect: junipernetworks.junos.junos_banner + command: + redirect: junipernetworks.junos.junos_command + config: + redirect: junipernetworks.junos.junos_config + facts: + redirect: junipernetworks.junos.junos_facts + interfaces: + redirect: junipernetworks.junos.junos_interfaces + l2_interfaces: + redirect: junipernetworks.junos.junos_l2_interfaces + l3_interfaces: + redirect: junipernetworks.junos.junos_l3_interfaces + lacp: + redirect: junipernetworks.junos.junos_lacp + lacp_interfaces: + redirect: junipernetworks.junos.junos_lacp_interfaces + lag_interfaces: + redirect: junipernetworks.junos.junos_lag_interfaces + lldp_global: + redirect: junipernetworks.junos.junos_lldp_global + bgp_global: + redirect: junipernetworks.junos.junos_bgp_global + bgp_address_family: + redirect: junipernetworks.junos.junos_bgp_address_family + routing_instances: + redirect: junipernetworks.junos.junos_routing_instances + prefix_lists: + redirect: junipernetworks.junos.junos_prefix_lists + logging_global: + redirect: junipernetworks.junos.junos_logging_global + ntp_global: + redirect: junipernetworks.junos.junos_ntp_global + security_policies: + redirect: junipernetworks.junos.junos_security_policies + security_policies_global: + redirect: junipernetworks.junos.junos_security_policies_global + security_zones: + redirect: junipernetworks.junos.junos_security_zones + snmp_server: + redirect: junipernetworks.junos.junos_snmp_server + hostname: + redirect: junipernetworks.junos.junos_hostname + routing_options: + redirect: junipernetworks.junos.junos_routing_options + lldp_interfaces: + redirect: junipernetworks.junos.junos_lldp_interfaces + netconf: + redirect: junipernetworks.junos.junos_netconf + ospfv2: + redirect: junipernetworks.junos.junos_ospfv2 + ospfv3: + redirect: junipernetworks.junos.junos_ospfv3 + ospf_interfaces: + redirect: junipernetworks.junos.junos_ospf_interfaces + package: + redirect: junipernetworks.junos.junos_package + ping: + redirect: junipernetworks.junos.junos_ping + rpc: + redirect: junipernetworks.junos.junos_rpc + scp: + redirect: junipernetworks.junos.junos_scp + deprecation: + removal_date: "2025-01-01" + warning_text: See the plugin documentation for more details + junos_scp: + deprecation: + removal_date: "2025-01-01" + warning_text: See the plugin documentation for more details + static_routes: + redirect: junipernetworks.junos.junos_static_routes + system: + redirect: junipernetworks.junos.junos_system + user: + redirect: junipernetworks.junos.junos_user + vlans: + redirect: junipernetworks.junos.junos_vlans + vrf: + redirect: junipernetworks.junos.junos_vrf diff --git a/ansible_collections/junipernetworks/junos/pyproject.toml b/ansible_collections/junipernetworks/junos/pyproject.toml new file mode 100644 index 00000000..fa4225f3 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/pyproject.toml @@ -0,0 +1,7 @@ +[tool.black] +line-length = 100 + +[tool.pytest.ini_options] +addopts = ["-vvv", "-n", "2", "--log-level", "WARNING", "--color", "yes"] +testpaths = ["tests"] +filterwarnings = ['ignore:AnsibleCollectionFinder has already been configured'] diff --git a/ansible_collections/junipernetworks/junos/requirements.txt b/ansible_collections/junipernetworks/junos/requirements.txt new file mode 100644 index 00000000..a53c179d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/requirements.txt @@ -0,0 +1,6 @@ +jxmlease +ncclient +paramiko +scp +xmltodict +ansible-pylibssh diff --git a/ansible_collections/junipernetworks/junos/test-requirements.txt b/ansible_collections/junipernetworks/junos/test-requirements.txt new file mode 100644 index 00000000..396789ae --- /dev/null +++ b/ansible_collections/junipernetworks/junos/test-requirements.txt @@ -0,0 +1,7 @@ +# For CML +virl2-client==2.6.1 + +# Unit test runner +pytest-ansible +pytest-xdist +pytest-cov diff --git a/ansible_collections/junipernetworks/junos/tests/.gitignore b/ansible_collections/junipernetworks/junos/tests/.gitignore new file mode 100644 index 00000000..ea1472ec --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/.gitignore @@ -0,0 +1 @@ +output/ diff --git a/ansible_collections/junipernetworks/junos/tests/config.yml b/ansible_collections/junipernetworks/junos/tests/config.yml new file mode 100644 index 00000000..c26ea596 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/config.yml @@ -0,0 +1,3 @@ +--- +modules: + python_requires: ">=3.9" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/target-prefixes.network b/ansible_collections/junipernetworks/junos/tests/integration/target-prefixes.network new file mode 100644 index 00000000..738c4ab4 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/target-prefixes.network @@ -0,0 +1 @@ +junos diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/meta/main.yaml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tasks/main.yaml new file mode 100644 index 00000000..d308b6d1 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Execute netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - "netconf" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..63ac8f93 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/_initial_config.yaml @@ -0,0 +1,20 @@ +--- +- name: Debug + ansible.builtin.debug: + msg: "START junipernetworks.junos.junos_acl_interfaces ACL interfaces initial config on connection={{ ansible_connection }}" + +- name: Set initial state for firewalls and interfaces + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: initial_acl + direction: in + - name: second_acl + direction: out + +- name: Debug + ansible.builtin.debug: + msg: "END junipernetworks.junos.junos_acl_interfaces ACL interfaces initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..12fce836 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/_reset_config.yaml @@ -0,0 +1,18 @@ +--- +- name: Debug + ansible.builtin.debug: + msg: "START junipernetworks.junos.junos_acl_interfaces reset ACL and ACL interfaces config on connection={{ ansible_connection }}" + +- name: Set initial state for firewalls and interfaces + junipernetworks.junos.junos_config: + lines: + - delete firewall + - set firewall family inet filter initial_acl term ten_dot from source-port bgp protocol tcp source-address 10.0.0.0/8 + - set firewall family inet filter initial_acl term eleven_dot from source-port bgp protocol tcp source-address 11.0.0.0/8 + - set firewall family inet filter second_acl term twelve_dot from source-port bgp protocol tcp source-address 12.0.0.0/8 + - "delete interfaces ge-1/0/0" + - "delete interfaces ge-2/0/0" + +- name: Debug + ansible.builtin.debug: + msg: "END junipernetworks.junos.junos_acl_interfaces reset ACL and ACL interfaces config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/deleted.yaml new file mode 100644 index 00000000..2915e007 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/deleted.yaml @@ -0,0 +1,64 @@ +--- +- name: Debug + ansible.builtin.debug: + msg: "START junipernetworks.junos.junos_acl_interfaces deleted integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Invoke initial config + ansible.builtin.include_tasks: _initial_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: initial_acl + direction: in + + - name: Delete a single ACL + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: second_acl + direction: out + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: &changed + that: + - result.changed == True + - "{{ config|symmetric_difference(result.after) == [] }}" + + - name: Set facts + ansible.builtin.set_fact: + config: [] + + - name: Delete all ACLs from the device + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: *changed + + tags: deleted + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug + ansible.builtin.debug: + msg: "END junipernetworks.junos.junos_acl_interfaces deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..204b3b7b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/empty_config.yaml @@ -0,0 +1,55 @@ +--- +- name: Debug + ansible.builtin.debug: + msg: + START junipernetworks.junos.junos_acl_interfaces empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_acl_interfaces: + config: + state: merged + +- name: Assert result + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_acl_interfaces: + config: + state: replaced + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_acl_interfaces: + running_config: + state: parsed + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_acl_interfaces: + config: + state: rendered + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/gathered.yaml new file mode 100644 index 00000000..79fbac2f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/gathered.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: START junos_acl_interfaces gathered integration tests on connection={{ ansible_connection }} + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + expected_gathered_config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: second_acl + direction: in + - name: initial_acl + direction: out + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: second_acl + direction: in + - name: initial_acl + direction: out + state: merged + register: result + + - name: Gather security policies facts using gathered state + register: result + junipernetworks.junos.junos_acl_interfaces: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ result['gathered'] == expected_gathered_config }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_acl_interfaces gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/merged.yaml new file mode 100644 index 00000000..d6a0a353 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/merged.yaml @@ -0,0 +1,58 @@ +--- +- name: Debug + ansible.builtin.debug: + msg: "START junipernetworks.junos.junos_acl_interfaces merged integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: second_acl + direction: in + - name: initial_acl + direction: out + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_acl_interfaces: &merged + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: second_acl + direction: in + - name: initial_acl + direction: out + state: merged + register: result + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config|symmetric_difference(result.after) == [] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_acl_interfaces: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: merged + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junipernetworks.junos.junos_acl_interfaces merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/overridden.yaml new file mode 100644 index 00000000..ea1c6a1c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/overridden.yaml @@ -0,0 +1,51 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junipernetworks.junos.junos_acl_interfaces overridden integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Initial configuration + ansible.builtin.include_tasks: _initial_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: initial_acl + direction: in + + - name: Override configuration of ACL + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: initial_acl + direction: in + state: overridden + register: result + + - name: Assert changed + ansible.builtin.assert: &changed + that: + - result.changed == True + - "{{ config|symmetric_difference(result.after) == [] }}" + + - name: Assert changed + ansible.builtin.assert: *changed + + tags: overridden + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junipernetworks.junos.junos_acl_interfaces overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/replaced.yaml new file mode 100644 index 00000000..2d63c95d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acl_interfaces/tests/netconf/replaced.yaml @@ -0,0 +1,51 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junipernetworks.junos.junos_acl_interfaces replaced integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Initial configuration + ansible.builtin.include_tasks: _initial_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: initial_acl + direction: in + - name: second_acl + direction: out + - name: initial_acl + direction: out + + - name: Replace configuration of ACL + junipernetworks.junos.junos_acl_interfaces: + config: + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: initial_acl + direction: out + state: replaced + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - "{{ config|symmetric_difference(result.after) == [] }}" + + tags: replaced + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junipernetworks.junos.junos_acl_interfaces replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/meta/main.yaml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tasks/main.yaml new file mode 100644 index 00000000..7b18bda9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tasks/main.yaml @@ -0,0 +1,4 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: ["netconf"] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..436b450a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/_reset_config.yaml @@ -0,0 +1,19 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_acls reset ACL config on connection={{ ansible_connection }}" + +- name: Set initial state + junipernetworks.junos.junos_config: + lines: + - delete firewall + - set firewall family inet filter initial_acl term ten_dot from source-port bgp protocol tcp source-address 10.0.0.0/8 + - set firewall family inet filter initial_acl term eleven_dot from source-port bgp protocol tcp source-address 11.0.0.0/8 + - set firewall family inet filter second_acl term twelve_dot from source-port bgp protocol tcp source-address 12.0.0.0/8 + - set firewall family inet filter third_acl term thirteen_dot from source-port bgp protocol tcp source-address 13.0.0.0/16 + - set firewall family inet filter third_acl term thirteen_dot from source-port bgp protocol tcp source-address 13.1.0.0/16 + - "set firewall family inet6 filter initial_acl6 term colon_eleven from source-port 631 source-address ::11" + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_acls reset ACL config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/config_policy.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/config_policy.yaml new file mode 100644 index 00000000..c425425c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/config_policy.yaml @@ -0,0 +1,14 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_acls preconfig policy options config on connection={{ ansible_connection }}" + +- name: Set policy config + junipernetworks.junos.junos_config: + lines: + - set policy-options prefix-list ospf-all-routers + - set policy-options prefix-list ipv4-interfaces + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_acls preconfig policy options config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/deleted.yaml new file mode 100644 index 00000000..e44d3728 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/deleted.yaml @@ -0,0 +1,166 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_acls deleted integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset config + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + config: + - acls: + - aces: + - name: ten_dot + source: + address: 10.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + name: initial_acl + - aces: + - name: twelve_dot + source: + address: 12.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + name: second_acl + - aces: + - name: thirteen_dot + source: + address: + - 13.0.0.0/16 + - 13.1.0.0/16 + port_protocol: + eq: bgp + protocol: tcp + name: third_acl + afi: ipv4 + - acls: + - aces: + - name: colon_eleven + source: + address: ::11/128 + port_protocol: + eq: "631" + name: initial_acl6 + afi: ipv6 + + - name: Delete a single ACE + junipernetworks.junos.junos_acls: + config: + - afi: ipv4 + acls: + - name: initial_acl + aces: + - name: eleven_dot + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: &changed + that: + - result.changed == True + - "{{ config|symmetric_difference(result.after) == [] }}" + + - name: Set facts + ansible.builtin.set_fact: + config: + - acls: + - aces: + - name: ten_dot + source: + address: 10.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + name: initial_acl + - aces: + - name: thirteen_dot + source: + address: + - 13.0.0.0/16 + - 13.1.0.0/16 + port_protocol: + eq: bgp + protocol: tcp + name: third_acl + afi: ipv4 + - acls: + - aces: + - name: colon_eleven + source: + address: ::11/128 + port_protocol: + eq: "631" + name: initial_acl6 + afi: ipv6 + + - name: Delete a whole ACL + junipernetworks.junos.junos_acls: + config: + - afi: ipv4 + acls: + - name: second_acl + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: *changed + + - name: Set facts + ansible.builtin.set_fact: + config: + - acls: + - aces: + - name: ten_dot + source: + address: 10.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + name: initial_acl + - aces: + - name: thirteen_dot + source: + address: + - 13.0.0.0/16 + - 13.1.0.0/16 + port_protocol: + eq: bgp + protocol: tcp + name: third_acl + afi: ipv4 + + - name: Delete all ACLs under one AFI + junipernetworks.junos.junos_acls: + config: + - afi: ipv6 + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: *changed + + - name: Set facts + ansible.builtin.set_fact: + config: [] + + - name: Delete all ACLs from the device + junipernetworks.junos.junos_acls: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: *changed + + tags: deleted + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_acls deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..99878acf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/empty_config.yaml @@ -0,0 +1,66 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START junos_acls empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_acls: + config: + state: merged + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_acls: + config: + state: replaced + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_acls: + config: + state: overridden + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_acls: + running_config: + state: parsed + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_acls: + config: + state: rendered + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..c5e52190 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,45 @@ + + + + 18.4R1-S2.4 + + + + + from-cisco + + 1 + + + 10.0.0.0/8 + + + 11.0.0.0/8 + + 1000 + + udp + vrrp + 100 + who + radius + + + icmp_deny + + + + + + 2 + + radius + + + + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/gathered.yaml new file mode 100644 index 00000000..207b79f7 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/gathered.yaml @@ -0,0 +1,100 @@ +--- +- ansible.builtin.debug: + msg: "START junos_acls gathered integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.include_tasks: config_policy.yaml + + - ansible.builtin.set_fact: + expected_gathered_output: + - acls: + - aces: + - name: ten_dot + source: + address: 10.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + - name: eleven_dot + source: + address: 11.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + name: initial_acl + - aces: + - name: twelve_dot + source: + address: 12.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + name: second_acl + - aces: + - name: thirteen_dot + source: + address: + - 13.0.0.0/16 + - 13.1.0.0/16 + port_protocol: + eq: bgp + protocol: tcp + name: third_acl + - aces: + - name: ssh_rule + source: + prefix_list: + - name: "ipv4-interfaces" + - name: "ospf-all-routers" + port_protocol: + eq: ssh + protocol: tcp + name: allow_ssh_acl + afi: ipv4 + - acls: + - aces: + - name: colon_eleven + source: + address: ::11/128 + port_protocol: + eq: "631" + name: initial_acl6 + afi: ipv6 + + - name: Merge the provided configuration with the existing running configuration + junipernetworks.junos.junos_acls: + config: + - afi: ipv4 + acls: + - name: allow_ssh_acl + aces: + - name: ssh_rule + source: + prefix_list: + - name: "ipv4-interfaces" + - name: "ospf-all-routers" + port_protocol: + eq: ssh + protocol: tcp + state: merged + + - name: Gather Junos Acls facts using gathered state + register: result + junipernetworks.junos.junos_acls: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ expected_gathered_output == result['gathered'] }}" + register: result + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.include_tasks: reset_policy_config.yaml + +- ansible.builtin.debug: + msg: "END junos_acls gathered integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/idempotent.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/idempotent.yaml new file mode 100644 index 00000000..e944f5de --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/idempotent.yaml @@ -0,0 +1,79 @@ +--- +- ansible.builtin.debug: + msg: "START junos_acls idempotence integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.set_fact: + config: + - acls: + - aces: + - name: ten_dot + source: + address: 10.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + - name: eleven_dot + source: + address: 11.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + name: initial_acl + - aces: + - name: twelve_dot + source: + address: 12.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + name: second_acl + - aces: + - name: thirteen_dot + source: + address: + - 13.0.0.0/16 + - 13.1.0.0/16 + port_protocol: + eq: bgp + protocol: tcp + name: third_acl + afi: ipv4 + - acls: + - aces: + - name: colon_eleven + source: + address: ::11/128 + port_protocol: + eq: 631 + name: initial_acl6 + afi: ipv6 + + - name: Test equivalence + junipernetworks.junos.junos_acls: + config: "{{ config }}" + state: merged + register: result + + - ansible.builtin.assert: + that: + - result.changed == False + + - name: Test idempotence + junipernetworks.junos.junos_acls: + config: "{{ config }}" + state: overridden + register: result + + - ansible.builtin.assert: + that: + - result.changed == False + + tags: idempotence + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_acls idempotence integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/merged.yaml new file mode 100644 index 00000000..4f360ead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/merged.yaml @@ -0,0 +1,106 @@ +--- +- ansible.builtin.debug: + msg: "START junos_acls merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.include_tasks: config_policy.yaml + + - ansible.builtin.set_fact: + config: + - acls: + - aces: + - name: ten_dot + source: + address: 10.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + - name: eleven_dot + source: + address: 11.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + name: initial_acl + - aces: + - name: twelve_dot + source: + address: 12.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + name: second_acl + - aces: + - name: thirteen_dot + source: + address: + - 13.0.0.0/16 + - 13.1.0.0/16 + port_protocol: + eq: bgp + protocol: tcp + name: third_acl + - aces: + - name: ssh_rule + source: + prefix_list: + - name: "ipv4-interfaces" + - name: "ospf-all-routers" + port_protocol: + eq: ssh + protocol: tcp + name: allow_ssh_acl + afi: ipv4 + - acls: + - aces: + - name: colon_eleven + source: + address: ::11/128 + port_protocol: + eq: "631" + name: initial_acl6 + afi: ipv6 + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_acls: &merged + config: + - afi: ipv4 + acls: + - name: allow_ssh_acl + aces: + - name: ssh_rule + source: + prefix_list: + - name: "ipv4-interfaces" + - name: "ospf-all-routers" + port_protocol: + eq: ssh + protocol: tcp + state: merged + register: result + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config|symmetric_difference(result.after) == [] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_acls: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.include_tasks: reset_policy_config.yaml + +- ansible.builtin.debug: + msg: "END junos_acls merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/overridden.yaml new file mode 100644 index 00000000..6de41d2e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/overridden.yaml @@ -0,0 +1,49 @@ +--- +- ansible.builtin.debug: + msg: "START junos_acls overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.set_fact: + config: + - acls: + - aces: + - name: ace_10 + grant: deny + protocol: tcp + name: acl_1 + - aces: + - name: ace_20 + grant: deny + protocol: udp + name: acl_2 + afi: ipv4 + + - name: Override the entire running configuration with the provided configuration + junipernetworks.junos.junos_acls: &overridden + config: "{{ config }}" + state: overridden + register: result + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config|symmetric_difference(result.after) == [] }}" + + - name: Override the entire running configuration with the provided configuration (IDEMPOTENT) + junipernetworks.junos.junos_acls: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_acls overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/parsed.yaml new file mode 100644 index 00000000..bd55e13a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/parsed.yaml @@ -0,0 +1,44 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: + START junos_acls parsed integration tests on connection={{ ansible_connection + }} + +- name: Set facts + ansible.builtin.set_fact: + expected_parsed_output: + - acls: + - aces: + - destination: + address: "11.0.0.0/8" + port_protocol: + eq: "['who', 'radius']" + name: "1" + protocol: "['udp', 'vrrp']" + source: + address: "10.0.0.0/8" + - destination: + port_protocol: + eq: "radius" + name: "2" + name: "from-cisco" + afi: ipv4 + +- name: Parse externally provided acls config to agnostic model + register: result + junipernetworks.junos.junos_acls: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output | symmetric_difference(result['parsed']) |length ==\ + \ 0 }}" + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_acls parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/rendered.yaml new file mode 100644 index 00000000..1dae9de3 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/rendered.yaml @@ -0,0 +1,35 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START junos_acls rendered integration tests on connection={{ + ansible_connection }} + +- name: Set facts + ansible.builtin.set_fact: + expected_rendered_output: 'initial_aclten_dot10.0.0.0/8bgptcp' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_acls: + config: + - acls: + - aces: + - name: ten_dot + source: + address: 10.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + name: initial_acl + afi: ipv4 + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- name: Debug task + ansible.builtin.debug: + msg: END junos_acls rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/replaced.yaml new file mode 100644 index 00000000..679dccd2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/replaced.yaml @@ -0,0 +1,105 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_acls replaced integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + config: + - acls: + - aces: + - name: ten_dot + source: + address: 10.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + - name: eleven_dot + source: + address: 11.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + name: initial_acl + - aces: + - name: twelve_dot + source: + address: 12.0.0.0/8 + port_protocol: + eq: bgp + protocol: tcp + - name: ace_20 + grant: permit + protocol: igmp + source: + address: 192.168.1.100/32 + - name: ace_21 + grant: permit + protocol: tcp + name: second_acl + - aces: + - name: thirteen_dot + source: + address: + - 13.0.0.0/16 + - 13.1.0.0/16 + port_protocol: + eq: bgp + protocol: tcp + name: third_acl + afi: ipv4 + - acls: + - aces: + - name: colon_eleven + source: + address: ::11/128 + port_protocol: + eq: "631" + name: initial_acl6 + afi: ipv6 + + - name: Replace the specified ACL with given config + junipernetworks.junos.junos_acls: &replaced + config: + - afi: ipv4 + acls: + - name: second_acl + aces: + - name: ace_20 + grant: permit + protocol: igmp + source: + address: 192.168.1.100 + - name: ace_21 + grant: permit + protocol: tcp + state: replaced + register: result + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config|symmetric_difference(result.after) == [] }}" + + - name: Replace the specified ACL with given config (IDEMPOTENT) + junipernetworks.junos.junos_acls: *replaced + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: replaced + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_acls replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/reset_policy_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/reset_policy_config.yaml new file mode 100644 index 00000000..82c89c15 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_acls/tests/netconf/reset_policy_config.yaml @@ -0,0 +1,16 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_acls reset policy options config on connection={{ ansible_connection }}" + +- name: Reset policy options config + junipernetworks.junos.junos_config: + lines: + - delete firewall family inet filter PROTECT-RE term allow-ospf from source-prefix-list ipv4-interfaces + - delete firewall family inet filter PROTECT-RE term allow-ospf from source-prefix-list ospf-all-routers + - delete policy-options prefix-list ospf-all-routers + - delete policy-options prefix-list ipv4-interfaces + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_acls reset policy options config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/defaults/main.yaml new file mode 100644 index 00000000..9ef5ba51 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/tasks/main.yaml new file mode 100644 index 00000000..ac951c8f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/tasks/main.yaml @@ -0,0 +1,3 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/tasks/netconf.yaml new file mode 100644 index 00000000..824d3b00 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/tasks/netconf.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/tests/netconf/basic.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/tests/netconf/basic.yaml new file mode 100644 index 00000000..f1205566 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_banner/tests/netconf/basic.yaml @@ -0,0 +1,205 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START junos_banner netconf/basic.yaml on connection={{ ansible_connection + }}" + +- name: Setup - remove login banner + junipernetworks.junos.junos_banner: + banner: login + state: absent + +- name: Create login banner + register: result + junipernetworks.junos.junos_banner: + banner: login + text: this is my login banner + state: present + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == true + - "'this is my login banner' in config.xml" + +- name: Create login banner (idempotent) + register: result + junipernetworks.junos.junos_banner: + banner: login + text: this is my login banner + state: present + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + +- name: Deactivate login banner + register: result + junipernetworks.junos.junos_banner: + banner: login + text: this is my login banner + state: present + active: false + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == true + - '''this is my login banner'' in config.xml' + +- name: Activate login banner + register: result + junipernetworks.junos.junos_banner: + banner: login + text: this is my login banner + state: present + active: true + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == true + - "'this is my login banner' in config.xml" + +- name: check mode + register: result + check_mode: true + junipernetworks.junos.junos_banner: + banner: login + text: this is not the login banner you're looking for + state: present + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == true + - result.failed == false + +- name: Delete login banner + register: result + junipernetworks.junos.junos_banner: + banner: login + state: absent + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == true + - "'this is my login banner' not in config.xml" + +- name: Setup - remove motd banner + junipernetworks.junos.junos_banner: + banner: motd + state: absent + +- name: Create motd banner + register: result + junipernetworks.junos.junos_banner: + banner: motd + text: this is my motd banner + state: present + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == true + - "'this is my motd banner' in config.xml" + +- name: Create motd banner (idempotent) + register: result + junipernetworks.junos.junos_banner: + banner: motd + text: this is my motd banner + state: present + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + +- name: Deactivate motd banner + register: result + junipernetworks.junos.junos_banner: + banner: motd + text: this is my motd banner + state: present + active: false + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == true + - "'this is my motd banner'\ + \ in config.xml" + +- name: Activate motd banner + register: result + junipernetworks.junos.junos_banner: + banner: motd + text: this is my motd banner + state: present + active: true + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == true + - "'this is my motd banner' in config.xml" + +- name: Delete motd banner + register: result + junipernetworks.junos.junos_banner: + banner: motd + state: absent + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == true + - "'this is my motd banner' not in config.xml" + +- name: Debug task + ansible.builtin.debug: + msg="END junos_banner netconf/basic.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..18a11dd7 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/_reset_config.yaml @@ -0,0 +1,13 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_bgp_address_family reset config on connection={{ ansible_connection }}" + +- name: Reset the config releavent to bgp address family resource + junipernetworks.junos.junos_config: + lines: + - delete protocols bgp family + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_bgp_address_family reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/deleted.yaml new file mode 100644 index 00000000..2bca3aea --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/deleted.yaml @@ -0,0 +1,136 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_bgp_address_family deleted integration tests on connection={{ ansible_connection }}" + +- block: + - name: Initial configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + expected_deleted_output: + address_family: + - afi: "evpn" + af_type: + - type: "signaling" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_bgp_address_family: &merged + config: + address_family: + - afi: "evpn" + af_type: + - type: "signaling" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + - afi: "inet" + af_type: + - type: "flow" + legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + + - type: "unicast" + extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: "9.9.9.9" + + - type: "labeled-unicast" + entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_prefix_label: true + per_group_label: true + prefix_limit: + maximum: 20 + limit_threshold: 99 + forever: true + resolve_vpn: true + rib: "inet.3" + route_refresh_priority_priority: 3 + + - type: "any" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 99 + idle_timeout_value: 2000 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: "from-fib" + state: merged + + - name: Delete existing configuration with running configuration + junipernetworks.junos.junos_bgp_address_family: &deleted + config: + address_family: + - afi: "inet" + state: deleted + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_deleted_output == result.after }}" + + - name: Delete the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_bgp_address_family: *deleted + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - name: Set facts + ansible.builtin.set_fact: + expected_deleted_res_output: {} + + - name: Merge the existing config with provided configuration + junipernetworks.junos.junos_bgp_address_family: *merged + register: result + + - name: Delete complete existing bgp address family configuration + junipernetworks.junos.junos_bgp_address_family: &deleted_res + config: + state: deleted + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_deleted_res_output == result.after }}" + + tags: deleted + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_bgp_address_family deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..64f38991 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/empty_config.yaml @@ -0,0 +1,70 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: + START junos_bgp_address_family empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_address_family: + config: + state: merged + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_address_family: + config: + state: replaced + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Override with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_address_family: + config: + state: overridden + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_address_family: + running_config: + state: parsed + +- name: Debug task + ansible.builtin.debug: + msg: result + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_address_family: + config: + state: rendered + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..bb0b56fc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,120 @@ + + + + 18.4R1-S2.4 + + + 2 + 5 + + 10 + + + + 9.9.9.9 + + + + + + 4 + + + + + + + + + + + + + + 20 + + 99 + + 2000 + + + + + + + 23000 + 32000 + + + 20 + 32000 + + + + 2 + + + from-fib + + + + + 20 + + 99 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/gathered.yaml new file mode 100644 index 00000000..023c1801 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/gathered.yaml @@ -0,0 +1,149 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START junos_bgp_address_family gathered integration tests on connection={{ ansible_connection }} + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + expected_gathered_output: + address_family: + - af_type: + - accepted_prefix_limit: + idle_timeout_value: 2001 + limit_threshold: 98 + maximum: 20 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + type: "signaling" + afi: "evpn" + + - af_type: + - accepted_prefix_limit: + idle_timeout_value: 2000 + limit_threshold: 99 + maximum: 20 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: "from-fib" + type: "any" + + - legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + type: "flow" + + - entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_group_label: true + per_prefix_label: true + prefix_limit: + forever: true + limit_threshold: 99 + maximum: 20 + resolve_vpn: true + rib: "inet.3" + route_refresh_priority_priority: 3 + type: "labeled-unicast" + + - extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: "9.9.9.9" + type: "unicast" + afi: "inet" + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_bgp_address_family: &merged + config: + address_family: + - afi: "evpn" + af_type: + - type: "signaling" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + - afi: "inet" + af_type: + - type: "flow" + legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + + - type: "unicast" + extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: "9.9.9.9" + + - type: "labeled-unicast" + entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_prefix_label: true + per_group_label: true + prefix_limit: + maximum: 20 + limit_threshold: 99 + forever: true + resolve_vpn: true + rib: "inet.3" + route_refresh_priority_priority: 3 + + - type: "any" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 99 + idle_timeout_value: 2000 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: "from-fib" + state: merged + + - name: Gather bgp address family facts using gathered state + register: result + junipernetworks.junos.junos_bgp_address_family: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ expected_gathered_output == result['gathered'] }}" + + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_bgp_address_family gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/merged.yaml new file mode 100644 index 00000000..f47dd971 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/merged.yaml @@ -0,0 +1,155 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_bgp_address_family merged integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + expected_merged_output: + address_family: + - af_type: + - accepted_prefix_limit: + idle_timeout_value: 2001 + limit_threshold: 98 + maximum: 20 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + type: "signaling" + afi: "evpn" + + - af_type: + - accepted_prefix_limit: + idle_timeout_value: 2000 + limit_threshold: 99 + maximum: 20 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: "from-fib" + type: "any" + + - legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + type: "flow" + + - entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_group_label: true + per_prefix_label: true + prefix_limit: + forever: true + limit_threshold: 99 + maximum: 20 + resolve_vpn: true + rib: "inet.3" + route_refresh_priority_priority: 3 + type: "labeled-unicast" + + - extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: "9.9.9.9" + type: "unicast" + afi: "inet" + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_bgp_address_family: &merged + config: + address_family: + - afi: "evpn" + af_type: + - type: "signaling" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + - afi: "inet" + af_type: + - type: "flow" + legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + + - type: "unicast" + extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: "9.9.9.9" + + - type: "labeled-unicast" + entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_prefix_label: true + per_group_label: true + prefix_limit: + maximum: 20 + limit_threshold: 99 + forever: true + resolve_vpn: true + rib: "inet.3" + route_refresh_priority_priority: 3 + + - type: "any" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 99 + idle_timeout_value: 2000 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: "from-fib" + state: merged + register: result + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_merged_output == result.after }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_bgp_address_family: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: merged + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_bgp_address_family merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/overridden.yaml new file mode 100644 index 00000000..286793b8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/overridden.yaml @@ -0,0 +1,131 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_bgp_address_family overridden integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + expected_overridden_output: + address_family: + - afi: "evpn" + af_type: + - type: "signaling" + accepted_prefix_limit: + maximum: 21 + limit_threshold: 99 + idle_timeout_value: 2002 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + damping: true + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_bgp_address_family: &merged + config: + address_family: + - afi: "evpn" + af_type: + - type: "signaling" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + - afi: "inet" + af_type: + - type: "flow" + legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + + - type: "unicast" + extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: "9.9.9.9" + + - type: "labeled-unicast" + entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_prefix_label: true + per_group_label: true + prefix_limit: + maximum: 20 + limit_threshold: 99 + forever: true + resolve_vpn: true + rib: "inet.3" + route_refresh_priority_priority: 3 + + - type: "any" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 99 + idle_timeout_value: 2000 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: "from-fib" + state: merged + + - name: Override existing configuration with running configuration + junipernetworks.junos.junos_bgp_address_family: &overridden + config: + address_family: + - afi: "evpn" + af_type: + - type: "signaling" + accepted_prefix_limit: + maximum: 21 + limit_threshold: 99 + idle_timeout_value: 2002 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + damping: true + state: overridden + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_overridden_output == result.after }}" + + - name: Override the existing running configuration with the provided configuration (IDEMPOTENT) + junipernetworks.junos.junos_bgp_address_family: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_bgp_address_family overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/parsed.yaml new file mode 100644 index 00000000..5203c828 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/parsed.yaml @@ -0,0 +1,84 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: + START junos_bgp_address_family parsed integration tests on connection={{ ansible_connection + }} + +- name: Set facts + ansible.builtin.set_fact: + expected_parsed_output: + address_family: + - af_type: + - accepted_prefix_limit: + idle_timeout_value: 2001 + limit_threshold: 98 + maximum: 20 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + type: "signaling" + afi: "evpn" + + - af_type: + - accepted_prefix_limit: + idle_timeout_value: 2000 + limit_threshold: 99 + maximum: 20 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: "from-fib" + type: "any" + + - legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + type: "flow" + + - entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_group_label: true + per_prefix_label: true + prefix_limit: + forever: true + limit_threshold: 99 + maximum: 20 + resolve_vpn: true + rib: "inet.3" + route_refresh_priority_priority: 3 + type: "labeled-unicast" + + - extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: "9.9.9.9" + type: "unicast" + afi: "inet" + +- name: Parse externally provided bgp_address_family config to agnostic model + register: result + junipernetworks.junos.junos_bgp_address_family: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output == result['parsed'] }}" + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_bgp_address_family parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/rendered.yaml new file mode 100644 index 00000000..e919a2c8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/rendered.yaml @@ -0,0 +1,83 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: + START junos_bgp_address_family rendered integration tests on connection={{ + ansible_connection }} + +- name: Set facts + ansible.builtin.set_fact: + expected_rendered_output: '20982001249.9.9.92099320992000220320003200023000from-fib' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: "evpn" + af_type: + - type: "signaling" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + - afi: "inet" + af_type: + - type: "flow" + legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + + - type: "unicast" + extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: "9.9.9.9" + + - type: "labeled-unicast" + entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_prefix_label: true + per_group_label: true + prefix_limit: + maximum: 20 + limit_threshold: 99 + forever: true + resolve_vpn: true + rib: "inet.3" + route_refresh_priority_priority: 3 + + - type: "any" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 99 + idle_timeout_value: 2000 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: "from-fib" + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_bgp_address_family rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/replaced.yaml new file mode 100644 index 00000000..d827874e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_address_family/tests/netconf/replaced.yaml @@ -0,0 +1,177 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_bgp_address_family replaced integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + expected_replaced_output: + address_family: + - af_type: + - accepted_prefix_limit: + idle_timeout_value: 2002 + limit_threshold: 99 + maximum: 21 + damping: true + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + type: "signaling" + afi: "evpn" + + - af_type: + - accepted_prefix_limit: + idle_timeout_value: 2000 + limit_threshold: 99 + maximum: 20 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: "from-fib" + type: "any" + + - legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + type: "flow" + + - entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_group_label: true + per_prefix_label: true + prefix_limit: + forever: true + limit_threshold: 99 + maximum: 20 + resolve_vpn: true + rib: "inet.3" + route_refresh_priority_priority: 3 + type: "labeled-unicast" + + - extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: "9.9.9.9" + type: "unicast" + afi: "inet" + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_bgp_address_family: &merged + config: + address_family: + - afi: "evpn" + af_type: + - type: "signaling" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + - afi: "inet" + af_type: + - type: "flow" + legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + + - type: "unicast" + extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: "9.9.9.9" + + - type: "labeled-unicast" + entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_prefix_label: true + per_group_label: true + prefix_limit: + maximum: 20 + limit_threshold: 99 + forever: true + resolve_vpn: true + rib: "inet.3" + route_refresh_priority_priority: 3 + + - type: "any" + accepted_prefix_limit: + maximum: 20 + limit_threshold: 99 + idle_timeout_value: 2000 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: "from-fib" + state: merged + + - name: Replace existing configuration with running configuration + junipernetworks.junos.junos_bgp_address_family: &replaced + config: + address_family: + - afi: "evpn" + af_type: + - type: "signaling" + accepted_prefix_limit: + maximum: 21 + limit_threshold: 99 + idle_timeout_value: 2002 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + damping: true + state: replaced + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_replaced_output == result.after }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_bgp_address_family: *replaced + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: replaced + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_bgp_address_family replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..d5ab5e10 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/_initial_config.yaml @@ -0,0 +1,35 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_bgp_global initial config on connection={{ ansible_connection }}" + +- name: Configure basic config relevant to BGP GLOBAL + junipernetworks.junos.junos_config: + lines: + - set routing-options autonomous-system 65534 + - set routing-options autonomous-system loops 3 + - set routing-options autonomous-system asdot-notation + - set protocols bgp accept-remote-nexthop + - set protocols bgp add-path-display-ipv4-address + - set protocols bgp advertise-from-main-vpn-tables + - set protocols bgp advertise-inactive + - set protocols bgp authentication-algorithm md5 + - set protocols bgp bgp-error-tolerance malformed-route-limit 20000000 + - set protocols bgp bmp monitor enable + - set protocols bgp damping + - set protocols bgp description "This is configured with Junos_bgp resource module" + - set protocols bgp egress-te-sid-stats + - set protocols bgp hold-time 5 + - set protocols bgp holddown-all-stale-labels + - set protocols bgp include-mp-next-hop + - set protocols bgp log-updown + - set protocols bgp no-advertise-peer-as + - set protocols bgp no-aggregator-id + - set protocols bgp no-client-reflect + - set protocols bgp out-delay 10 + - set protocols bgp precision-timers + - set protocols bgp preference 2 + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_bgp_global initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..efa729d7 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/_reset_config.yaml @@ -0,0 +1,37 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_bgp_global reset config on connection={{ ansible_connection }}" + +- name: Reset the config releavent to bgp global resource + junipernetworks.junos.junos_config: + lines: + - delete routing-options autonomous-system + - delete protocols bgp accept-remote-nexthop + - delete protocols bgp add-path-display-ipv4-address + - delete protocols bgp advertise-from-main-vpn-tables + - delete protocols bgp advertise-inactive + - delete protocols bgp authentication-algorithm + - delete protocols bgp bgp-error-tolerance + - delete protocols bgp bmp + - delete protocols bgp damping + - delete protocols bgp description + - delete protocols bgp egress-te-sid-stats + - delete protocols bgp hold-time + - delete protocols bgp holddown-all-stale-labels + - delete protocols bgp include-mp-next-hop + - delete protocols bgp log-updown + - delete protocols bgp no-advertise-peer-as + - delete protocols bgp no-aggregator-id + - delete protocols bgp no-client-reflect + - delete protocols bgp out-delay + - delete protocols bgp precision-timers + - delete protocols bgp preference + - delete protocols bgp egress-te + - delete protocols bgp egress-te-backup-paths + - delete protocols bgp group external + - delete protocols bgp group internal + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_bgp_global reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/deleted.yaml new file mode 100644 index 00000000..c892c7fd --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/deleted.yaml @@ -0,0 +1,34 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_bgp_global deleted integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Initial config + ansible.builtin.include_tasks: _initial_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + config: {} + + - name: Delete all ospf config from the device + junipernetworks.junos.junos_bgp_global: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config == result.after }}" + + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_bgp_global deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..50ccb3ff --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/empty_config.yaml @@ -0,0 +1,54 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START junos_bgp_global empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + config: + state: merged + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + config: + state: replaced + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + running_config: + state: parsed + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + config: + state: rendered + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..f91cc45a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,47 @@ + + + + 18.4R1-S2.4 + + + + + + This is configured with Junos_bgp resource module + + 2 + 5 + + + + 10 + + + md5 + + + + + enable + + + static-to-bgp + + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/gathered.yaml new file mode 100644 index 00000000..1d1cde1a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/gathered.yaml @@ -0,0 +1,30 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START junos_bgp_global gathered integration tests on connection={{ ansible_connection }} + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Initial config + ansible.builtin.include_tasks: _initial_config.yaml + + - name: Gather interfaces facts using gathered state + register: result + junipernetworks.junos.junos_bgp_global: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['gathered'] }}" + + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_bgp_global gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/merged.yaml new file mode 100644 index 00000000..8037559b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/merged.yaml @@ -0,0 +1,129 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_bgp_global merged integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_bgp_global: &merged + config: + as_number: "65534" + loops: 3 + asdot_notation: true + accept_remote_nexthop: true + add_path_display_ipv4_address: true + advertise_from_main_vpn_tables: true + advertise_inactive: true + authentication_algorithm: "md5" + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + egress_te_sid_stats: true + hold_time: 5 + holddown_all_stale_labels: true + include_mp_next_hop: true + log_updown: true + no_advertise_peer_as: true + no_aggregator_id: true + no_client_reflect: true + out_delay: 10 + precision_timers: true + preference: "2" + state: merged + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['before'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['after'] == result['after'] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_bgp_global: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - name: Update the running configuration with providede configuration + junipernetworks.junos.junos_bgp_global: + config: + as_number: "65534" + loops: 2 + asdot_notation: true + description: "This is updated with Junos_bgp resource module" + egress_te_backup_paths: + templates: + - path_name: "customer1" + peers: + - "11.11.11.11" + - "11.11.11.12" + - "11.11.11.13" + remote_nexthop: "2.2.2.2" + groups: + - name: "internal" + type: "internal" + vpn_apply_export: true + out_delay: 30 + accept_remote_nexthop: true + add_path_display_ipv4_address: true + peer_as: "65534" + allow: + - "all" + - "1.1.1.0/24" + neighbors: + - neighbor_address: "11.11.11.11" + peer_as: "65534" + out_delay: 11 + - neighbor_address: "11.11.11.12" + peer_as: "65534" + out_delay: 12 + + - name: "external" + out_delay: 20 + peer_as: "65534" + accept_remote_nexthop: true + add_path_display_ipv4_address: true + neighbors: + - neighbor_address: "12.12.12.12" + peer_as: "65534" + out_delay: 21 + accept_remote_nexthop: true + add_path_display_ipv4_address: true + - neighbor_address: "11.11.11.13" + peer_as: "65534" + out_delay: 31 + accept_remote_nexthop: true + add_path_display_ipv4_address: true + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['updated'] == result['after'] }}" + + tags: merged + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_bgp_global merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/overridden.yaml new file mode 100644 index 00000000..88cb9fcb --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/overridden.yaml @@ -0,0 +1,51 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_bgp_global overridden integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Initial config + ansible.builtin.include_tasks: _initial_config.yaml + + - name: Replace configuration + junipernetworks.junos.junos_bgp_global: &overridden + config: + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ overridden['after'] == result.after }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_bgp_global: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_bgp_global overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/parsed.yaml new file mode 100644 index 00000000..8b226564 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/parsed.yaml @@ -0,0 +1,52 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: + START junos_bgp_global parsed integration tests on connection={{ ansible_connection + }} + +- name: Set facts + ansible.builtin.set_fact: + expected_parsed_output: + accept_remote_nexthop: true + add_path_display_ipv4_address: true + advertise_bgp_static: + policy: "static-to-bgp" + advertise_from_main_vpn_tables: true + advertise_inactive: true + as_number: "65432" + authentication_algorithm: "md5" + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + egress_te_sid_stats: true + hold_time: 5 + holddown_all_stale_labels: true + include_mp_next_hop: true + log_updown: true + no_advertise_peer_as: true + no_aggregator_id: true + no_client_reflect: true + out_delay: 10 + precision_timers: true + preference: "2" + remove_private: + set: true + +- name: Parse externally provided bgp_global config to agnostic model + register: result + junipernetworks.junos.junos_bgp_global: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output == result['parsed'] }}" + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_bgp_global parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/purged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/purged.yaml new file mode 100644 index 00000000..6ad1d45b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/purged.yaml @@ -0,0 +1,34 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_bgp_global purged integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Initial config + ansible.builtin.include_tasks: _initial_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + config: {} + + - name: Purge all ospf config from the device + junipernetworks.junos.junos_bgp_global: + state: purged + register: result + + - name: Assert changed + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config == result.after }}" + + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_bgp_global purged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/rendered.yaml new file mode 100644 index 00000000..6ca1f765 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/rendered.yaml @@ -0,0 +1,41 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START junos_bgp_global rendered integration tests on connection={{ + ansible_connection }} + +- name: Set facts + ansible.builtin.set_fact: + expected_rendered_output: 'md5This is configured with Junos_bgp resource module52410automatic20000000enable' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_bgp_global: + config: + authentication_algorithm: "md5" + bfd_liveness_detection: + minimum_receive_interval: 4 + multiplier: 10 + no_adaptation: true + transmit_interval: + minimum_interval: 2 + version: "automatic" + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + egress_te_sid_stats: true + hold_time: 5 + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- name: Debug task + ansible.builtin.debug: + msg: END junos_bgp_global rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/replaced.yaml new file mode 100644 index 00000000..93c3a797 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/replaced.yaml @@ -0,0 +1,51 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_bgp_global replaced integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Initial config + ansible.builtin.include_tasks: _initial_config.yaml + + - name: Replace configuration + junipernetworks.junos.junos_bgp_global: &replaced + config: + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result.after }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_bgp_global: *replaced + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: replaced + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_bgp_global replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/rtt.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/rtt.yml new file mode 100644 index 00000000..e8bf494b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/tests/netconf/rtt.yml @@ -0,0 +1,92 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START junos_bgp_global round trip integration tests on connection={{ + ansible_connection }} + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_bgp_global: + config: + accept_remote_nexthop: true + add_path_display_ipv4_address: true + advertise_from_main_vpn_tables: true + advertise_inactive: true + as_number: "65534" + asdot_notation: true + authentication_algorithm: "md5" + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + egress_te_sid_stats: true + hold_time: 5 + holddown_all_stale_labels: true + include_mp_next_hop: true + log_updown: true + loops: 3 + no_advertise_peer_as: true + no_aggregator_id: true + no_client_reflect: true + out_delay: 10 + precision_timers: true + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - bgp_global + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_bgp_global: + config: + accept_remote_nexthop: true + add_path_display_ipv4_address: true + advertise_from_main_vpn_tables: true + advertise_inactive: true + as_number: "65535" + asdot_notation: true + authentication_algorithm: "md5" + bgp_error_tolerance: + malformed_route_limit: 20000000 + preference: "2" + state: replaced + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_bgp_global: + config: "{{ ansible_facts['network_resources']['bgp_global'] }}" + state: replaced + + - name: Assert that before dicts are correct + ansible.builtin.assert: + that: + - result.changed == True + - "{{ result['after'] == revert['before'] }}" + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + - result.changed == True + - "{{ base_config['after'] == revert['after'] }}" + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_bgp_global round trip integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/vars/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/vars/main.yaml new file mode 100644 index 00000000..a9f9e9b3 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_bgp_global/vars/main.yaml @@ -0,0 +1,119 @@ +--- +merged: + before: {} + + after: + accept_remote_nexthop: true + add_path_display_ipv4_address: true + advertise_from_main_vpn_tables: true + advertise_inactive: true + as_number: "65534" + asdot_notation: true + authentication_algorithm: "md5" + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + egress_te_sid_stats: true + hold_time: 5 + holddown_all_stale_labels: true + include_mp_next_hop: true + log_updown: true + loops: 3 + no_advertise_peer_as: true + no_aggregator_id: true + no_client_reflect: true + out_delay: 10 + precision_timers: true + preference: "2" + + updated: + accept_remote_nexthop: true + add_path_display_ipv4_address: true + advertise_from_main_vpn_tables: true + advertise_inactive: true + as_number: "65534" + asdot_notation: true + authentication_algorithm: "md5" + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is updated with Junos_bgp resource module" + egress_te_backup_paths: + templates: + - path_name: "customer1" + peers: + - "11.11.11.11" + - "11.11.11.12" + - "11.11.11.13" + remote_nexthop: "2.2.2.2" + egress_te_sid_stats: true + groups: + - accept_remote_nexthop: true + add_path_display_ipv4_address: true + allow: + - "0.0.0.0/0" + - "1.1.1.0/24" + name: "internal" + neighbors: + - neighbor_address: "11.11.11.11" + out_delay: 11 + peer_as: "65534" + - neighbor_address: "11.11.11.12" + out_delay: 12 + peer_as: "65534" + out_delay: 30 + peer_as: "65534" + type: "internal" + vpn_apply_export: true + + - accept_remote_nexthop: true + add_path_display_ipv4_address: true + name: "external" + neighbors: + - accept_remote_nexthop: true + add_path_display_ipv4_address: true + neighbor_address: "12.12.12.12" + out_delay: 21 + peer_as: "65534" + + - accept_remote_nexthop: true + add_path_display_ipv4_address: true + neighbor_address: "11.11.11.13" + out_delay: 31 + peer_as: "65534" + out_delay: 20 + peer_as: "65534" + hold_time: 5 + holddown_all_stale_labels: true + include_mp_next_hop: true + log_updown: true + loops: 2 + no_advertise_peer_as: true + no_aggregator_id: true + no_client_reflect: true + out_delay: 10 + precision_timers: true + preference: "2" + +replaced: + after: + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + +overridden: + after: + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/defaults/main.yaml new file mode 100644 index 00000000..9ef5ba51 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/cli.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/cli.yaml new file mode 100644 index 00000000..7a0bc541 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/cli.yaml @@ -0,0 +1,19 @@ +--- +- name: Collect all cli test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + register: test_cases + delegate_to: localhost + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + vars: + ansible_connection: ansible.netcommon.network_cli + loop_control: + loop_var: test_case_to_run diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/main.yaml new file mode 100644 index 00000000..3243ad57 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/main.yaml @@ -0,0 +1,14 @@ +--- +- name: Invoke netconf xml tasks + ansible.builtin.include_tasks: netconf_xml.yaml + +- name: Invoke netconf text + ansible.builtin.include_tasks: netconf_text.yaml + +- name: Invoke netconf json tasks + ansible.builtin.include_tasks: netconf_json.yaml + +- name: Invoke netconf cli tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - network_cli diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/netconf_json.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/netconf_json.yaml new file mode 100644 index 00000000..88125160 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/netconf_json.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect netconf_json test cases with json encoding + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf_json" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/netconf_text.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/netconf_text.yaml new file mode 100644 index 00000000..6680dd8a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/netconf_text.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect netconf_text test cases with text encoding + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf_text" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/netconf_xml.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/netconf_xml.yaml new file mode 100644 index 00000000..e2a9be49 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tasks/netconf_xml.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect netconf_xml test cases with xml encoding + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf_xml" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/cli/cli_commmand.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/cli/cli_commmand.yaml new file mode 100644 index 00000000..649e5a52 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/cli/cli_commmand.yaml @@ -0,0 +1,69 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START cli/cli_command.yaml on connection={{ ansible_connection }} + +- block: + - name: Run get output for single command + register: result + ansible.netcommon.cli_command: + command: show version + + - name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + + - name: Run test with prompt and answer + loop: + - configure + - set system syslog file test any any + - rollback + - exit + register: result + ansible.netcommon.cli_command: + command: "{{ item }}" + prompt: + - Exit with uncommitted changes + answer: true + + - name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + + - loop: + - configure + - rollback + - set system login user ansible_test class operator authentication plain-text-password + - commit + register: result + ignore_errors: true + ansible.netcommon.cli_command: + command: "{{item}}" + prompt: + - New password + - Retype new password + answer: + - Test1234 + - Test1234 + check_all: true + + - name: Assertion + ansible.builtin.assert: + that: + - "'failed' not in result" + + - register: result + ignore_errors: true + junipernetworks.junos.junos_netconf: + + - name: Assertion + ansible.builtin.assert: + that: + - result.failed == false + when: ansible_connection == 'ansible.netcommon.network_cli' + +- name: Debug task + ansible.builtin.debug: msg="END cli/cli_command.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/bad_operator.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/bad_operator.yaml new file mode 100644 index 00000000..6b51014f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/bad_operator.yaml @@ -0,0 +1,27 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_json/bad_operator.yaml on connection={{ ansible_connection + }}" + +- name: Run test bad operator with json encoding + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + wait_for: + - result[0]['software-information'][0]['host-name'][0]['data'] foo lo0 + format: json + +- name: Assertion + ansible.builtin.assert: + that: + - result.failed == true + - result.msg is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_json/bad_operator.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/contains.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/contains.yaml new file mode 100644 index 00000000..32129d3f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/contains.yaml @@ -0,0 +1,28 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_json/contains.yaml on connection={{ ansible_connection + }}" + +- name: Run test contains operator with json encoding + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: json + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['name'][0]['data'] + contains lo0 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_json/contains.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/equal.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/equal.yaml new file mode 100644 index 00000000..9d397f3f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/equal.yaml @@ -0,0 +1,44 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_json/equal.yaml on connection={{ ansible_connection + }}" + +- name: Perform test == operator with xml encoding + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['name'][0]['data'] + == lo0 + format: json + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Run test eq operator with json encoding + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['name'][0]['data'] + eq lo0 + format: json + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: msg="END netconf_json/equal.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/greaterthan.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/greaterthan.yaml new file mode 100644 index 00000000..474a54bb --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/greaterthan.yaml @@ -0,0 +1,46 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_json/greaterthan.yaml on connection={{ ansible_connection + }}" + +- name: Test gt operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: json + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['local-index'][0]['data'] + gt 5 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Run test > operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: json + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['local-index'][0]['data'] + > 5 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_json/greaterthan.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/greaterthanorequal.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/greaterthanorequal.yaml new file mode 100644 index 00000000..c5ba4a52 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/greaterthanorequal.yaml @@ -0,0 +1,46 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_json/greaterthanorequal.yaml on connection={{ ansible_connection + }}" + +- name: Run test ge operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: json + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['local-index'][0]['data'] + ge 6 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Run test >= operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: json + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['local-index'][0]['data'] + >= 6 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_json/greaterthanorequal.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/lessthan.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/lessthan.yaml new file mode 100644 index 00000000..3fba44bc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/lessthan.yaml @@ -0,0 +1,46 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_json/lessthan.yaml on connection={{ ansible_connection + }}" + +- name: Run test lt operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: json + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['local-index'][0]['data'] + lt 7 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Run test < operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: json + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['local-index'][0]['data'] + lt 7 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_json/lessthan.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/lessthanorequal.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/lessthanorequal.yaml new file mode 100644 index 00000000..6d598980 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/lessthanorequal.yaml @@ -0,0 +1,46 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_json/lessthanorequal.yaml on connection={{ ansible_connection + }}" + +- name: Run test le operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: json + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['local-index'][0][data] + le 6 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Run test <= operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: json + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['local-index'][0][data] + <= 6 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_json/lessthanorequal.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/notequal.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/notequal.yaml new file mode 100644 index 00000000..3213b8b6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/notequal.yaml @@ -0,0 +1,46 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_json/notequal.yaml on connection={{ ansible_connection + }}" + +- name: Run test neq operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: json + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['name'][0]['data'] + neq em0 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Run test != operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: json + wait_for: + - result[1]['interface-information'][0]['physical-interface'][0]['name'][0]['data'] + neq em0 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_json/notequal.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/output.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/output.yaml new file mode 100644 index 00000000..9e1c16a2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_json/output.yaml @@ -0,0 +1,67 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_json/output.yaml on connection={{ ansible_connection + }}" + +- name: Run get output for single command + register: result + junipernetworks.junos.junos_command: + commands: + - show version + format: json + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Get output for multiple commands + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show route + format: json + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Get output for single command with cli transport + register: result + connection: ansible.netcommon.network_cli + junipernetworks.junos.junos_command: + commands: + - show version | display json + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Get output for multiple commands with cli transport + register: result + connection: ansible.netcommon.network_cli + junipernetworks.junos.junos_command: + commands: + - show version + - show route + format: json + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: msg="END netconf_json/output.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/bad_operator.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/bad_operator.yaml new file mode 100644 index 00000000..9fa6242d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/bad_operator.yaml @@ -0,0 +1,28 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_text/bad_operator.yaml on connection={{ ansible_connection + }}" + +- name: Test bad operator with text encoding + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + wait_for: + - result[1].interface-information[0].physical-interface[0].name[0].data foo + lo0 + encoding: text + +- name: Assertion + ansible.builtin.assert: + that: + - result.failed == true + - result.msg is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_text/bad_operator.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/contains.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/contains.yaml new file mode 100644 index 00000000..13cb325c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/contains.yaml @@ -0,0 +1,27 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_text/contains.yaml on connection={{ ansible_connection + }}" + +- name: Test contains operator with text encoding + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + display: text + wait_for: + - result[1] contains lo0 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_text/contains.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/invalid.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/invalid.yaml new file mode 100644 index 00000000..ae847181 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/invalid.yaml @@ -0,0 +1,41 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_text/invalid.yaml on connection={{ ansible_connection + }}" + +- name: Run invalid command + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show foo + display: text + +- name: Debug task + ansible.builtin.debug: var=result + +- name: Assertion + ansible.builtin.assert: + that: + - result.failed == true + - result.msg is defined + +- name: Run commands that ansible.builtin.include invalid command + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: + - show version + - show foo + display: text + +- name: Assertion + ansible.builtin.assert: + that: + - result.failed == true + - result.msg is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_text/invalid.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/no_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/no_config.yaml new file mode 100644 index 00000000..b90ee106 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/no_config.yaml @@ -0,0 +1,26 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_text/no_config.yaml on connection={{ ansible_connection + }}" + +- name: Test handling of show command's empty response received from network device + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: + - show configuration system ntp + display: text + +- name: Assertion + ansible.builtin.assert: + that: + - result.failed == false + - result.changed == false + - result.stdout|symmetric_difference([""]) == [] + - result.stdout_lines|symmetric_difference([[""]]) == [] + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_text/no_config.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/output.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/output.yaml new file mode 100644 index 00000000..74bc67f1 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/output.yaml @@ -0,0 +1,78 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_text/output.yaml on connection={{ ansible_connection + }}" + +- name: Get output for single command + register: result + junipernetworks.junos.junos_command: + commands: show version + display: text + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Get output for multiple commands + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show route + display: text + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: get output for partial config commands + register: result + junipernetworks.junos.junos_command: + commands: + - show configuration system syslog + display: text + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Get output for single command with cli transport + register: result + junipernetworks.junos.junos_command: + commands: show version + display: text + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Get output for multiple commands with cli transport + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show route + display: text + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: msg="END netconf_text/output.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/timeout.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/timeout.yaml new file mode 100644 index 00000000..f1a6d51d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_text/timeout.yaml @@ -0,0 +1,26 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_text/timeout.yaml on connection={{ ansible_connection + }}" + +- name: Test bad condition + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: + - show version + wait_for: + - result[0] contains bad_value_string + display: text + +- name: Assertion + ansible.builtin.assert: + that: + - result.failed == true + - result.msg is defined + +- name: Assertion + ansible.builtin.debug: + msg="END netconf_text/timeout.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/bad_operator.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/bad_operator.yaml new file mode 100644 index 00000000..8e3f1c2d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/bad_operator.yaml @@ -0,0 +1,28 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_xml/bad_operator.yaml on connection={{ ansible_connection + }}" + +- name: Test bad operator with xml encoding + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + wait_for: + - result[1].rpc-reply.interface-information[0].physical-interface[0].name[0].data + foo lo0 + format: xml + +- name: Assertion + ansible.builtin.assert: + that: + - result.failed == true + - result.msg is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_xml/bad_operator.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/contains.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/contains.yaml new file mode 100644 index 00000000..1cb01968 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/contains.yaml @@ -0,0 +1,28 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_xml/contains.yaml on connection={{ ansible_connection + }}" + +- name: Test contains operator with xml encoding + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: xml + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.name contains + lo0 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_xml/contains.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/equal.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/equal.yaml new file mode 100644 index 00000000..74507da7 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/equal.yaml @@ -0,0 +1,40 @@ +--- +- name: Debug task + ansible.builtin.debug: msg="START netconf_xml/equal.yaml on connection={{ ansible_connection }}" + +- name: Run test == operator with xml encoding + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.name == lo0 + format: xml + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Test eq operator with json encoding + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.name eq lo0 + format: xml + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: msg="END netconf_xml/equal.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/greaterthan.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/greaterthan.yaml new file mode 100644 index 00000000..d6ca1d0f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/greaterthan.yaml @@ -0,0 +1,46 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_xml/greaterthan.yaml on connection={{ ansible_connection + }}" + +- name: Run test gt operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: xml + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.local-index + gt 5 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Run test > operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: xml + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.local-index + > 5 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_xml/greaterthan.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/greaterthanorequal.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/greaterthanorequal.yaml new file mode 100644 index 00000000..6f1aebb2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/greaterthanorequal.yaml @@ -0,0 +1,46 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_xml/greaterthanorequal.yaml on connection={{ ansible_connection + }}" + +- name: Test ge operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: xml + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.local-index + ge 6 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Test >= operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: xml + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.local-index + >= 6 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_xml/greaterthanorequal.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/invalid.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/invalid.yaml new file mode 100644 index 00000000..95351ece --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/invalid.yaml @@ -0,0 +1,38 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_xml/invalid.yaml on connection={{ ansible_connection + }}" + +- name: Run invalid command + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: + - show foo + +- name: Debug task + ansible.builtin.debug: var=result + +- name: Assertion + ansible.builtin.assert: + that: + - result.failed == true + - result.msg is defined + +- name: Run commands that ansible.builtin.include invalid command + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: + - show version + - show foo + +- name: Assertion + ansible.builtin.assert: + that: + - result.failed == true + - result.msg is defined + +- name: Debug task + ansible.builtin.debug: msg="END netconf_xml/invalid.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/lessthan.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/lessthan.yaml new file mode 100644 index 00000000..da596f53 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/lessthan.yaml @@ -0,0 +1,46 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_xml/lessthan.yaml on connection={{ ansible_connection + }}" + +- name: Test lt operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: xml + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.local-index + lt 7 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Test < operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: xml + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.local-index + lt 7 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_xml/lessthan.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/lessthanorequal.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/lessthanorequal.yaml new file mode 100644 index 00000000..bb8c0b85 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/lessthanorequal.yaml @@ -0,0 +1,46 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_xml/lessthanorequal.yaml on connection={{ ansible_connection + }}" + +- name: Test le operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: xml + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.local-index + le 6 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Test <= operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: xml + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.local-index + <= 6 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_xml/lessthanorequal.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/notequal.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/notequal.yaml new file mode 100644 index 00000000..2e901f21 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/notequal.yaml @@ -0,0 +1,44 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_xml/notequal.yaml on connection={{ ansible_connection + }}" + +- name: Test neq operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: xml + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.name neq em0 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Test != operator + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces lo0 + format: xml + wait_for: + - result[1].rpc-reply.interface-information.physical-interface.name neq em0 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: + msg="END netconf_xml/notequal.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/output.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/output.yaml new file mode 100644 index 00000000..ad3e3f68 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/output.yaml @@ -0,0 +1,66 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_xml/output.yaml on connection={{ ansible_connection + }}" + +- name: Get output for single command + register: result + junipernetworks.junos.junos_command: + commands: + - show version + format: xml + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Get output for multiple commands + register: result + junipernetworks.junos.junos_command: + commands: + - show version + - show route + format: xml + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Get output for single command with cli transport + register: result + connection: ansible.netcommon.network_cli + junipernetworks.junos.junos_command: + commands: show version | display xml + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Get output for multiple commands with cli transport + register: result + connection: ansible.netcommon.network_cli + junipernetworks.junos.junos_command: + commands: + - show version + - show route + display: xml + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout_lines is defined + +- name: Debug task + ansible.builtin.debug: msg="END netconf_xml/output.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/timeout.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/timeout.yaml new file mode 100644 index 00000000..fedb6d5d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_command/tests/netconf_xml/timeout.yaml @@ -0,0 +1,23 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg="START netconf_xml/timeout.yaml on connection={{ ansible_connection + }}" + +- name: Test bad condition + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: + - show version + wait_for: + - result[0] contains bad_value_string + +- name: Assertion + ansible.builtin.assert: + that: + - result.failed == true + - result.msg is defined + +- name: Debug task + ansible.builtin.debug: msg="END netconf_xml/timeout.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/cli_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/cli_config.yaml new file mode 100644 index 00000000..7e215184 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/cli_config.yaml @@ -0,0 +1,19 @@ +--- +- name: Collect all cli test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli_config" + patterns: "{{ testcase }}.yaml" + register: test_cases + delegate_to: localhost + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/main.yaml new file mode 100644 index 00000000..7daaf8c3 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Invoke netconf netconf tasks + ansible.builtin.include_tasks: netconf.yaml + +- name: Invoke cli tasks + ansible.builtin.include_tasks: cli_config.yaml + tags: + - network_cli + +- name: Invoke tasks + ansible.builtin.include_tasks: redirection.yaml + when: ansible_version.full is version('2.10.0', '>=') diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/netconf.yaml new file mode 100644 index 00000000..824d3b00 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/netconf.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/redirection.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/redirection.yaml new file mode 100644 index 00000000..0b26ef51 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tasks/redirection.yaml @@ -0,0 +1,19 @@ +--- +- name: Collect redirection test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/redirection/" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/templates/basic/config.j2 b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/templates/basic/config.j2 new file mode 100644 index 00000000..44ddf67b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/templates/basic/config.j2 @@ -0,0 +1,9 @@ +interfaces { + lo0 { + unit 0 { + family inet { + address 192.0.2.1/32; + } + } + } +} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/templates/basic/config.set b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/templates/basic/config.set new file mode 100644 index 00000000..df436bba --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/templates/basic/config.set @@ -0,0 +1 @@ +set interfaces lo0 unit 0 family inet address 192.0.2.1/32 diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/templates/basic/config.xml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/templates/basic/config.xml new file mode 100644 index 00000000..a120d4bc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/templates/basic/config.xml @@ -0,0 +1,15 @@ + + + lo0 + + 0 + + +
+ 192.0.2.1/32 +
+
+
+
+
+
diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/cli_config/cli_backup.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/cli_config/cli_backup.yaml new file mode 100644 index 00000000..37c7157b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/cli_config/cli_backup.yaml @@ -0,0 +1,110 @@ +--- +- ansible.builtin.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 + ansible.builtin.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 + register: result + ansible.netcommon.cli_config: + backup: true + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: collect any backup files + ansible.builtin.find: + paths: "{{ role_path }}/backup" + pattern: "{{ inventory_hostname_short }}_config*" + register: backup_files + connection: local + +- ansible.builtin.assert: + that: + - backup_files.files is defined + +- name: take configuration backup in custom filename and directory path + register: result + ansible.netcommon.cli_config: + backup: true + backup_options: + filename: backup.cfg + dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: check if the backup file-1 exist + ansible.builtin.find: + paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup.cfg" + register: backup_file + connection: local + +- ansible.builtin.assert: + that: + - backup_file.files is defined + +- name: take configuration backup in custom filename + register: result + ansible.netcommon.cli_config: + backup: true + backup_options: + filename: backup.cfg + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: check if the backup file-2 exist + ansible.builtin.find: + paths: "{{ role_path }}/backup/backup.cfg" + register: backup_file + connection: local + +- ansible.builtin.assert: + that: + - backup_file.files is defined + +- name: take configuration backup in custom path and default filename + register: result + ansible.netcommon.cli_config: + backup: true + backup_options: + dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: check if the backup file-3 exist + ansible.builtin.find: + paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" + pattern: "{{ inventory_hostname_short }}_config*" + register: backup_file + connection: local + +- ansible.builtin.assert: + that: + - backup_file.files is defined + +- ansible.builtin.debug: msg="END cli_config/backup.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/cli_config/cli_basic.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/cli_config/cli_basic.yaml new file mode 100644 index 00000000..fd0659a3 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/cli_config/cli_basic.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg="START cli_config/cli_basic.yaml on connection={{ ansible_connection + }}" + +- name: setup + ansible.netcommon.cli_config: &id002 + config: delete interfaces ge-0/0/1 + +- name: setup + ansible.netcommon.cli_config: &id003 + config: delete interfaces ge-0/0/2 + +- name: configure device with config + register: result + ansible.netcommon.cli_config: &id001 + config: set interfaces ge-0/0/1 description 'test-interface' + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Idempotence + register: result + ansible.netcommon.cli_config: *id001 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: configure device with config + register: result + ansible.netcommon.cli_config: + config: set interfaces ge-0/0/2 description 'test-interface' + +- name: test rollabck + register: result + ansible.netcommon.cli_config: + rollback: 1 + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ge-0/0/2' in result.diff.prepared" + +- name: remove root-authethication (test error scenario) + ignore_errors: true + register: result + ansible.netcommon.cli_config: + config: delete system root-authentication + +- ansible.builtin.assert: + that: + - result.failed == true + - "'Missing mandatory statement' in result.msg" + +- name: teardown + ansible.netcommon.cli_config: *id002 + +- name: teardown + ansible.netcommon.cli_config: *id003 + +- ansible.builtin.debug: + msg="END cli_config/cli_basic.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/cli_config/cli_replace.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/cli_config/cli_replace.yaml new file mode 100644 index 00000000..b997b318 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/cli_config/cli_replace.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg="START cli_config/cli_replace.yaml on connection={{ ansible_connection + }}" + +- name: set interface config + loop: + - delete interfaces ge-0/0/11 + - set interfaces ge-0/0/11 description "test cli_config" + ansible.netcommon.cli_config: + config: "{{ item }}" + +- name: get running configuration + register: result + ansible.netcommon.cli_command: + command: show configuration + +- name: copy configuration to file + copy: + content: "{{ result['stdout'] }}" + dest: /tmp/junos01.cfg + +- name: modify interface ge-0/0/11 configuration + replace: + path: /tmp/junos01.cfg + regexp: test cli_config + replace: test cli_config replaced + +- name: copy config file to remote host + ansible.netcommon.net_put: + src: /tmp/junos01.cfg + protocol: sftp + dest: /var/home/{{ ansible_user }}/junos01.cfg + +- name: replace syslog test file configuration + ansible.netcommon.cli_config: + replace: /var/home/{{ ansible_user }}/junos01.cfg + +- name: get interface configuration + register: result + ansible.netcommon.cli_command: + command: show configuration interfaces ge-0/0/11 + +- name: ansible.builtin.assert that interface config change is reflected on device + ansible.builtin.assert: + that: + - "'test cli_config replaced' in result.stdout" + +- name: replace interface configuration (idempotent) + register: result + ansible.netcommon.cli_config: + replace: /var/home/{{ ansible_user }}/junos01.cfg + +- name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + +- name: delete interface config + ansible.netcommon.cli_config: + config: delete interfaces ge-0/0/11 + +- ansible.builtin.debug: + msg="END cli_config/cli_replace.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/backup.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/backup.yaml new file mode 100644 index 00000000..b6746c40 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/backup.yaml @@ -0,0 +1,32 @@ +--- +- ansible.builtin.debug: msg="START netconf/backup.yaml on connection={{ ansible_connection }}" + +- name: setup + junipernetworks.junos.junos_config: + lines: + - set system host-name {{ inventory_hostname_short }} + - delete interfaces lo0 + +- name: configure device with config + register: result + junipernetworks.junos.junos_config: + src: basic/config.j2 + backup: true + +- ansible.builtin.assert: + that: + - result.changed == true + - result.updates is not defined + +- name: take configuration backup in custom filename + register: result + junipernetworks.junos.junos_config: + backup: true + backup_options: + filename: backup.cfg + +- ansible.builtin.assert: + that: + - result.changed == true + +- ansible.builtin.debug: msg="END netconf/backup.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/bad_action.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/bad_action.yaml new file mode 100644 index 00000000..ad97a18f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/bad_action.yaml @@ -0,0 +1,17 @@ +--- +- ansible.builtin.debug: + msg="START netconf/bad_action.yaml on connection={{ ansible_connection + }}" + +- name: configure single bad_action command + register: result + ignore_errors: true + junipernetworks.junos.junos_config: + lines: + - invalid system foo + +- ansible.builtin.assert: + that: + - result.failed == true + +- ansible.builtin.debug: msg="END netconf/bad_action.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/invalid.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/invalid.yaml new file mode 100644 index 00000000..6cb7453d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/invalid.yaml @@ -0,0 +1,27 @@ +--- +- ansible.builtin.debug: msg="START netconf/invalid.yaml on connection={{ ansible_connection }}" + +- name: configure single invalid command + register: result + ignore_errors: true + junipernetworks.junos.junos_config: + lines: + - set system foo + +- ansible.builtin.assert: + that: + - result.failed == true + +- name: configure multiple invalid command + register: result + ignore_errors: true + junipernetworks.junos.junos_config: + lines: + - set system host-name {{ inventory_hostname_short }} + - set system foo + +- ansible.builtin.assert: + that: + - result.failed == true + +- ansible.builtin.debug: msg="END netconf/invalid.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/multiple.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/multiple.yaml new file mode 100644 index 00000000..b5384193 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/multiple.yaml @@ -0,0 +1,43 @@ +--- +- ansible.builtin.debug: msg="START netconf/multiple.yaml on connection={{ ansible_connection }}" + +- name: setup + register: test + junipernetworks.junos.junos_config: + lines: + - set system host-name {{ inventory_hostname_short }} + - delete interfaces lo0 + +- name: configure multiple commands + register: result + junipernetworks.junos.junos_config: + lines: + - set system host-name {{ inventory_hostname_short }} + - set interfaces lo0 unit 0 family inet address 192.0.2.1/32 + +- ansible.builtin.assert: + that: + - result.changed == true + - "'host-name;' not in result.diff.prepared" + - "'address 192.0.2.1/32' in result.diff.prepared" + +- name: check multiple commands idempotent + register: result + junipernetworks.junos.junos_config: + lines: + - set system host-name {{ inventory_hostname_short }} + - set interfaces lo0 unit 0 family inet address 192.0.2.1/32 + +- ansible.builtin.assert: + that: + - result.changed == false + - result.diff is not defined + +- name: teardown + register: test + junipernetworks.junos.junos_config: + lines: + - set system host-name {{ inventory_hostname_short }} + - delete interfaces lo0 + +- ansible.builtin.debug: msg="END netconf/multiple.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/single.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/single.yaml new file mode 100644 index 00000000..07f09dce --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/single.yaml @@ -0,0 +1,72 @@ +--- +- ansible.builtin.debug: msg="START netconf/single.yaml on connection={{ ansible_connection }}" + +- name: setup + junipernetworks.junos.junos_config: + lines: + - set system host-name {{ inventory_hostname_short }} + +- name: configure single command + register: result + junipernetworks.junos.junos_config: + lines: + - set system host-name localhost + +- ansible.builtin.assert: + that: + - result.changed == true + - "'+ host-name localhost;' in result.diff.prepared" + +- name: check single command idempotent + register: result + junipernetworks.junos.junos_config: + lines: + - set system host-name localhost + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: confirm previous commit + register: result + junipernetworks.junos.junos_config: + confirm_commit: true + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: teardown for rollback test + junipernetworks.junos.junos_config: + lines: + - delete system syslog file test1 + +- name: Configure syslog file + register: result + junipernetworks.junos.junos_config: + lines: + - set system syslog file test1 any any + +- ansible.builtin.assert: + that: + - result.changed == true + - result.diff.prepared is search("\+ *file test1") + - result.diff.prepared is search("\+ *any any") + +- name: Rollback junos config + register: result + junipernetworks.junos.junos_config: + rollback: 1 + +- ansible.builtin.assert: + that: + - result.changed == true + - result.diff.prepared is search("\+ *file test1") + - result.diff.prepared is search("\+ *any any") + +- name: teardown + junipernetworks.junos.junos_config: + lines: + - set system host-name {{ inventory_hostname_short }} + +- ansible.builtin.debug: msg="END netconf/single.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/src_basic.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/src_basic.yaml new file mode 100644 index 00000000..504a7693 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/src_basic.yaml @@ -0,0 +1,96 @@ +--- +- ansible.builtin.debug: msg="START netconf/src_basic.yaml on connection={{ ansible_connection }}" + +- name: setup + junipernetworks.junos.junos_config: + lines: + - set system host-name {{ inventory_hostname_short }} + - delete interfaces lo0 + +- name: configure device with text config + register: result + junipernetworks.junos.junos_config: + src: basic/config.j2 + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: check device with config + register: result + junipernetworks.junos.junos_config: + src: basic/config.j2 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: teardown + register: result + junipernetworks.junos.junos_config: + lines: + - delete interfaces lo0 + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: configure device with set config + register: result + junipernetworks.junos.junos_config: + src: basic/config.set + +- ansible.builtin.assert: + that: + - result.changed == true + - "'address 192.0.2.1/32' in result.diff.prepared" + +- name: check device with config + register: result + junipernetworks.junos.junos_config: + src: basic/config.set + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: teardown + register: result + junipernetworks.junos.junos_config: + lines: + - delete interfaces lo0 + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: configure device with xml config + register: result + junipernetworks.junos.junos_config: + src: basic/config.xml + +- ansible.builtin.assert: + that: + - result.changed == true + - "'address 192.0.2.1/32' in result.diff.prepared" + +- name: check device with config + register: result + junipernetworks.junos.junos_config: + src: basic/config.xml + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: teardown + register: result + junipernetworks.junos.junos_config: + lines: + - delete interfaces lo0 + +- ansible.builtin.assert: + that: + - result.changed == true + +- ansible.builtin.debug: msg="END netconf/src_basic.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/src_invalid.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/src_invalid.yaml new file mode 100644 index 00000000..1934b1c5 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/netconf/src_invalid.yaml @@ -0,0 +1,18 @@ +--- +- ansible.builtin.debug: + msg="START netconf/src_invalid.yaml on connection={{ ansible_connection + }}" + +- name: configure with invalid src + register: result + ignore_errors: true + junipernetworks.junos.junos_config: + src: basic/foobar.j2 + +- ansible.builtin.assert: + that: + - result.changed == false + - result.failed == true + - result.msg == 'path specified in src not found' + +- ansible.builtin.debug: msg="END netconf/src_invalid.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/redirection/shortname.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/redirection/shortname.yaml new file mode 100644 index 00000000..d21594c2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_config/tests/redirection/shortname.yaml @@ -0,0 +1,47 @@ +--- +- ansible.builtin.debug: msg="START redirection/netconf/shortname.yaml on connection={{ ansible_connection }}" + +- name: setup + junipernetworks.junos.config: + lines: + - delete interfaces lo0 + +- name: Use src with module alias + register: result + junipernetworks.junos.config: + src: basic/config.j2 + +- ansible.builtin.assert: + that: + # make sure that the template content was read and not the path + - result.changed == true + +- name: teardown + register: result + junipernetworks.junos.config: + lines: + - delete interfaces lo0 + +- name: use module alias to take configuration backup + register: result + junipernetworks.junos.config: + backup: true + backup_options: + filename: backup_with_alias.cfg + dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: check if the backup file-4 exist + ansible.builtin.find: + paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup_with_alias.cfg" + register: backup_file + connection: local + +- ansible.builtin.assert: + that: + - backup_file.files is defined + +- ansible.builtin.debug: msg="END redirection/netconf/shortname.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/defaults/main.yaml new file mode 100644 index 00000000..9ef5ba51 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tasks/main.yaml new file mode 100644 index 00000000..ac951c8f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tasks/main.yaml @@ -0,0 +1,3 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tasks/netconf.yaml new file mode 100644 index 00000000..824d3b00 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tasks/netconf.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tests/netconf/facts.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tests/netconf/facts.yaml new file mode 100644 index 00000000..6dfcaf57 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tests/netconf/facts.yaml @@ -0,0 +1,128 @@ +--- +- name: Debug task + ansible.builtin.debug: msg="START netconf/facts.yaml on connection={{ ansible_connection }}" + +- name: Collect default facts from device + register: result + junipernetworks.junos.junos_facts: + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - "'ansible_net_hostname' in result['ansible_facts']" + - "'ansible_net_system' in result['ansible_facts']" + - "'ansible_net_model' in result['ansible_facts']" + +- name: Collect config facts from device + register: result + junipernetworks.junos.junos_facts: + gather_subset: config + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - "'ansible_net_config' in result['ansible_facts']" + - "'ansible_net_interfaces' not in result['ansible_facts']" + - "'ansible_net_memfree_mb' not in result['ansible_facts']" + +- name: Collect all facts from device except hardware + register: result + junipernetworks.junos.junos_facts: + gather_subset: "!hardware" + vars: + ansible_command_timeout: 100 + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - "'ansible_net_config' in result['ansible_facts']" + - "'ansible_net_interfaces' in result['ansible_facts']" + - "'ansible_net_memfree_mb' not in result['ansible_facts']" + +- name: Invalid facts subset value + ignore_errors: true + register: result + junipernetworks.junos.junos_facts: + gather_subset: test + +- name: Assertion + ansible.builtin.assert: + that: + - result.failed == true + - "'Subset must be one of' in result.msg" + +- name: Collect config facts from device in set format + register: result + junipernetworks.junos.junos_facts: + gather_subset: config + config_format: set + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - "'set system services netconf ssh' in result['ansible_facts']['ansible_net_config']" + +- name: Collect config facts from device in xml format + register: result + junipernetworks.junos.junos_facts: + gather_subset: config + config_format: xml + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - "'' in result['ansible_facts']['ansible_net_config']" + +- name: Collect config facts from device in json format + register: result + junipernetworks.junos.junos_facts: + gather_subset: config + config_format: json + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - "'{{ result['ansible_facts']['ansible_net_config']['configuration'][0]['system'][0]['service'][0]['netconf']\ + \ }}' is defined" + when: ansible_net_version == "15.1X49-D15.4" + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - "'ssh' in result['ansible_facts']['ansible_net_config']['configuration']['system']['services']['netconf']" + when: ansible_net_version == "17.3R1.10" + +- name: Collect config facts from device in text format + register: result + junipernetworks.junos.junos_facts: + gather_subset: config + config_format: text + +- name: Assertion + ansible.builtin.assert: + that: + - result.changed == false + - "'netconf {' in result['ansible_facts']['ansible_net_config']" + +- name: Collect list of available network resources for junos + register: result + junipernetworks.junos.junos_facts: + available_network_resources: true + gather_network_resources: all + +- name: Assert that correct available_network_resources returned + ansible.builtin.assert: + that: + - result.changed == false + - "{{ result['ansible_facts']['available_network_resources'] | symmetric_difference(result['ansible_facts']['ansible_net_gather_network_resources']) |length\ + \ == 0 }}" + +- name: Debug task + ansible.builtin.debug: msg="END netconf/facts.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tests/netconf/network_facts.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tests/netconf/network_facts.yaml new file mode 100644 index 00000000..f0d08f31 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_facts/tests/netconf/network_facts.yaml @@ -0,0 +1,124 @@ +--- +- ansible.builtin.debug: + msg="START cli_config/cli_basic.yaml on connection={{ ansible_connection + }}" + +- name: Reset acls + junipernetworks.junos.junos_acls: + state: deleted + +- name: Reset vlans + junipernetworks.junos.junos_vlans: + state: deleted + +- name: Reset lldp_global + junipernetworks.junos.junos_lldp_global: + state: deleted + +- name: Reset lldp_interfaces + junipernetworks.junos.junos_lldp_interfaces: + state: deleted + +- name: Reset logging_global + junipernetworks.junos.junos_logging_global: + state: deleted + +- name: Reset ntp_global + junipernetworks.junos.junos_ntp_global: + state: deleted + +- name: Reset ospf_interfaces + junipernetworks.junos.junos_ospf_interfaces: + state: deleted + +- name: Reset ospfv2 + junipernetworks.junos.junos_ospfv2: + state: deleted + +- name: Reset ospfv3 + junipernetworks.junos.junos_ospfv3: + state: deleted + +- name: Reset prefix_lists + junipernetworks.junos.junos_prefix_lists: + state: deleted + +- name: Reset routing_instances + junipernetworks.junos.junos_routing_instances: + state: deleted + +- name: Reset routing_options + junipernetworks.junos.junos_routing_options: + state: deleted + +- name: Reset security_policies + junipernetworks.junos.junos_security_policies: + state: deleted + +- name: Reset security_policies_global + junipernetworks.junos.junos_security_policies_global: + state: deleted + +- name: Reset security_zones + junipernetworks.junos.junos_security_zones: + state: deleted + +- name: Reset snmp_server + junipernetworks.junos.junos_snmp_server: + state: deleted + +- name: Reset static_routes + junipernetworks.junos.junos_static_routes: + state: deleted + +- name: Gather junipernetworks junos facts + junipernetworks.junos.junos_facts: + gather_subset: config + gather_network_resources: + - acls + - lldp_global + - lldp_interfaces + - logging_global + - ntp_global + - ospf_interfaces + - ospfv2 + - ospfv3 + - prefix_lists + - routing_instances + - routing_options + - security_policies + - security_policies_global + - security_zones + - snmp_server + - static_routes + - vlans + register: gather_resources + +- name: Display Facts + ansible.builtin.debug: + msg: "{{ gather_resources }}" + +- name: Assert that empty facts was generated + ansible.builtin.assert: + that: + - " gather_resources['ansible_facts']['ansible_network_resources']['acls'] == []" + - " gather_resources['ansible_facts']['ansible_network_resources']['lldp_global'] == {}" + - " gather_resources['ansible_facts']['ansible_network_resources']['lldp_interfaces'] == []" + - " gather_resources['ansible_facts']['ansible_network_resources']['logging_global'] == {}" + - " gather_resources['ansible_facts']['ansible_network_resources']['ntp_global'] == {}" + - " gather_resources['ansible_facts']['ansible_network_resources']['ospf_interfaces'] == []" + - " gather_resources['ansible_facts']['ansible_network_resources']['ospfv2'] == []" + - " gather_resources['ansible_facts']['ansible_network_resources']['ospfv3'] == []" + - " gather_resources['ansible_facts']['ansible_network_resources']['prefix_lists'] == []" + - " gather_resources['ansible_facts']['ansible_network_resources']['routing_instances'] == []" + - " gather_resources['ansible_facts']['ansible_network_resources']['routing_options'] == []" + - " gather_resources['ansible_facts']['ansible_network_resources']['security_policies'] == {}" + - " gather_resources['ansible_facts']['ansible_network_resources']['security_policies_global'] == {}" + - " gather_resources['ansible_facts']['ansible_network_resources']['security_zones'] == {}" + - " gather_resources['ansible_facts']['ansible_network_resources']['snmp_server'] == {}" + - " gather_resources['ansible_facts']['ansible_network_resources']['static_routes'] == []" + - " gather_resources['ansible_facts']['ansible_network_resources']['vlans'] == []" + +- ansible.builtin.debug: + msg="END cli_config/cli_basic.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..cf6e70db --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/_initial_config.yaml @@ -0,0 +1,13 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_hostname initial config on connection={{ ansible_connection }}" + +- name: Configure basic config relevant to ntp global + junipernetworks.junos.junos_config: + lines: + - set system host-name "vsrx12" + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_hostname initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..a8d6419d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/_reset_config.yaml @@ -0,0 +1,13 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_hostname reset config on connection={{ ansible_connection }}" + +- name: Reset the config releavent to ntp global resource + junipernetworks.junos.junos_config: + lines: + - delete system host-name + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_hostname reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/deleted.yaml new file mode 100644 index 00000000..00a4b968 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/deleted.yaml @@ -0,0 +1,33 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_hostname deleted integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Initial configuration + ansible.builtin.include_tasks: _initial_config.yaml + + - name: Set facts + ansible.builtin.set_fact: + config: {} + - name: Delete hostname config + junipernetworks.junos.junos_hostname: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config == result.after }}" + + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_hostname deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..ca0ed718 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/empty_config.yaml @@ -0,0 +1,66 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START junos_hostname empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_hostname: + config: + state: merged + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_hostname: + config: + state: replaced + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_hostname: + config: + state: overridden + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_hostname: + running_config: + state: parsed + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_hostname: + config: + state: rendered + +- name: Assertion + ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..6619c8d6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,156 @@ + + + + 18.4R1-S2.4 + + + + vagrant + 2000 + super-user + + $6$QiBkxU5N$QY11GzNuFs1sfY0OAacyJ/0WFmP9ciovUAmM425yYAo9OjccxvjWlEZNo8SeqCQxYeM86cfd9V.N1RiiHW2zN0 + + ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key + + + + + + $1$nq.N1UsY$JxA/ESAj3KuXseXE597gg0 + + ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key + + + + + + + + 830 + + + + + vsrx + + + * + + any + + + + + messages + + any + + + + authorization + + + + + interactive-commands + + interactive-commands + + + + + + + + https://ae1.juniper.net/junos/key_retrieval + + + + + 78.46.194.186 + + 2 + + + 78.44.194.186 + + + 172.44.194.186 + 10000 + 3 + + + + 48.46.194.186 + 34 + 2 + + rt1 + + + 48.45.194.186 + 34 + 2 + + + + 172.16.255.255 + rt1 + 50 + 3 + 200 + + + 192.16.255.255 + rt2 + 50 + 3 + 200 + + + +
224.0.0.1
+
+ 3000 + 2000 + + 300 + accept + + + 172.45.194.186 + rt1 + + + 171.45.194.186 + rt2 + +
+
+ + + fxp0 + + 0 + + + + + + + + + + + + rt1 + rt1 + + + rt2 + rt2 + + +
+
diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/gathered.yaml new file mode 100644 index 00000000..8c1a988a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/gathered.yaml @@ -0,0 +1,29 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START junos_hostname gathered integration tests on connection={{ ansible_connection }} + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + - name: Initial configuration + ansible.builtin.include_tasks: _initial_config.yaml + + - name: Gather interfaces facts using gathered state + register: result + junipernetworks.junos.junos_hostname: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ merged['gathered'] == result['gathered'] }}" + + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_hostname gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/merged.yaml new file mode 100644 index 00000000..8d8b2dfd --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/merged.yaml @@ -0,0 +1,59 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_hostname merged integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_hostname: &merged + config: + hostname: "vsrx" + + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['before'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['after'] == result['after'] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_hostname: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - name: Update the running configuration with providede configuration + junipernetworks.junos.junos_hostname: + config: + hostname: "vsrx14" + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['updated'] == result['after'] }}" + + tags: merged + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Reset configuration + ansible.builtin.debug: + msg: "END junos_hostname merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/overridden.yaml new file mode 100644 index 00000000..365df590 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/overridden.yaml @@ -0,0 +1,46 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_hostname overridden integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Initial configuration + ansible.builtin.include_tasks: _initial_config.yaml + + - name: Override configuration + junipernetworks.junos.junos_hostname: &overridden + config: + hostname: "vsrx14" + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['gathered'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['updated'] == result.after }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_hostname: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_hostname overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/parsed.yaml new file mode 100644 index 00000000..1591fec9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/parsed.yaml @@ -0,0 +1,23 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: + START junos_hostname parsed integration tests on connection={{ ansible_connection + }} + +- name: Parse externally provided hostname config to agnostic model + register: result + junipernetworks.junos.junos_hostname: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['parsed'] }}" + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_hostname parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/rendered.yaml new file mode 100644 index 00000000..83d10685 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/rendered.yaml @@ -0,0 +1,26 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START junos_hostname rendered integration tests on connection={{ + ansible_connection }} + +- name: Set facts + ansible.builtin.set_fact: + expected_rendered_output: 'vsrx14' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_hostname: + config: + hostname: "vsrx14" + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- name: Debug task + ansible.builtin.debug: + msg: END junos_hostname rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/replaced.yaml new file mode 100644 index 00000000..d7b35b96 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/replaced.yaml @@ -0,0 +1,45 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_hostname replaced integration tests on connection={{ ansible_connection }}" + +- block: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + + - name: Initial configuration + ansible.builtin.include_tasks: _initial_config.yaml + + - name: Override configuration + junipernetworks.junos.junos_hostname: &replaced + config: + hostname: "vsrx14" + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['gathered'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['updated'] == result.after }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_hostname: *replaced + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_hostname replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/rtt.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/rtt.yml new file mode 100644 index 00000000..c08892aa --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/tests/netconf/rtt.yml @@ -0,0 +1,60 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START junos_hostname round trip integration tests on connection={{ + ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_hostname: + config: + hostname: vsrx + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - hostname + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_hostname: + config: + hostname: "vsrx14" + state: replaced + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_hostname: + config: "{{ ansible_facts['network_resources']['hostname'] }}" + state: replaced + + - name: Assert that before dicts are correct + ansible.builtin.assert: + that: + - result.changed == True + - "{{ result['after'] == revert['before'] }}" + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + - result.changed == True + - "{{ base_config['after'] == revert['after'] }}" + always: + - name: Reset configuration + ansible.builtin.include_tasks: _reset_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_hostname round trip integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/vars/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/vars/main.yaml new file mode 100644 index 00000000..13d4c195 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_hostname/vars/main.yaml @@ -0,0 +1,12 @@ +--- +merged: + before: {} + + after: + hostname: "vsrx" + + updated: + hostname: "vsrx14" + + gathered: + hostname: "vsrx12" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/meta/main.yaml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..b2c608df --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/_initial_config.yaml @@ -0,0 +1,15 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START junos_interfaces initial config on connection={{ ansible_connection }}" + +- name: Configure basic config relevant to interfaces + junipernetworks.junos.junos_config: + lines: + - set interfaces fe-0/0/2 vlan-tagging + - set interfaces fe-0/0/2.10 vlan-id 10 + - set interfaces fe-0/0/2.11 vlan-id 11 + +- name: Debug task + ansible.builtin.debug: + msg: "END junos_interfaces initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/_remove_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/_remove_config.yaml new file mode 100644 index 00000000..875fd360 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/_remove_config.yaml @@ -0,0 +1,21 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: + Start junos_nterfaces deleted remove interface config ansible_connection={{ + ansible_connection }} + +- name: Setup - remove interface config + junipernetworks.junos.junos_config: + lines: + - delete interfaces ge-0/0/1 + - delete interfaces ge-0/0/2 + - delete interfaces ge-0/0/3 + - delete interfaces lo0 + - delete interfaces fe-0/0/2 + +- name: Debug task + ansible.builtin.debug: + msg: + End junos_nterfaces deleted remove interface config ansible_connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/deleted.yaml new file mode 100644 index 00000000..524476f2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/deleted.yaml @@ -0,0 +1,105 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: + START junos_interfaces deleted integration tests on connection={{ ansible_connection + }} + +- name: Reset configuration + ansible.builtin.include_tasks: _remove_config.yaml + +- name: Set facts + ansible.builtin.set_fact: + expected_deleted_output: + - name: fxp0 + enabled: true + - name: ge-0/0/2 + enabled: true + +- block: + - name: Configure initial state for interface + register: result + junipernetworks.junos.junos_interfaces: &id002 + config: + - name: ge-0/0/1 + description: Configured by Ansible - Interface 1 + mtu: 1024 + speed: 100m + enabled: false + duplex: full-duplex + hold_time: + up: 2000 + down: 2200 + + - name: ge-0/0/2 + description: Configured by Ansible - Interface 2 + mtu: 2048 + speed: 10m + hold_time: + up: 3000 + down: 3200 + units: + - name: 0 + description: "Logical interface UNIT 0" + state: merged + + - name: Delete the provided interface configuration from running configuration + register: result + junipernetworks.junos.junos_interfaces: &id001 + config: + - name: ge-0/0/1 + + - name: ge-0/0/2 + + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_deleted_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Delete the provided interface configuration from running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + + - name: Configure initial state for interface + register: result + junipernetworks.junos.junos_interfaces: *id002 + + - name: Delete the all interface configuration from running configuration + register: result + junipernetworks.junos.junos_interfaces: + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_deleted_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: Delete the all interface configuration from running configuration (IDEMPOTENT) + register: result + junipernetworks.junos.junos_interfaces: + state: deleted + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - name: Reset configuration + ansible.builtin.include_tasks: _remove_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_interfaces deleted integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..26d323fc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,53 @@ + + + + + + ge-0/0/1 + Configured by Ansible + + 100m + 1024 + + 2000 + 2200 + + full-duplex + + 0 + + + access + + vlan100 + + + + + + + ge-0/0/2 + Configured by Ansible + 400 + 10m + 2048 + + 3000 + 3200 + + + 0 + + + trunk + + vlan200 + vlan300 + + + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/gathered.yaml new file mode 100644 index 00000000..05e8b095 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/gathered.yaml @@ -0,0 +1,77 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: START junos_interfaces gathered integration tests on connection={{ + ansible_connection }} + +- name: Reset configuration + ansible.builtin.include_tasks: _remove_config.yaml + +- name: Set facts + ansible.builtin.set_fact: + expected_merged_output: + - name: ge-0/0/1 + description: Configured by Ansible - Interface 1 + mtu: 1024 + speed: 100m + enabled: false + duplex: full-duplex + hold_time: + up: 2000 + down: 2200 + + - name: ge-0/0/2 + description: Configured by Ansible - Interface 2 + mtu: 2048 + speed: 10m + enabled: true + hold_time: + up: 3000 + down: 3200 + + - name: fxp0 + enabled: true + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_interfaces: &id001 + config: + - name: ge-0/0/1 + description: Configured by Ansible - Interface 1 + mtu: 1024 + speed: 100m + enabled: false + duplex: full-duplex + hold_time: + up: 2000 + down: 2200 + - name: ge-0/0/2 + description: Configured by Ansible - Interface 2 + mtu: 2048 + speed: 10m + hold_time: + up: 3000 + down: 3200 + state: merged + + - name: Gather interfaces facts using gathered state + register: result + junipernetworks.junos.junos_interfaces: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + "{{ expected_merged_output | symmetric_difference(result['gathered']) |length\ + \ == 0 }}" + + always: + - name: Reset configuration + ansible.builtin.include_tasks: _remove_config.yaml + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_interfaces gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/groups.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/groups.yaml new file mode 100644 index 00000000..f6960275 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/groups.yaml @@ -0,0 +1,59 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: + START junos_interfaces groups integration tests on connection={{ ansible_connection + }} + +- name: Reset configuration + ansible.builtin.include_tasks: _remove_config.yaml + +- name: Set facts + ansible.builtin.set_fact: + expected_group_output: + - name: ge-0/0/11 + description: within test group + enabled: true + + - name: ge-0/0/12 + description: global interface config + enabled: true + + - name: fxp0 + enabled: true + +- name: Teardown delete interface configuration + junipernetworks.junos.junos_config: &id001 + lines: + - delete apply-groups test + - delete groups test interfaces ge-0/0/11 + - delete interfaces ge-0/0/12 + +- block: + - name: Setup interface configuration + junipernetworks.junos.junos_config: + lines: + - set groups test interfaces ge-0/0/11 description "within test group" + - set apply-groups test + - set interfaces ge-0/0/12 description "global interface config" + + - name: Get junos interfaces facts + register: result + junipernetworks.junos.junos_facts: + gather_subset: min + gather_network_resources: interfaces + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_group_output | symmetric_difference(result['ansible_facts']['ansible_network_resources']['interfaces'])|length\ + \ == 0 }}" + always: + - name: Teardown delete interface configuration + junipernetworks.junos.junos_config: *id001 + +- name: Debug task + ansible.builtin.debug: + msg: + END junos_interfaces merged integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/merged.yaml new file mode 100644 index 00000000..3d4f364e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/merged.yaml @@ -0,0 +1,94 @@ +--- +- ansible.builtin.debug: + msg: + START junos_interfaces merged integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _initial_config.yaml + +- ansible.builtin.set_fact: + expected_merged_output: + - name: ge-0/0/1 + description: Configured by Ansible - Interface 1 + mtu: 1024 + speed: 100m + enabled: false + duplex: full-duplex + hold_time: + up: 2000 + down: 2200 + + - name: ge-0/0/2 + description: Configured by Ansible - Interface 2 + mtu: 2048 + speed: 10m + enabled: true + hold_time: + up: 3000 + down: 3200 + + - enabled: true + name: fe-0/0/2 + units: + - description: "This is logical interface UNIT 10" + name: 10 + - description: "This is logical interface UNIT 11" + name: 11 + - name: fxp0 + enabled: true + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_interfaces: &id001 + config: + - name: ge-0/0/1 + description: Configured by Ansible - Interface 1 + mtu: 1024 + speed: 100m + enabled: false + duplex: full-duplex + hold_time: + up: 2000 + down: 2200 + + - name: ge-0/0/2 + description: Configured by Ansible - Interface 2 + mtu: 2048 + speed: 10m + hold_time: + up: 3000 + down: 3200 + - name: fe-0/0/2 + units: + - name: 10 + description: "This is logical interface UNIT 10" + - name: 11 + description: "This is logical interface UNIT 11" + state: merged + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_merged_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: + Merge the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_interfaces merged integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/overridden.yaml new file mode 100644 index 00000000..34b9be83 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/overridden.yaml @@ -0,0 +1,73 @@ +--- +- ansible.builtin.debug: + msg: + START junos_interfaces overridden integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.set_fact: + expected_overridden_output: + - name: ge-0/0/1 + description: Overridden by Ansible - Interface 1 + enabled: true + + - name: fxp0 + enabled: true + +- block: + - name: Configure initial state for interface + register: result + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/1 + description: Configured by Ansible - Interface 1 + mtu: 1024 + speed: 100m + enabled: false + duplex: full-duplex + hold_time: + up: 2000 + down: 2200 + + - name: ge-0/0/2 + description: Configured by Ansible - Interface 2 + mtu: 2048 + speed: 10m + enabled: false + hold_time: + up: 3000 + down: 3200 + state: merged + + - name: Override the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_interfaces: &id001 + config: + - name: ge-0/0/1 + description: Overridden by Ansible - Interface 1 + state: overridden + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_overridden_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Override the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_interfaces overridden integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/parsed.yaml new file mode 100644 index 00000000..0a1c50b1 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/parsed.yaml @@ -0,0 +1,42 @@ +--- +- ansible.builtin.debug: + msg: + START junos_interfaces parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + - description: Configured by Ansible + duplex: full-duplex + enabled: false + hold_time: + down: 2200 + up: 2000 + mtu: 1024 + name: ge-0/0/1 + speed: 100m + + - description: Configured by Ansible + enabled: true + hold_time: + down: 3200 + up: 3000 + mtu: 2048 + name: ge-0/0/2 + speed: 10m + +- name: Parse externally provided interfaces config to agnostic model + register: result + junipernetworks.junos.junos_interfaces: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output | symmetric_difference(result['parsed']) |length ==\ + \ 0 }}" +- ansible.builtin.debug: + msg: + END junos_interfaces parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/rendered.yaml new file mode 100644 index 00000000..bee5568a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/rendered.yaml @@ -0,0 +1,29 @@ +--- +- ansible.builtin.debug: + msg: START junos_interfaces rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: 'ge-0/0/2Configured by Ansible20m204832003200' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/2 + description: Configured by Ansible + mtu: 2048 + speed: 20m + hold_time: + up: 3200 + down: 3200 + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_interfaces rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/replaced.yaml new file mode 100644 index 00000000..bcec623b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/replaced.yaml @@ -0,0 +1,86 @@ +--- +- ansible.builtin.debug: + msg: + START junos_interfaces replaced integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.set_fact: + expected_replaced_output: + - name: ge-0/0/1 + description: Replaced by Ansible - Interface 1 + mtu: 2048 + speed: 10m + enabled: true + + - name: ge-0/0/2 + description: Configured by Ansible - Interface 2 + mtu: 2048 + speed: 10m + enabled: true + hold_time: + up: 3000 + down: 3200 + + - name: fxp0 + enabled: true + +- block: + - name: Configure initial state for interface + register: result + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/1 + description: Configured by Ansible - Interface 1 + mtu: 1024 + speed: 100m + enabled: false + duplex: full-duplex + hold_time: + up: 2000 + down: 2200 + + - name: ge-0/0/2 + description: Configured by Ansible - Interface 2 + mtu: 2048 + speed: 10m + hold_time: + up: 3000 + down: 3200 + state: merged + + - name: Replace the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_interfaces: &id001 + config: + - name: ge-0/0/1 + description: Replaced by Ansible - Interface 1 + mtu: 2048 + speed: 10m + enabled: true + state: replaced + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_replaced_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Replace the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_interfaces replaced integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/rtt.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/rtt.yaml new file mode 100644 index 00000000..cb8bb6c2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_interfaces/tests/netconf/rtt.yaml @@ -0,0 +1,105 @@ +--- +- ansible.builtin.debug: + msg: + START junos_interfaces round trip integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.set_fact: + expected_revert_output: + - name: ge-0/0/1 + description: Configured by Ansible - Interface 1 + mtu: 1024 + speed: 100m + enabled: false + duplex: full-duplex + hold_time: + up: 2000 + down: 2200 + + - name: ge-0/0/2 + description: Configured by Ansible - Interface 2 + mtu: 2048 + speed: 10m + enabled: true + hold_time: + up: 3000 + down: 3200 + + - name: fxp0 + enabled: true + +- block: + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/1 + description: Configured by Ansible - Interface 1 + mtu: 1024 + speed: 100m + enabled: false + duplex: full-duplex + hold_time: + up: 2000 + down: 2200 + + - name: ge-0/0/2 + description: Configured by Ansible - Interface 2 + mtu: 2048 + speed: 10m + enabled: true + hold_time: + up: 3000 + down: 3200 + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - interfaces + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/1 + description: Configured by Ansible - Interface 1 modified + mtu: 3048 + speed: 10m + enabled: true + duplex: half-duplex + hold_time: + up: 3000 + down: 2200 + + - name: ge-0/0/2 + description: Configured by Ansible - Interface 2 modified + mtu: 4048 + speed: 100m + enabled: false + hold_time: + up: 4000 + down: 5200 + state: merged + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_interfaces: + config: "{{ ansible_facts['network_resources']['interfaces'] }}" + state: replaced + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + "{{ expected_revert_output | symmetric_difference(revert['after'])\ + \ |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/meta/main.yaml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tasks/netconf.yaml new file mode 100644 index 00000000..b88eee1c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/_base_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/_base_config.yaml new file mode 100644 index 00000000..24bc9e1d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/_base_config.yaml @@ -0,0 +1,18 @@ +--- +- ansible.builtin.debug: + msg: + Start junos_l2_interfaces base config ansible_connection={{ ansible_connection + }} + +- name: Configure vlan + junipernetworks.junos.junos_config: + lines: + - set vlans vlan100 vlan-id 100 + - set vlans vlan200 vlan-id 200 + - set vlans vlan300 vlan-id 300 + - set vlans vlan400 vlan-id 400 + +- ansible.builtin.debug: + msg: + End junos_l2_interfaces base config ansible_connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/_remove_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/_remove_config.yaml new file mode 100644 index 00000000..2b814d63 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/_remove_config.yaml @@ -0,0 +1,22 @@ +--- +- ansible.builtin.debug: + msg: + Start junos_l2_interfaces deleted remove l2 interface config ansible_connection={{ + ansible_connection }} + +- name: Setup - remove interface config + junipernetworks.junos.junos_config: + lines: + - delete interfaces ge-0/0/1 + - delete interfaces ge-0/0/2 + - delete interfaces ge-0/0/3 + - delete interfaces lo0 + - delete vlans vlan100 + - delete vlans vlan200 + - delete vlans vlan300 + - delete vlans vlan400 + +- ansible.builtin.debug: + msg: + End junos_l2_interfaces deleted remove l2 interface config ansible_connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/deleted.yaml new file mode 100644 index 00000000..d26fa62d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/deleted.yaml @@ -0,0 +1,90 @@ +--- +- ansible.builtin.debug: + msg: + START junos_l2_interfaces deleted integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_deleted_output: + - name: ge-0/0/1 + unit: 0 + enhanced_layer: true + access: + vlan: vlan100 + +- block: + - name: Configure initial state for l2 interface + register: result + junipernetworks.junos.junos_l2_interfaces: &id002 + config: + - name: ge-0/0/1 + access: + vlan: vlan100 + + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan200 + - vlan300 + native_vlan: "400" + state: merged + + - name: Delete the provided l2 interface configuration from running configuration + register: result + junipernetworks.junos.junos_l2_interfaces: &id001 + config: + - name: ge-0/0/2 + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_deleted_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Delete the provided l2 interface configuration from running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_l2_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + + - name: Configure initial state for interface + register: result + junipernetworks.junos.junos_l2_interfaces: *id002 + + - name: Delete the all l2 interface configuration from running configuration + register: result + junipernetworks.junos.junos_l2_interfaces: + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ result['after'] == [] }}" + + - name: Delete the all l2 interface configuration from running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_l2_interfaces: + state: deleted + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_l2_interfaces deleted integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..26d323fc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,53 @@ + + + + + + ge-0/0/1 + Configured by Ansible + + 100m + 1024 + + 2000 + 2200 + + full-duplex + + 0 + + + access + + vlan100 + + + + + + + ge-0/0/2 + Configured by Ansible + 400 + 10m + 2048 + + 3000 + 3200 + + + 0 + + + trunk + + vlan200 + vlan300 + + + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/gathered.yaml new file mode 100644 index 00000000..1d66a975 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/gathered.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START junos_l2_interfaces gathered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_merged_output: + - name: ge-0/0/1 + access: + vlan: vlan100 + enhanced_layer: true + unit: 0 + + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan200 + - vlan300 + native_vlan: "400" + enhanced_layer: true + unit: 0 + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/1 + access: + vlan: vlan100 + + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan200 + - vlan300 + native_vlan: "400" + state: merged + + - name: Gather l2_interfaces facts using gathered state + register: result + junipernetworks.junos.junos_l2_interfaces: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + "{{ expected_merged_output | symmetric_difference(result['gathered']) |length\ + \ == 0 }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_l2_interfaces gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/merged.yaml new file mode 100644 index 00000000..426f565e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/merged.yaml @@ -0,0 +1,67 @@ +--- +- ansible.builtin.debug: + msg: + START junos_l2_interfaces merged integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_merged_output: + - name: ge-0/0/1 + access: + vlan: vlan100 + enhanced_layer: true + unit: 0 + + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan200 + - vlan300 + native_vlan: "400" + enhanced_layer: true + unit: 0 + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_l2_interfaces: &id001 + config: + - name: ge-0/0/1 + access: + vlan: vlan100 + + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan200 + - vlan300 + native_vlan: "400" + state: merged + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_merged_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: + Merge the provided l2 interface configuration from running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_l2_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_l2_interfaces merged integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/overridden.yaml new file mode 100644 index 00000000..b418b355 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/overridden.yaml @@ -0,0 +1,71 @@ +--- +- ansible.builtin.debug: + msg: + START junos_l2_interfaces override integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_overridden_output: + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan100 + native_vlan: "200" + enhanced_layer: true + unit: 0 + +- block: + - name: Setup initial l2 configuration + register: result + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/1 + access: + vlan: vlan100 + + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan200 + - vlan300 + native_vlan: "400" + state: overridden + + - name: Override the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_l2_interfaces: &id001 + config: + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan100 + native_vlan: "200" + state: overridden + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_overridden_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Override the provided l2 interface configuration from running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_l2_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_l2_interfaces override integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/parsed.yaml new file mode 100644 index 00000000..805d43dd --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/parsed.yaml @@ -0,0 +1,38 @@ +--- +- ansible.builtin.debug: + msg: + START junos_l2_interfaces parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + - name: ge-0/0/1 + access: + vlan: vlan100 + enhanced_layer: true + unit: 0 + + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan200 + - vlan300 + native_vlan: "400" + enhanced_layer: true + unit: 0 + +- name: Parse externally provided interfaces config to agnostic model + register: result + junipernetworks.junos.junos_l2_interfaces: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output | symmetric_difference(result['parsed']) |length ==\ + \ 0 }}" +- ansible.builtin.debug: + msg: + END junos_l2_interfaces parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/rendered.yaml new file mode 100644 index 00000000..ca1d574f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/rendered.yaml @@ -0,0 +1,63 @@ +--- +- ansible.builtin.debug: + msg: START junos_l2_interfaces rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: ' + + ge-0/0/1 + + 0 + + + access + + vlan100 + + + + + + + ge-0/0/2 + + 0 + + + trunk + + vlan200 + vlan300 + + + + + 400 + + ' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/1 + access: + vlan: vlan100 + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan200 + - vlan300 + native_vlan: "400" + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_l2_interfaces rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/replaced.yaml new file mode 100644 index 00000000..af268450 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/replaced.yaml @@ -0,0 +1,67 @@ +--- +- ansible.builtin.debug: + msg: + START junos_l2_interfaces replaced integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_replaced_output: + - name: ge-0/0/1 + trunk: + allowed_vlans: + - vlan100 + - vlan300 + native_vlan: "400" + enhanced_layer: true + unit: 0 + + - name: ge-0/0/2 + access: + vlan: vlan200 + enhanced_layer: true + unit: 0 + +- block: + - name: Replace the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_l2_interfaces: &id001 + config: + - name: ge-0/0/1 + trunk: + allowed_vlans: + - vlan100 + - vlan300 + native_vlan: "400" + + - name: ge-0/0/2 + access: + vlan: vlan200 + state: replaced + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_replaced_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Replace the provided interface configuration from running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_l2_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_l2_interfaces replaced integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/rtt.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/rtt.yml new file mode 100644 index 00000000..f934983c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l2_interfaces/tests/netconf/rtt.yml @@ -0,0 +1,59 @@ +--- +- ansible.builtin.debug: + msg: START junos_l2_interfaces round trip integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- block: + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan100 + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - l2_interfaces + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/2 + trunk: + allowed_vlans: + - vlan100 + native_vlan: "200" + state: overridden + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_l2_interfaces: + config: "{{ ansible_facts['network_resources']['l2_interfaces'] }}" + state: overridden + + - name: Assert that config was reverted + ansible.builtin.assert: + that: "{{ base_config['after'] | symmetric_difference(revert['after'])\ + \ |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_l2_interfaces round trip integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/meta/main.yaml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tasks/main.yaml new file mode 100644 index 00000000..a6fc560a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tasks/netconf.yaml new file mode 100644 index 00000000..7be9e860 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tasks/netconf.yaml @@ -0,0 +1,19 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..02790ace --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,56 @@ + + + + + + ge-1/0/0 + + 0 + + + 1500 +
+ 192.168.100.1/24 +
+
+ 10.200.16.20/24 +
+
+ +
+
+
+ + ge-2/0/0 + + 0 + + +
+ 192.168.100.2/24 +
+
+ 10.200.16.21/24 +
+
+ +
+
+ + 1 + + +
+ 192.178.100.2/24 +
+
+ 10.210.16.21/24 +
+
+ +
+
+
+
+
+
diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/junos_l3_interfaces.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/junos_l3_interfaces.yml new file mode 100644 index 00000000..7684629a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/junos_l3_interfaces.yml @@ -0,0 +1,133 @@ +--- +- name: bootstrap interfaces + register: result + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-1/0/0 + ipv4: + - address: 192.168.100.1/24 + + - address: 10.200.16.20/24 + + - name: ge-2/0/0 + ipv4: + - address: 192.168.100.2/24 + + - address: 10.200.16.21/24 + + - name: ge-3/0/0 + ipv4: + - address: 192.168.100.3/24 + + - address: 10.200.16.22/24 + state: replaced + +- ansible.builtin.assert: + that: + - result is changed + - "'192.168.100.1/24' in result.commands[0]" + - "'10.200.16.20/24' in result.commands[0]" + - result.after[0].name == 'ge-1/0/0' + - result.after[0].ipv4[0]['address'] == '192.168.100.1/24' + - result.after[0].ipv4[1]['address'] == '10.200.16.20/24' + +- name: bootstrap interfaces (idempotent) + register: result + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-1/0/0 + ipv4: + - address: 192.168.100.1/24 + + - address: 10.200.16.20/24 + + - name: ge-2/0/0 + ipv4: + - address: 192.168.100.2/24 + + - address: 10.200.16.21/24 + + - name: ge-3/0/0 + ipv4: + - address: 192.168.100.3/24 + + - address: 10.200.16.22/24 + state: replaced + +- ansible.builtin.assert: + that: + - result is not changed + +- name: Gather l3_interfaces facts using gathered state + register: result + junipernetworks.junos.junos_l3_interfaces: + state: gathered + +- name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + - result.gathered[0].name == 'ge-1/0/0' + - result.gathered[0].ipv4[0]['address'] == '192.168.100.1/24' + - result.gathered[0].ipv4[1]['address'] == '10.200.16.20/24' + - result.gathered[1].name == 'ge-2/0/0' + - result.gathered[1].ipv4[0]['address'] == '192.168.100.2/24' + - result.gathered[1].ipv4[1]['address'] == '10.200.16.21/24' + - result.gathered[2].name == 'ge-3/0/0' + - result.gathered[2].ipv4[0]['address'] == '192.168.100.3/24' + - result.gathered[2].ipv4[1]['address'] == '10.200.16.22/24' + +- name: Add another interface ip + register: result + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-1/0/0 + mtu: 1500 + ipv4: + - address: 100.64.0.1/10 + + - address: 100.64.0.2/10 + state: merged + +- ansible.builtin.assert: + that: + - result is changed + - "'100.64.0.1/10' in result.commands[0]" + - "'100.64.0.2/10' in result.commands[0]" + - result.after[0].name == 'ge-1/0/0' + - result.after[0].ipv4[0]['address'] == '192.168.100.1/24' + - result.after[0].ipv4[1]['address'] == '10.200.16.20/24' + - result.after[0].ipv4[2]['address'] == '100.64.0.1/10' + - result.after[0].ipv4[3]['address'] == '100.64.0.2/10' + - result.after[0].mtu == '1500' + +- name: Delete ge-2/0/0 interface config + register: result + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-2/0/0 + state: deleted + +- ansible.builtin.assert: + that: + - result is changed + - "'ge-2/0/00' in result.commands[0]" + +- name: Override all config + register: result + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-1/0/0 + ipv4: + - address: dhcp + + - name: fxp0 + ipv4: + - address: dhcp + state: overridden + +- ansible.builtin.assert: + that: + - result is changed + - "'fxp00'\ + \ in result.commands[0]" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/parsed.yaml new file mode 100644 index 00000000..266d15b3 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/parsed.yaml @@ -0,0 +1,45 @@ +--- +- ansible.builtin.debug: + msg: + START junos_l3_interfaces parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + - name: ge-1/0/0 + mtu: 1500 + ipv4: + - address: 192.168.100.1/24 + + - address: 10.200.16.20/24 + unit: 0 + + - name: ge-2/0/0 + ipv4: + - address: 192.168.100.2/24 + + - address: 10.200.16.21/24 + unit: 0 + + - name: ge-2/0/0 + ipv4: + - address: 192.178.100.2/24 + + - address: 10.210.16.21/24 + unit: 1 + +- name: Parse externally provided interfaces config to agnostic model + register: result + junipernetworks.junos.junos_l3_interfaces: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output | symmetric_difference(result['parsed']) |length ==\ + \ 0 }}" +- ansible.builtin.debug: + msg: + END junos_l3_interfaces parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/rendered.yaml new file mode 100644 index 00000000..f0756bb8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_l3_interfaces/tests/netconf/rendered.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: START junos_l3_interfaces rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: ' + + ge-0/0/1 + + 0 + + + access + + vlan100 + + + + + + + ge-0/0/2 + + 0 + + + trunk + + vlan200 + vlan300 + + + + + 400 + + ' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_l3_interfaces: + config: + - name: ge-1/0/0 + ipv4: + - address: 192.168.100.1/24 + - address: 10.200.16.20/24 + unit: 0 + + - name: ge-2/0/0 + ipv4: + - address: 192.168.100.2/24 + - address: 10.200.16.21/24 + unit: 0 + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_l3_interfaces rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tasks/main.yaml new file mode 100644 index 00000000..8248d55c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf task + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/_remove_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/_remove_config.yaml new file mode 100644 index 00000000..e15b129d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/_remove_config.yaml @@ -0,0 +1,15 @@ +--- +- ansible.builtin.debug: + msg: + Start junos_lacp deleted remove lacp config ansible_connection={{ ansible_connection + }} + +- name: Setup - remove lacp config + junipernetworks.junos.junos_config: + lines: + - delete chassis aggregated-devices ethernet lacp + +- ansible.builtin.debug: + msg: + End junos_lacp deleted remove lacp config ansible_connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/deleted.yaml new file mode 100644 index 00000000..31b72d41 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/deleted.yaml @@ -0,0 +1,47 @@ +--- +- ansible.builtin.debug: + msg: START junos_lacp deleted lacp tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.set_fact: + expected_deleted_output: [] + +- block: + - name: Merge global LACP attributes + register: result + junipernetworks.junos.junos_lacp: + config: + system_priority: 63 + link_protection: revertive + state: merged + + - name: Delete global lacp attributes + register: result + junipernetworks.junos.junos_lacp: &id001 + config: + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ result['after'] == {} }}" + + - name: + Delete the provided interface configuration from running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lacp: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lacp deleted lacp integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..88c8729f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,16 @@ + + + + + + + + 63 + + + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/gathered.yaml new file mode 100644 index 00000000..bc3effbc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/gathered.yaml @@ -0,0 +1,37 @@ +--- +- ansible.builtin.debug: + msg: START junos_lacp gathered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.set_fact: + expected_merged_output: + system_priority: 63 + link_protection: revertive + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lacp: &id001 + config: + system_priority: 63 + link_protection: revertive + state: merged + + - name: Gather lacp facts using gathered state + register: result + junipernetworks.junos.junos_lacp: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ expected_merged_output == result['gathered'] }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lacp gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/merged.yaml new file mode 100644 index 00000000..9776ac8f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/merged.yaml @@ -0,0 +1,45 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lacp merged integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.set_fact: + expected_merged_output: + - system_priority: 63 + link_protection: revertive + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lacp: &id001 + config: + system_priority: 63 + link_protection: revertive + state: merged + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_merged_output | symmetric_difference([result['after']])\ + \ |length == 0 }}" + + - name: + Merge the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lacp: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lacp merged integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/parsed.yaml new file mode 100644 index 00000000..7f297c08 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/parsed.yaml @@ -0,0 +1,25 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lacp parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + link_protection: revertive + system_priority: 63 + +- name: Parse externally provided lacp config to agnostic model + register: result + junipernetworks.junos.junos_lacp: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output == result['parsed'] }}" +- ansible.builtin.debug: + msg: + END junos_lacp parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/rendered.yaml new file mode 100644 index 00000000..6935d490 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/rendered.yaml @@ -0,0 +1,24 @@ +--- +- ansible.builtin.debug: + msg: START junos_lacp rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: '63' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_lacp: + config: + system_priority: 63 + link_protection: revertive + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_lacp rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/replaced.yaml new file mode 100644 index 00000000..d898a551 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/replaced.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lacp replaced integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.set_fact: + expected_replaced_output: + - system_priority: 73 + +- block: + - name: Set initial config + junipernetworks.junos.junos_lacp: + config: + system_priority: 73 + link_protection: revertive + state: replaced + + - name: Replace the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lacp: &id001 + config: + system_priority: 73 + state: replaced + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_replaced_output | symmetric_difference([result['after']])\ + \ |length == 0 }}" + + - name: + Replace the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lacp: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lacp replaced integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/rtt.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/rtt.yaml new file mode 100644 index 00000000..eca82093 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp/tests/netconf/rtt.yaml @@ -0,0 +1,58 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lacp RTT integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.set_fact: + expected_revert_output: + - system_priority: 63 + link_protection: non-revertive + +- block: + - name: Apply the provided configuration (base config) + junipernetworks.junos.junos_lacp: + config: + system_priority: 63 + link_protection: non-revertive + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - lacp + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_lacp: + config: + system_priority: 73 + link_protection: revertive + state: replaced + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_lacp: + config: "{{ ansible_facts['network_resources']['lacp'] }}" + state: replaced + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + "{{ expected_revert_output | symmetric_difference([revert['after']])\ + \ |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lacp RTT integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/meta/main.yaml new file mode 100644 index 00000000..7f867d73 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/meta/main.yaml @@ -0,0 +1,2 @@ +--- +dependencies: diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tasks/main.yaml new file mode 100644 index 00000000..61aebceb --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf play + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/_base_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/_base_config.yaml new file mode 100644 index 00000000..56113e5d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/_base_config.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: + Start junos_lacp_interfaces base config ansible_connection={{ ansible_connection + }} + +- name: Configure base lag interface + junipernetworks.junos.junos_config: + lines: + - set interfaces ae1 description "Configured by Ansible" + - set interfaces ae2 description "Configured by Ansible" + - set interfaces ge-0/0/1 ether-options 802.3ad ae1 + - set interfaces ge-0/0/2 ether-options 802.3ad ae1 + - set interfaces ge-0/0/3 ether-options 802.3ad ae2 + - set interfaces ge-0/0/4 ether-options 802.3ad ae2 + +- ansible.builtin.debug: + msg: + End junos_lacp_interfaces base config ansible_connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/_remove_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/_remove_config.yaml new file mode 100644 index 00000000..c180dc0a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/_remove_config.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: + Start junos_nterfaces deleted remove interface config ansible_connection={{ + ansible_connection }} + +- name: Setup - remove interface config + junipernetworks.junos.junos_config: + lines: + - delete interfaces ae1 + - delete interfaces ae2 + - delete interfaces ge-0/0/1 + - delete interfaces ge-0/0/2 + - delete interfaces ge-0/0/3 + - delete interfaces ge-0/0/4 + - delete interfaces lo0 + +- ansible.builtin.debug: + msg: + End junos_nterfaces deleted remove interface config ansible_connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/deleted.yaml new file mode 100644 index 00000000..2eec2f58 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/deleted.yaml @@ -0,0 +1,110 @@ +--- +- ansible.builtin.debug: + msg: START junos_lacp_interfaces deleted integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_deleted_output: + - name: ae2 + period: slow + sync_reset: disable + system: + priority: 200 + mac: + address: 00:00:00:00:00:04 + + - name: ge-0/0/3 + port_priority: 300 + +- block: + - name: Configure initial state for interface + register: result + junipernetworks.junos.junos_lacp_interfaces: &id002 + config: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + + - name: ge-0/0/1 + port_priority: 100 + force_up: true + + - name: ae2 + period: slow + sync_reset: disable + system: + priority: 200 + mac: + address: 00:00:00:00:00:04 + + - name: ge-0/0/3 + port_priority: 300 + force_up: false + state: merged + + - name: Delete the provided interface configuration from running configuration + register: result + junipernetworks.junos.junos_lacp_interfaces: &id001 + config: + - name: ae1 + + - name: ge-0/0/1 + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_deleted_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Delete the provided lacp interface configuration from running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lacp_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + + - name: Configure initial state for interface + register: result + junipernetworks.junos.junos_lacp_interfaces: *id002 + + - name: Delete the all lacp interface configuration from running configuration + register: result + junipernetworks.junos.junos_lacp_interfaces: + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ result['after'] == [] }}" + + - name: + Delete the all lacp interfaces configuration from running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lacp_interfaces: + state: deleted + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lacp_interfaces deleted integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..d7bd3d84 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,130 @@ + + + + + + ge-0/0/1 + + + + + 100 + + ae1 + + + + + ge-0/0/2 + + + ae1 + + + + + ge-0/0/3 + + + ae2 + + + + + ge-0/0/4 + + + ae2 + + + + + ge-1/0/0 + + 0 + + +
+ 192.168.100.1/24 +
+
+ 10.200.16.20/24 +
+
+ +
+
+
+ + ge-2/0/0 + + 0 + + +
+ 192.168.100.2/24 +
+
+ 10.200.16.21/24 +
+
+ +
+
+
+ + ge-3/0/0 + + 0 + + +
+ 192.168.100.3/24 +
+
+ 10.200.16.22/24 +
+
+ +
+
+
+ + ae1 + Configured by Ansible + + + fast + enable + 100 + 00:00:00:00:00:02 + + + + + ae2 + Configured by Ansible + + + em1 + TEST + + + fxp0 + ANSIBLE + 1g + automatic + + 0 + + +
+ 10.8.38.38/24 +
+
+
+
+
+
+
+
diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/gathered.yaml new file mode 100644 index 00000000..87e3ac1b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/gathered.yaml @@ -0,0 +1,59 @@ +--- +- ansible.builtin.debug: + msg: START junos_lacp_interfaces gathered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_merged_output: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + + - name: ge-0/0/1 + port_priority: 100 + force_up: true + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lacp_interfaces: &id001 + config: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + + - name: ge-0/0/1 + port_priority: 100 + force_up: true + state: merged + + - name: Gather interfaces facts using gathered state + register: result + junipernetworks.junos.junos_lacp_interfaces: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + "{{ expected_merged_output | symmetric_difference(result['gathered']) |length\ + \ == 0 }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lacp_interfaces gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/merged.yaml new file mode 100644 index 00000000..5b057b7a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/merged.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lacp_interfaces merged integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_merged_output: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + + - name: ge-0/0/1 + port_priority: 100 + force_up: true + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lacp_interfaces: &id001 + config: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + + - name: ge-0/0/1 + port_priority: 100 + force_up: true + state: merged + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_merged_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: + Merge the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lacp_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lacp_interfaces merged integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/overridden.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/overridden.yml new file mode 100644 index 00000000..4f3e33f7 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/overridden.yml @@ -0,0 +1,85 @@ +--- +- ansible.builtin.debug: + msg: START junos_lacp_interfaces overide integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_overridden_output: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:01 + +- block: + - name: Configure initial state for lacp interface + register: result + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + + - name: ge-0/0/1 + port_priority: 100 + force_up: true + + - name: ae2 + period: slow + sync_reset: disable + system: + priority: 200 + mac: + address: 00:00:00:00:00:04 + + - name: ge-0/0/3 + port_priority: 300 + force_up: false + state: merged + + - name: Override the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lacp_interfaces: &id001 + config: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:01 + state: overridden + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_overridden_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Override the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lacp_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lacp_interfaces override integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/parsed.yaml new file mode 100644 index 00000000..52bf84ad --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/parsed.yaml @@ -0,0 +1,35 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lacp_interfaces parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + + - name: ge-0/0/1 + port_priority: 100 + force_up: true + +- name: Parse externally provided interfaces config to agnostic model + register: result + junipernetworks.junos.junos_lacp_interfaces: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output | symmetric_difference(result['parsed']) |length ==\ + \ 0 }}" +- ansible.builtin.debug: + msg: + END junos_lacp_interfaces parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/rendered.yaml new file mode 100644 index 00000000..99299abd --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/rendered.yaml @@ -0,0 +1,33 @@ +--- +- ansible.builtin.debug: + msg: START junos_lacp_interfaces rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: 'ae1fastenable00:00:00:00:00:02100ge-0/0/1100' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + + - name: ge-0/0/1 + port_priority: 100 + force_up: true + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_lacp_interfaces rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/replaced.yaml new file mode 100644 index 00000000..34fc141c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/replaced.yaml @@ -0,0 +1,117 @@ +--- +- ansible.builtin.debug: + msg: START junos_lacp_interfaces replaced integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_replaced_output: + - name: ae1 + period: slow + sync_reset: disable + system: + priority: 10 + mac: + address: 00:00:00:00:00:03 + + - name: ae2 + period: fast + system: + priority: 300 + + - name: ge-0/0/1 + force_up: true + port_priority: 100 + + - name: ge-0/0/2 + port_priority: 250 + + - name: ge-0/0/3 + port_priority: 300 + + - name: ge-0/0/4 + port_priority: 400 + force_up: true + +- block: + - name: Configure initial state for lacp interface + register: result + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + + - name: ge-0/0/1 + port_priority: 100 + force_up: true + + - name: ae2 + period: slow + sync_reset: disable + system: + priority: 200 + mac: + address: 00:00:00:00:00:04 + + - name: ge-0/0/3 + port_priority: 300 + force_up: false + state: merged + + - name: Replace the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lacp_interfaces: &id001 + config: + - name: ae1 + period: slow + sync_reset: disable + system: + priority: 10 + mac: + address: 00:00:00:00:00:03 + + - name: ge-0/0/2 + port_priority: 250 + force_up: false + + - name: ae2 + period: fast + system: + priority: 300 + + - name: ge-0/0/4 + port_priority: 400 + force_up: true + state: replaced + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_replaced_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Replace the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lacp_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lacp_interfaces replaced integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/rtt.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/rtt.yaml new file mode 100644 index 00000000..11c497b2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lacp_interfaces/tests/netconf/rtt.yaml @@ -0,0 +1,81 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lacp_interfaces round trip integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_revert_output: &base_config + - name: ae1 + period: slow + sync_reset: disable + system: + priority: 10 + mac: + address: 00:00:00:00:00:03 + + - name: ae2 + period: fast + system: + priority: 300 + + - name: ge-0/0/2 + port_priority: 250 + force_up: true + + - name: ge-0/0/4 + port_priority: 400 + force_up: true + +- block: + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_lacp_interfaces: + config: *base_config + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - lacp_interfaces + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae1 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:01 + state: merged + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_lacp_interfaces: + config: "{{ ansible_facts['network_resources']['lacp_interfaces'] }}" + state: overridden + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + "{{ expected_revert_output | symmetric_difference(revert['after'])\ + \ |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END junos_lacp_interfaces round trip integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/meta/main.yaml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tasks/main.yaml new file mode 100644 index 00000000..a6fc560a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/_base_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/_base_config.yaml new file mode 100644 index 00000000..8239e190 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/_base_config.yaml @@ -0,0 +1,16 @@ +--- +- ansible.builtin.debug: + msg: + Start junos_lag_interfaces base config ansible_connection={{ ansible_connection + }} + +- name: Configure base lag interface + junipernetworks.junos.junos_config: + lines: + - set interfaces ae1 description "Configured by Ansible" + - set interfaces ae2 description "Configured by Ansible" + +- ansible.builtin.debug: + msg: + End junos_lag_interfaces base config ansible_connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/_remove_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/_remove_config.yaml new file mode 100644 index 00000000..acdbafba --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/_remove_config.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: + Start junos_lag_interfaces teardown ansible_connection={{ ansible_connection + }} + +- name: Remove interface config + junipernetworks.junos.junos_config: + lines: + - delete interfaces ge-0/0/1 + - delete interfaces ge-0/0/2 + - delete interfaces ge-0/0/3 + - delete interfaces ge-0/0/4 + - delete interfaces ae1 + - delete interfaces ae2 + +- ansible.builtin.debug: + msg: + End junos_lag_interfaces teardown ansible_connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/deleted.yaml new file mode 100644 index 00000000..6877a89f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/deleted.yaml @@ -0,0 +1,101 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lag_interfaces deleted integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_deleted_1_output: + - name: ae1 + members: + - member: ge-0/0/1 + ether_option_type: "ether" + + - member: ge-0/0/2 + ether_option_type: "ether" + mode: active + expected_deleted_2_output: [] + +- block: + - name: Base LAG configuration + junipernetworks.junos.junos_lag_interfaces: &id002 + config: + - name: ae1 + members: + - member: ge-0/0/1 + + - member: ge-0/0/2 + mode: active + + - name: ae2 + link_protection: true + members: + - member: ge-0/0/3 + link_type: primary + + - member: ge-0/0/4 + link_type: backup + mode: passive + state: merged + + - name: Delete the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lag_interfaces: &id001 + config: + - name: ae2 + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_deleted_1_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Delete the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lag_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + + - name: Configure initial state for lag interface + register: result + junipernetworks.junos.junos_lag_interfaces: *id002 + + - name: Delete the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lag_interfaces: + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_deleted_2_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Delete the provided configuration with the exisiting running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lag_interfaces: + state: deleted + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lag_interfaces deleted integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..e0f9e964 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,235 @@ + + + + + + ge-0/0/0 + + flexible-ethernet-services + + 100 + 100 + + + + + + + + + 1500 + + + + + 200 + 101 + + + 1350 +
+ 10.10.10.21/31 +
+
+ + 1350 +
+ 2001:db8::22/64 +
+
+
+
+
+ + xe-0/1/0 + + + ae0 + + + + + + xe-0/1/1 + + + ae0 + + + + + + xe-0/1/4 + {ae0} + + + ae0 + + + + + + xe-0/1/5 + {ae0} + + + ae0 + + + + + + ae0 + ae0 + + 9192 + + 1 + 10g + + + + + + 0 + 100 + + +
+ 192.168.1.1/24 +
+
+
+
+
+ + ge-0/0/1 + + + ae1 + + + + + ge-0/0/2 + + + ae1 + + + + + ge-0/0/3 + + + ae2 + + + + + + ge-0/0/4 + + + ae2 + + + + + + ge-1/0/0 + + 0 + + +
+ 192.168.100.1/24 +
+
+ 10.200.16.20/24 +
+
+ + +
+
+
+ + ge-2/0/0 + + 0 + + +
+ 192.168.100.2/24 +
+
+ 10.200.16.21/24 +
+
+ + +
+
+
+ + ge-3/0/0 + + 0 + + +
+ 192.168.100.3/24 +
+
+ 10.200.16.22/24 +
+
+ + +
+
+
+ + ae1 + Configured by Ansible + + + + + + + + ae2 + Configured by Ansible + + + + + + + + + + em1 + TEST + + + fxp0 + ANSIBLE + 1g + automatic + + 0 + + +
+ 10.8.38.38/24 +
+
+
+
+
+
+
+
diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/gathered.yaml new file mode 100644 index 00000000..4831f9b6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/gathered.yaml @@ -0,0 +1,70 @@ +--- +- ansible.builtin.debug: + msg: START junos_lag_interfaces gathered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_merged_output: + - name: ae1 + members: + - member: ge-0/0/1 + ether_option_type: "ether" + - member: ge-0/0/2 + ether_option_type: "ether" + mode: active + + - name: ae2 + link_protection: true + members: + - member: ge-0/0/3 + ether_option_type: "ether" + link_type: primary + + - member: ge-0/0/4 + ether_option_type: "ether" + link_type: backup + mode: passive + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lag_interfaces: &id001 + config: + - name: ae1 + members: + - member: ge-0/0/1 + - member: ge-0/0/2 + mode: active + + - name: ae2 + link_protection: true + members: + - member: ge-0/0/3 + link_type: primary + - member: ge-0/0/4 + link_type: backup + mode: passive + state: merged + + - name: Gather lag interfaces facts using gathered state + register: result + junipernetworks.junos.junos_lag_interfaces: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + "{{ expected_merged_output | symmetric_difference(result['gathered']) |length\ + \ == 0 }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lag_interfaces gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/merged.yaml new file mode 100644 index 00000000..611805c5 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/merged.yaml @@ -0,0 +1,79 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lag_interfaces merged integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_merged_output: + - name: ae1 + members: + - member: ge-0/0/1 + ether_option_type: "ether" + + - member: ge-0/0/2 + ether_option_type: "ether" + mode: active + + - name: ae2 + link_protection: true + members: + - member: ge-0/0/3 + ether_option_type: "ether" + link_type: primary + + - member: ge-0/0/4 + ether_option_type: "ether" + link_type: backup + mode: passive + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lag_interfaces: &id001 + config: + - name: ae1 + members: + - member: ge-0/0/1 + + - member: ge-0/0/2 + mode: active + + - name: ae2 + link_protection: true + members: + - member: ge-0/0/3 + link_type: primary + + - member: ge-0/0/4 + link_type: backup + mode: passive + state: merged + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_merged_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: + Merge the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lag_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lag_interfaces merged integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/overridden.yaml new file mode 100644 index 00000000..44ad486f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/overridden.yaml @@ -0,0 +1,72 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lag_interfaces overridden integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_overridden_output: + - name: ae1 + members: + - member: ge-0/0/2 + ether_option_type: "ether" + mode: active + +- block: + - name: Base LAG configuration + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae1 + members: + - member: ge-0/0/1 + + - member: ge-0/0/2 + mode: active + + - name: ae2 + link_protection: true + members: + - member: ge-0/0/3 + link_type: primary + + - member: ge-0/0/4 + link_type: backup + mode: passive + state: merged + + - name: Override the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lag_interfaces: &id001 + config: + - name: ae1 + members: + - member: ge-0/0/2 + mode: active + state: overridden + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_overridden_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Override the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lag_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END junos_lag_interfaces overridden integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/parsed.yaml new file mode 100644 index 00000000..b1bed96d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/parsed.yaml @@ -0,0 +1,56 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lag_interfaces parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + - name: ae0 + members: + - member: xe-0/1/0 + ether_option_type: gigether + link_type: "primary" + - member: xe-0/1/1 + ether_option_type: gigether + link_type: "primary" + - member: xe-0/1/4 + ether_option_type: gigether + link_type: "primary" + - member: xe-0/1/5 + ether_option_type: gigether + link_type: "primary" + mode: active + - name: ae1 + members: + - member: ge-0/0/1 + ether_option_type: ether + - member: ge-0/0/2 + ether_option_type: ether + mode: active + - name: ae2 + link_protection: true + members: + - member: ge-0/0/3 + ether_option_type: ether + link_type: primary + - member: ge-0/0/4 + ether_option_type: ether + link_type: backup + mode: passive + +- name: Parse externally provided interfaces config to agnostic model + register: result + junipernetworks.junos.junos_lag_interfaces: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output | symmetric_difference(result['parsed']) |length ==\ + \ 0 }}" +- ansible.builtin.debug: + msg: + END junos_lag_interfaces parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/rendered.yaml new file mode 100644 index 00000000..a5abcfac --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/rendered.yaml @@ -0,0 +1,36 @@ +--- +- ansible.builtin.debug: + msg: START junos_lag_interfaces rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: 'ae1ge-0/0/1ae1ge-0/0/2ae1ae2ge-0/0/3ae2ge-0/0/4ae2' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae1 + members: + - member: ge-0/0/1 + - member: ge-0/0/2 + mode: active + + - name: ae2 + link_protection: true + members: + - member: ge-0/0/3 + link_type: primary + - member: ge-0/0/4 + link_type: backup + mode: passive + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_lag_interfaces rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/replaced.yaml new file mode 100644 index 00000000..2bd1f734 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lag_interfaces/tests/netconf/replaced.yaml @@ -0,0 +1,84 @@ +--- +- ansible.builtin.debug: + msg: START junos_lag_interfaces replaced integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_replaced_output: + - name: ae1 + members: + - member: ge-0/0/1 + ether_option_type: "ether" + mode: passive + + - name: ae2 + link_protection: true + members: + - member: ge-0/0/3 + ether_option_type: "ether" + link_type: primary + + - member: ge-0/0/4 + ether_option_type: "ether" + link_type: backup + mode: passive + +- block: + - name: Base LAG configuration + junipernetworks.junos.junos_lag_interfaces: + config: + - name: ae1 + members: + - member: ge-0/0/1 + + - member: ge-0/0/2 + mode: active + + - name: ae2 + link_protection: true + members: + - member: ge-0/0/3 + link_type: primary + + - member: ge-0/0/4 + link_type: backup + mode: passive + state: merged + + - name: Replace the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lag_interfaces: &id001 + config: + - name: ae1 + members: + - member: ge-0/0/1 + mode: passive + state: replaced + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_replaced_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Replace the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lag_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_lag_interfaces replaced integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tasks/main.yaml new file mode 100644 index 00000000..a6fc560a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/_remove_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/_remove_config.yaml new file mode 100644 index 00000000..9d317f61 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/_remove_config.yaml @@ -0,0 +1,15 @@ +--- +- ansible.builtin.debug: + msg: + Start junos_lldp_global deleted remove interface config ansible_connection={{ + ansible_connection }} + +- name: Setup - remove lldp global config + junipernetworks.junos.junos_config: + lines: + - delete protocols lldp + +- ansible.builtin.debug: + msg: + End junos_lldp_global deleted remove interface config ansible_connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/deleted.yaml new file mode 100644 index 00000000..88d00b31 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/deleted.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lldp_global deleted integration tests on connection={{ ansible_connection + }} + +- name: get supported protocols + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show lldp + +- name: lldp supported + ansible.builtin.set_fact: + lldp_supported: true + when: not result.failed + +- name: lldp not supported + ansible.builtin.set_fact: + lldp_supported: false + when: result.failed + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.set_fact: + expected_deleted_output: [] + + - name: Configure initial state for lldp global + register: result + junipernetworks.junos.junos_lldp_global: + config: + interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + state: merged + + - name: Delete the provided configuration from running configuration + register: result + junipernetworks.junos.junos_lldp_global: &id001 + config: + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ result['after'] == {} }}" + + - name: Delete the provided configuration from running configuration (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lldp_global: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + when: lldp_supported + +- ansible.builtin.debug: + msg: + END junos_lldp_global deleted integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..28735efb --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,28 @@ + + + + + + + 0.0.0.0 + + ge-0/0/0.0 + + + + + 10.1.1.1 + 10000 + 400 + 10 + + ge-0/0/1 + + + ge-0/0/2 + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/gathered.yaml new file mode 100644 index 00000000..26f57fa4 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/gathered.yaml @@ -0,0 +1,56 @@ +--- +- ansible.builtin.debug: + msg: START junos_lldp_global gathered integration tests on connection={{ + ansible_connection }} + +- name: get supported protocols + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show lldp + +- name: lldp supported + ansible.builtin.set_fact: + lldp_supported: true + when: not result.failed + +- name: lldp not supported + ansible.builtin.set_fact: + lldp_supported: false + when: result.failed + +- ansible.builtin.set_fact: + expected_merged_output: + address: 10.1.1.1 + hold_multiplier: 10 + interval: 10000 + transmit_delay: 400 + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lldp_global: &id001 + config: + interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + state: merged + + - name: Gather lldp_global facts using gathered state + register: result + junipernetworks.junos.junos_lldp_global: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ expected_merged_output == result['gathered'] }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml + when: lldp_supported + +- ansible.builtin.debug: + msg: + END junos_lldp_global gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/merged.yaml new file mode 100644 index 00000000..ba65dca5 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/merged.yaml @@ -0,0 +1,66 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lldp_global merged integration tests on connection={{ ansible_connection + }} + +- name: get supported protocols + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show lldp + +- name: lldp supported + ansible.builtin.set_fact: + lldp_supported: true + when: not result.failed + +- name: lldp not supported + ansible.builtin.set_fact: + lldp_supported: false + when: result.failed + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.set_fact: + expected_merged_output: + - interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lldp_global: &id001 + config: + interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + state: merged + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_merged_output | symmetric_difference([result['after']])\ + \ |length == 0 }}" + + - name: + Merge the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lldp_global: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + when: lldp_supported + +- ansible.builtin.debug: + msg: + END junos_lldp_global merged integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/parsed.yaml new file mode 100644 index 00000000..7a8b2eec --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/parsed.yaml @@ -0,0 +1,27 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lldp_global parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + address: 10.1.1.1 + hold_multiplier: 10 + interval: 10000 + transmit_delay: 400 + +- name: Parse externally provided lldp_global config to agnostic model + register: result + junipernetworks.junos.junos_lldp_global: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output == result['parsed'] }}" +- ansible.builtin.debug: + msg: + END junos_lldp_global parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/rendered.yaml new file mode 100644 index 00000000..c79ad52a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/rendered.yaml @@ -0,0 +1,26 @@ +--- +- ansible.builtin.debug: + msg: START junos_lldp_global rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: '10.1.1.11000040010' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_lldp_global: + config: + interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_lldp_global rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/replaced.yaml new file mode 100644 index 00000000..6f0f50ea --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/replaced.yaml @@ -0,0 +1,78 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lldp_global replaced integration tests on connection={{ ansible_connection + }} + +- name: get supported protocols + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show lldp + +- name: lldp supported + ansible.builtin.set_fact: + lldp_supported: true + when: not result.failed + +- name: lldp not supported + ansible.builtin.set_fact: + lldp_supported: false + when: result.failed + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.set_fact: + expected_replaced_output: + - interval: 20000 + address: 10.1.1.2 + transmit_delay: 500 + hold_multiplier: 5 + enabled: false + + - name: Configure initial state for lldp global + register: result + junipernetworks.junos.junos_lldp_global: + config: + interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + state: merged + + - name: Replace the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lldp_global: &id001 + config: + interval: 20000 + address: 10.1.1.2 + transmit_delay: 500 + hold_multiplier: 5 + enabled: false + state: replaced + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_replaced_output | symmetric_difference([result['after']])\ + \ |length == 0 }}" + + - name: + Replace the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lldp_global: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + when: lldp_supported + +- ansible.builtin.debug: + msg: + END junos_lldp_global replaced integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/rtt.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/rtt.yaml new file mode 100644 index 00000000..e7537bf5 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_global/tests/netconf/rtt.yaml @@ -0,0 +1,83 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lldp_global round trip integration tests on connection={{ ansible_connection + }} + +- name: get supported protocols + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show lldp + +- name: lldp supported + ansible.builtin.set_fact: + lldp_supported: true + when: not result.failed + +- name: lldp not supported + ansible.builtin.set_fact: + lldp_supported: false + when: result.failed + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.set_fact: + expected_revert_output: + - interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_lldp_global: + config: + interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - lldp_global + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_lldp_global: + config: + interval: 20000 + address: 10.1.1.2 + transmit_delay: 500 + hold_multiplier: 5 + enabled: false + state: replaced + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_lldp_global: + config: "{{ ansible_facts['network_resources']['lldp_global'] }}" + state: replaced + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + "{{ expected_revert_output | symmetric_difference([revert['after']])\ + \ |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + when: lldp_supported + +- ansible.builtin.debug: + msg: + END junos_lldp_global round trip integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/meta/main.yaml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tasks/main.yaml new file mode 100644 index 00000000..a6fc560a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/_remove_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/_remove_config.yaml new file mode 100644 index 00000000..5c1c477a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/_remove_config.yaml @@ -0,0 +1,15 @@ +--- +- ansible.builtin.debug: + msg: + Start junos_lldp_interfaces deleted remove interface config ansible_connection={{ + ansible_connection }} + +- name: Setup - remove lldp interfaces config + junipernetworks.junos.junos_config: + lines: + - delete protocols lldp + +- ansible.builtin.debug: + msg: + End junos_lldp_interfaces deleted remove interface config ansible_connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/deleted.yaml new file mode 100644 index 00000000..31849fac --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/deleted.yaml @@ -0,0 +1,95 @@ +--- +- ansible.builtin.debug: + msg: START junos_lldp_interfaces deleted integration tests on connection={{ + ansible_connection }} + +- name: get supported protocols + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show lldp + +- name: lldp supported + ansible.builtin.set_fact: + lldp_supported: true + when: not result.failed + +- name: lldp not supported + ansible.builtin.set_fact: + lldp_supported: false + when: result.failed + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.set_fact: + expected_deleted_output: + - name: ge-0/0/1 + + - name: Configure initial state for lldp interfaces + register: result + junipernetworks.junos.junos_lldp_interfaces: &id002 + config: + - name: ge-0/0/1 + + - name: ge-0/0/2 + enabled: false + state: merged + + - name: Delete the provided lldp interface configuration from running configuration + register: result + junipernetworks.junos.junos_lldp_interfaces: &id001 + config: + - name: ge-0/0/2 + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_deleted_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Delete the provided lldp interface configuration from running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lldp_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + + - name: Configure initial state for interface + register: result + junipernetworks.junos.junos_lldp_interfaces: *id002 + + - name: Delete the all lldp interface configuration from running configuration + register: result + junipernetworks.junos.junos_lldp_interfaces: + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ result['after'] == []}}" + + - name: + Delete the all lldp interface configuration from running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lldp_interfaces: + state: deleted + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + when: lldp_supported + +- ansible.builtin.debug: + msg: + END junos_lldp_interfaces deleted integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..7875abec --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,24 @@ + + + + + + + 0.0.0.0 + + ge-0/0/0.0 + + + + + + ge-0/0/1 + + + ge-0/0/2 + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/gathered.yaml new file mode 100644 index 00000000..05765490 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/gathered.yaml @@ -0,0 +1,58 @@ +--- +- ansible.builtin.debug: + msg: START junos_lldp_interfaces gathered integration tests on connection={{ + ansible_connection }} + +- name: get supported protocols + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show lldp + +- name: lldp supported + ansible.builtin.set_fact: + lldp_supported: true + when: not result.failed + +- name: lldp not supported + ansible.builtin.set_fact: + lldp_supported: false + when: result.failed + +- ansible.builtin.set_fact: + expected_merged_output: + - name: ge-0/0/1 + + - name: ge-0/0/2 + enabled: false + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lldp_interfaces: &id001 + config: + - name: ge-0/0/1 + + - name: ge-0/0/2 + enabled: false + state: merged + + - name: Gather lag interfaces facts using gathered state + register: result + junipernetworks.junos.junos_lldp_interfaces: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + "{{ expected_merged_output | symmetric_difference(result['gathered']) |length\ + \ == 0 }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml + when: lldp_supported + +- ansible.builtin.debug: + msg: + END junos_lldp_interfaces gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/merged.yaml new file mode 100644 index 00000000..9454ac5f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/merged.yaml @@ -0,0 +1,66 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lldp_interfaces merged integration tests on connection={{ ansible_connection + }} + +- name: get supported protocols + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show lldp + +- name: lldp supported + ansible.builtin.set_fact: + lldp_supported: true + when: not result.failed + +- name: lldp not supported + ansible.builtin.set_fact: + lldp_supported: false + when: result.failed + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.set_fact: + expected_merged_output: + - name: ge-0/0/1 + + - name: ge-0/0/2 + enabled: false + + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lldp_interfaces: &id001 + config: + - name: ge-0/0/1 + + - name: ge-0/0/2 + enabled: false + state: merged + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_merged_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: + Merge the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lldp_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + when: lldp_supported + +- ansible.builtin.debug: + msg: + END junos_lldp_interfaces merged integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/overridden.yaml new file mode 100644 index 00000000..ad3f8e54 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/overridden.yaml @@ -0,0 +1,69 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lldp_interfaces overridden integration tests on connection={{ + ansible_connection }} + +- name: get supported protocols + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show lldp + +- name: lldp supported + ansible.builtin.set_fact: + lldp_supported: true + when: not result.failed + +- name: lldp not supported + ansible.builtin.set_fact: + lldp_supported: false + when: result.failed + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.set_fact: + expected_overridden_output: + - name: ge-0/0/2 + + - name: Configure initial state for interface + register: result + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + + - name: ge-0/0/2 + enabled: false + state: merged + + - name: Override the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lldp_interfaces: &id001 + config: + - name: ge-0/0/2 + state: overridden + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_overridden_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Override the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lldp_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + when: lldp_supported + +- ansible.builtin.debug: + msg: END junos_lldp_interfaces overridden integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/parsed.yaml new file mode 100644 index 00000000..8ef4a087 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/parsed.yaml @@ -0,0 +1,28 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lldp_interfaces parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + - name: ge-0/0/1 + + - name: ge-0/0/2 + enabled: false + +- name: Parse externally provided lldp interfaces config to agnostic model + register: result + junipernetworks.junos.junos_lldp_interfaces: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output | symmetric_difference(result['parsed']) |length ==\ + \ 0 }}" +- ansible.builtin.debug: + msg: + END junos_lldp_interfaces parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/rendered.yaml new file mode 100644 index 00000000..b3738262 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/rendered.yaml @@ -0,0 +1,26 @@ +--- +- ansible.builtin.debug: + msg: START junos_lldp_interfaces rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: 'ge-0/0/1ge-0/0/2' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + + - name: ge-0/0/2 + enabled: false + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_lldp_interfaces rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/replaced.yaml new file mode 100644 index 00000000..aa791070 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/replaced.yaml @@ -0,0 +1,73 @@ +--- +- ansible.builtin.debug: + msg: START junos_lldp_interfaces replaced integration tests on connection={{ + ansible_connection }} + +- name: get supported protocols + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show lldp + +- name: lldp supported + ansible.builtin.set_fact: + lldp_supported: true + when: not result.failed + +- name: lldp not supported + ansible.builtin.set_fact: + lldp_supported: false + when: result.failed + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.set_fact: + expected_replaced_output: + - name: ge-0/0/1 + enabled: false + + - name: ge-0/0/2 + enabled: false + + - name: Configure initial state for interface + register: result + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + + - name: ge-0/0/2 + enabled: false + + - name: Replace the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_lldp_interfaces: &id001 + config: + - name: ge-0/0/1 + enabled: false + state: replaced + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_replaced_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Replace the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_lldp_interfaces: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + when: lldp_supported + +- ansible.builtin.debug: + msg: + END junos_lldp_interfaces replaced integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/rtt.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/rtt.yaml new file mode 100644 index 00000000..db6c7c20 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_lldp_interfaces/tests/netconf/rtt.yaml @@ -0,0 +1,78 @@ +--- +- ansible.builtin.debug: + msg: + START junos_lldp_interfaces round trip integration tests on connection={{ + ansible_connection }} + +- name: get supported protocols + register: result + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show lldp + +- name: lldp supported + ansible.builtin.set_fact: + lldp_supported: true + when: not result.failed + +- name: lldp not supported + ansible.builtin.set_fact: + lldp_supported: false + when: result.failed + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.set_fact: + expected_revert_output: + - name: ge-0/0/1 + + - name: ge-0/0/2 + enabled: false + + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + + - name: ge-0/0/2 + enabled: false + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - lldp_interfaces + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/2 + state: overridden + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_lldp_interfaces: + config: "{{ ansible_facts['network_resources']['lldp_interfaces'] }}" + state: replaced + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + "{{ expected_revert_output | symmetric_difference(revert['after'])\ + \ |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + when: lldp_supported + +- ansible.builtin.debug: + msg: END junos_lldp_interfaces round trip integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tasks/main.yaml new file mode 100644 index 00000000..a6fc560a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..b5cae6f7 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/_initial_config.yaml @@ -0,0 +1,12 @@ +--- +- ansible.builtin.debug: + msg: "START junos_logging_global initial config on connection={{ ansible_connection }}" + +- name: Configure basic config relevant to logging global + junipernetworks.junos.junos_config: + lines: + - set routing-instances inst11 instance-type virtual-router + - set routing-instances inst11 description "inst11" + +- ansible.builtin.debug: + msg: "END junos_logging_global initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..72d9d08c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/_reset_config.yaml @@ -0,0 +1,12 @@ +--- +- ansible.builtin.debug: + msg: "START junos_logging_global reset config on connection={{ ansible_connection }}" + +- name: Reset the config releavent to logging global resource + junipernetworks.junos.junos_config: + lines: + - delete system syslog + - delete routing-instances + +- ansible.builtin.debug: + msg: "END junos_logging_global reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/backups/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/backups/empty_config.yaml new file mode 100644 index 00000000..c2d74d60 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/backups/empty_config.yaml @@ -0,0 +1,49 @@ +--- +- ansible.builtin.debug: + msg: START junos_bgp_global empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/deleted.yaml new file mode 100644 index 00000000..88e25a4d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/deleted.yaml @@ -0,0 +1,99 @@ +--- +- ansible.builtin.debug: + msg: "START junos_logging_global deleted integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.set_fact: + config: {} + - name: Pre gathered operation configuration + junipernetworks.junos.junos_logging_global: + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: 65578 + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: 65578 + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: merged + - name: Delete all ospf config from the device + junipernetworks.junos.junos_logging_global: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config == result.after }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_logging_global deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..2afd9233 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: + START junos_logging_global empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_logging_global: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_logging_global: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_logging_global: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_logging_global: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_logging_global: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..5c1e3dc4 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,152 @@ + + + + 18.4R1-S2.4 + + + + vagrant + 2000 + super-user + + $6$QiBkxU5N$QY11GzNuFs1sfY0OAacyJ/0WFmP9ciovUAmM425yYAo9OjccxvjWlEZNo8SeqCQxYeM86cfd9V.N1RiiHW2zN0 + + ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key + + + + + + $1$nq.N1UsY$JxA/ESAj3KuXseXE597gg0 + + ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key + + + + + + + + 830 + + + + + vsrx + + + 5m + 10 + + + + + user1 + + + + user2 + + any + + + + user + + + + + + host111 + + any + + + ^set* + + 1231 + ftp + field + 11.1.1.11 + inst11 + + ^delete + ^prompt + + + + + + + file101 + + + + file102 + + any + + + + + + + + file103 + ^set* + + 65578 + 10 + + + + + ^delete + ^prompt + + + any + + + + authorization + + + + ftp + + + + change-log + + + + + + + 33.33.33.33 + inst11 + 45 + + + + + https://ae1.juniper.net/junos/key_retrieval + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/gathered.yaml new file mode 100644 index 00000000..df3ebfd4 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/gathered.yaml @@ -0,0 +1,99 @@ +--- +- ansible.builtin.debug: + msg: START junos_logging_global gathered integration tests on connection={{ ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Pre gathered operation configuration + junipernetworks.junos.junos_logging_global: + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: "5m" + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: "65578" + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: merged + + - name: Gather interfaces facts using gathered state + register: result + junipernetworks.junos.junos_logging_global: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['gathered'] }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_logging_global gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/merged.yaml new file mode 100644 index 00000000..bf017319 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/merged.yaml @@ -0,0 +1,136 @@ +--- +- ansible.builtin.debug: + msg: "START junos_logging_global merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_logging_global: &merged + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: "5m" + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: "65578" + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + + routing_instance: "inst11" + + log_rotate_frequency: 45 + + source_address: "33.33.33.33" + + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['before'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['after'] == result['after'] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_logging_global: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - name: Update the running configuration with providede configuration + junipernetworks.junos.junos_logging_global: + config: + files: + - name: "file101" + allow_duplicates: true + - name: "file104" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['updated'] == result['after'] }}" + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_logging_global merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/overridden.yaml new file mode 100644 index 00000000..a3107f67 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/overridden.yaml @@ -0,0 +1,175 @@ +--- +- ansible.builtin.debug: + msg: "START junos_logging_global overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Pre overridden operation configuration + junipernetworks.junos.junos_logging_global: + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: "5m" + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: "65578" + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: merged + + - name: Override configuration + junipernetworks.junos.junos_logging_global: &overridden + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: "5m" + no_world_readable: true + files: + - name: "file101" + allow_duplicates: true + - name: "file104" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: "65578" + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result.after }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_logging_global: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_logging_global overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/parsed.yaml new file mode 100644 index 00000000..e3cd47f9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/parsed.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: + START junos_logging_global parsed integration tests on connection={{ ansible_connection + }} + +- name: Parse externally provided logging_global config to agnostic model + register: result + junipernetworks.junos.junos_logging_global: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['parsed'] }}" +- ansible.builtin.debug: + msg: + END junos_logging_global parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/rendered.yaml new file mode 100644 index 00000000..b9555f5d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/rendered.yaml @@ -0,0 +1,29 @@ +--- +- ansible.builtin.debug: + msg: START junos_logging_global rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: '1065578' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_logging_global: + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: "65578" + no_world_readable: true + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_logging_global rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/replaced.yaml new file mode 100644 index 00000000..f4214b47 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/replaced.yaml @@ -0,0 +1,175 @@ +--- +- ansible.builtin.debug: + msg: "START junos_logging_global replaced integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Pre replaced operation configuration + junipernetworks.junos.junos_logging_global: + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: "5m" + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: "65578" + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: merged + + - name: Replace configuration + junipernetworks.junos.junos_logging_global: &replaced + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: "5m" + no_world_readable: true + files: + - name: "file101" + allow_duplicates: true + - name: "file104" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: "65578" + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result.after }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_logging_global: *replaced + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_logging_global replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/rtt.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/rtt.yml new file mode 100644 index 00000000..984a52af --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/tests/netconf/rtt.yml @@ -0,0 +1,141 @@ +--- +- ansible.builtin.debug: + msg: + START junos_logging_global round trip integration tests on connection={{ + ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_logging_global: + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: "5m" + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: "65578" + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - logging_global + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_logging_global: + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 12 + file_size: "5m" + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "info" + change_log: + level: "info" + state: replaced + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_logging_global: + config: "{{ ansible_facts['network_resources']['logging_global'] }}" + state: replaced + + - name: Assert that before dicts are correct + ansible.builtin.assert: + that: + - result.changed == True + - "{{ result['after'] == revert['before'] }}" + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + - result.changed == True + - "{{ base_config['after'] == revert['after'] }}" + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_logging_global round trip integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/vars/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/vars/main.yaml new file mode 100644 index 00000000..ba51d368 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_logging_global/vars/main.yaml @@ -0,0 +1,206 @@ +--- +merged: + before: {} + + after: + allow_duplicates: true + archive: + file_size: "5m" + files: 10 + no_binary_data: true + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + no_binary_data: true + files: 10 + file_size: "65578" + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + updated: + allow_duplicates: true + archive: + no_binary_data: true + files: 10 + file_size: "5m" + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + no_binary_data: true + files: 10 + file_size: "65578" + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + - name: "file104" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info +replaced: + after: + allow_duplicates: true + archive: + file_size: "5m" + files: 10 + no_binary_data: true + no_world_readable: true + files: + - name: "file101" + allow_duplicates: true + - name: "file104" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + no_binary_data: true + files: 10 + file_size: "65578" + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "inst11" + source_address: "11.1.1.11" + routing_instance: "inst11" + log_rotate_frequency: 45 + source_address: "33.33.33.33" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/tasks/cli.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/tasks/cli.yaml new file mode 100644 index 00000000..cfc0867a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/tasks/cli.yaml @@ -0,0 +1,22 @@ +--- +- name: Collect all cli test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests" + patterns: "{{ testcase }}.yaml" + use_regex: true + register: test_cases + connection: local + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + tags: + - network_cli diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/tasks/main.yaml new file mode 100644 index 00000000..c2c80a3c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/tasks/main.yaml @@ -0,0 +1,3 @@ +--- +- name: Invoke net_put test case + ansible.builtin.include_tasks: cli.yaml diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/tests/junos_net_put.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/tests/junos_net_put.yaml new file mode 100644 index 00000000..5f34d60e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_net_put/tests/junos_net_put.yaml @@ -0,0 +1,63 @@ +--- +- ansible.builtin.debug: msg="START net_put on connection={{ ansible_connection}}" + +- name: Create a 250mb file + ansible.builtin.command: "fallocate -l 1M /tmp/250mbfile" + args: + creates: /tmp/250mbfile + +- name: Check if the file exists + ansible.builtin.stat: + path: /tmp/250mbfile + register: file_stat + +- name: Verify file creation + ansible.builtin.assert: + that: + - file_stat.stat.exists == true + +- name: copy file from ansible controller to a network device using scp + ansible.netcommon.net_put: + src: /tmp/250mbfile + protocol: scp + dest: 250mbfile + check_destination: false + register: result + +- name: Verify file transfer of scp file + ansible.builtin.assert: + that: + - result.destination == '250mbfile' + - result.failed == false + +- name: Delete file from network device + junipernetworks.junos.junos_command: + commands: + - file delete 250mbfile + +- name: copy file from ansible controller to a network device using sftp + ansible.netcommon.net_put: + src: /tmp/250mbfile + protocol: sftp + dest: 250mbfile + check_destination: false + register: result + +- name: Verify file transfer of sftp file + ansible.builtin.assert: + that: + - result.destination == '250mbfile' + - result.failed == false + +- name: Delete file from network device + junipernetworks.junos.junos_command: + commands: + - file delete 250mbfile + +- name: Delete the file from ansible controller + ansible.builtin.file: + path: /tmp/250mbfile + state: absent + when: file_stat.stat.exists + +- ansible.builtin.debug: msg="END net_put on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/defaults/main.yaml new file mode 100644 index 00000000..9ef5ba51 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tasks/cli.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tasks/cli.yaml new file mode 100644 index 00000000..0637e8c1 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tasks/cli.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect all cli test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + register: test_cases + connection: local + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + tags: + - network_cli diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tasks/main.yaml new file mode 100644 index 00000000..aed90a6c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tasks/main.yaml @@ -0,0 +1,3 @@ +--- +- name: Invoke netconf + ansible.builtin.include_tasks: cli.yaml diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tests/cli/changeport.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tests/cli/changeport.yaml new file mode 100644 index 00000000..ae84d4b9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tests/cli/changeport.yaml @@ -0,0 +1,123 @@ +--- +- ansible.builtin.debug: + msg="START netconf/changeport.yaml on connection={{ ansible_connection + }}" + +- name: Setup + junipernetworks.junos.junos_netconf: + state: present + +- name: Change port + register: result + junipernetworks.junos.junos_netconf: + state: present + netconf_port: 8022 + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: idempotent tests + register: result + junipernetworks.junos.junos_netconf: + state: present + netconf_port: 8022 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: wait for netconf port tcp/8022 to be open + wait_for: + host: "{{ hostvars[item].ansible_host }}" + port: 8022 + with_inventory_hostnames: junos + +- name: Reset ansible connections + meta: reset_connection + +- name: Ensure we can communicate over 8022 + ansible.builtin.include_tasks: "{{ role_path }}/tests/utils/junos_command.yaml" + vars: + ansible_connection: ansible.netcommon.netconf + ansible_port: 8022 + is_ignore_errors: false + +- name: wait for netconf port tcp/830 to be closed + wait_for: + host: "{{ hostvars[item].ansible_host }}" + port: 830 + state: stopped + with_inventory_hostnames: junos + +- name: Ensure we can NOT communicate over default port + ansible.builtin.include_tasks: "{{ role_path }}/tests/utils/junos_command.yaml" + vars: + ansible_connection: ansible.netcommon.netconf + ansible_port: 830 + is_ignore_errors: true + +- ansible.builtin.assert: + that: + - result.failed == true + +- name: Set back netconf to default port + junipernetworks.junos.junos_netconf: + state: present + +- name: wait for netconf port tcp/830 to be open + wait_for: + host: "{{ hostvars[item].ansible_host }}" + port: 830 + with_inventory_hostnames: junos + +- name: Reset ansible connections + meta: reset_connection + +- name: Ensure we can communicate over netconf + ansible.builtin.include_tasks: "{{ role_path }}/tests/utils/junos_command.yaml" + vars: + ansible_connection: ansible.netcommon.netconf + ansible_port: 830 + is_ignore_errors: false + +- name: Change port (check mode) + register: result + check_mode: true + junipernetworks.junos.junos_netconf: + state: present + netconf_port: 12345 + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: wait for netconf port tcp/12345 to be closed + wait_for: + host: "{{ hostvars[item].ansible_host }}" + port: 12345 + state: stopped + with_inventory_hostnames: junos + +- name: Reset ansible connections + meta: reset_connection + +- name: Ensure we can NOT communicate over non-default port + ansible.builtin.include_tasks: "{{ role_path }}/tests/utils/junos_command.yaml" + vars: + ansible_connection: ansible.netcommon.netconf + ansible_port: 12345 + is_ignore_errors: true + +- ansible.builtin.assert: + that: + - result.failed == true + +- name: Ensure we can communicate over default port + ansible.builtin.include_tasks: "{{ role_path }}/tests/utils/junos_command.yaml" + vars: + ansible_connection: ansible.netcommon.netconf + ansible_port: 830 + is_ignore_errors: false + +- ansible.builtin.debug: msg="END netconf/changeport.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tests/cli/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tests/cli/netconf.yaml new file mode 100644 index 00000000..97cf4f3e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tests/cli/netconf.yaml @@ -0,0 +1,133 @@ +--- +- ansible.builtin.debug: msg="START netconf/netconf.yaml on connection={{ ansible_connection }}" + +- name: Ensure netconf is enabled + junipernetworks.junos.junos_netconf: + state: present + +- name: idempotent tests + register: result + junipernetworks.junos.junos_netconf: + state: present + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: wait for netconf port tcp/830 to be open + wait_for: + host: "{{ hostvars[item].ansible_host }}" + port: 830 + with_inventory_hostnames: junos + +- name: Reset ansible connections + meta: reset_connection + +- name: Ensure we can communicate over netconf + ansible.builtin.include_tasks: "{{ role_path }}/tests/utils/junos_command.yaml" + vars: + ansible_connection: ansible.netcommon.netconf + ansible_port: 830 + is_ignore_errors: false + +- name: Disable netconf (check mode) + register: result + check_mode: true + junipernetworks.junos.junos_netconf: + state: absent + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: wait for netconf port tcp/830 to be open + wait_for: + host: "{{ hostvars[item].ansible_host }}" + port: 830 + with_inventory_hostnames: junos + +- name: Reset ansible connections + meta: reset_connection + +- name: Ensure we can communicate over netconf + ansible.builtin.include_tasks: "{{ role_path }}/tests/utils/junos_command.yaml" + vars: + ansible_connection: ansible.netcommon.netconf + ansible_port: 830 + is_ignore_errors: false + +- name: Disable netconf + register: result + junipernetworks.junos.junos_netconf: + state: absent + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: idempotent tests + register: result + junipernetworks.junos.junos_netconf: + state: absent + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: wait for netconf port tcp/830 to be closed + wait_for: + host: "{{ hostvars[item].ansible_host }}" + port: 830 + state: stopped + with_inventory_hostnames: junos + +- name: Reset ansible connections + meta: reset_connection + +- name: Ensure we can NOT talk via netconf + ansible.builtin.include_tasks: "{{ role_path }}/tests/utils/junos_command.yaml" + vars: + ansible_connection: ansible.netcommon.netconf + ansible_port: 830 + is_ignore_errors: true + +- ansible.builtin.assert: + that: + - result.failed == true + +- name: Enable netconf (check mode) + register: result + check_mode: true + junipernetworks.junos.junos_netconf: + state: present + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: wait for netconf port tcp/830 to be closed + wait_for: + host: "{{ hostvars[item].ansible_host }}" + port: 830 + state: stopped + with_inventory_hostnames: junos + +- name: Reset ansible connections + meta: reset_connection + +- name: Ensure we can NOT talk via netconf + ansible.builtin.include_tasks: "{{ role_path }}/tests/utils/junos_command.yaml" + vars: + ansible_connection: ansible.netcommon.netconf + ansible_port: 830 + is_ignore_errors: true + +- ansible.builtin.assert: + that: + - result.failed == true + +- name: re-enable netconf + junipernetworks.junos.junos_netconf: + state: present + +- ansible.builtin.debug: msg="END netconf/netconfg.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tests/utils/junos_command.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tests/utils/junos_command.yaml new file mode 100644 index 00000000..76fa9c4d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_netconf/tests/utils/junos_command.yaml @@ -0,0 +1,6 @@ +--- +- name: run junos_command to check netconf connectivity + register: result + ignore_errors: "{{ is_ignore_errors }}" + junipernetworks.junos.junos_command: + rpcs: get-software-information diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tasks/main.yaml new file mode 100644 index 00000000..a6fc560a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..7df56549 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/_initial_config.yaml @@ -0,0 +1,14 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ntp_global initial config on connection={{ ansible_connection }}" + +- name: Configure basic config relevant to ntp global + junipernetworks.junos.junos_config: + lines: + - set routing-instances rt1 instance-type virtual-router + - set routing-instances rt1 description "rt1" + - set routing-instances rt2 instance-type virtual-router + - set routing-instances rt2 description "rt2" + +- ansible.builtin.debug: + msg: "END junos_ntp_global initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/_populate_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/_populate_config.yaml new file mode 100644 index 00000000..c42d5eb5 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/_populate_config.yaml @@ -0,0 +1,21 @@ +--- +- name: Populate config + junipernetworks.junos.junos_config: + lines: + - "set system ntp boot-server 78.46.194.186" + - "set system ntp broadcast 172.16.255.255 key 50 ttl 200 version 3 routing-instance-name rt1" + - "set system ntp broadcast 192.16.255.255 key 50 ttl 200 version 3 routing-instance-name rt2" + - "set system ntp broadcast-client" + - "set system ntp multicast-client 224.0.0.1" + - "set system ntp interval-range 2" + - "set system ntp peer 78.44.194.186" + - "set system ntp peer 172.44.194.186 key 10000 prefer version 3" + - "set system ntp server 48.46.194.186" + - "set system ntp server 48.46.194.186 key 34 prefer routing-instance rt1 version 2" + - "set system ntp server 48.45.194.186 key 34 prefer version 2" + - "set system ntp source-address 172.45.194.186 routing-instance rt1" + - "set system ntp source-address 171.45.194.186 routing-instance rt2" + - "set system ntp trusted-key 2000" + - "set system ntp trusted-key 3000" + - "set system ntp threshold 300 action accept" + - "set system ntp trusted-key 3000" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..0c08a7ce --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/_reset_config.yaml @@ -0,0 +1,12 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ntp_global reset config on connection={{ ansible_connection }}" + +- name: Reset the config releavent to ntp global resource + junipernetworks.junos.junos_config: + lines: + - delete system ntp + - delete routing-instances + +- ansible.builtin.debug: + msg: "END junos_ntp_global reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/backups/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/backups/empty_config.yaml new file mode 100644 index 00000000..c2d74d60 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/backups/empty_config.yaml @@ -0,0 +1,49 @@ +--- +- ansible.builtin.debug: + msg: START junos_bgp_global empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/deleted.yaml new file mode 100644 index 00000000..cd29f7dd --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/deleted.yaml @@ -0,0 +1,26 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ntp_global deleted integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + - ansible.builtin.set_fact: + config: {} + - name: Delete all ospf config from the device + junipernetworks.junos.junos_ntp_global: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config == result.after }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ntp_global deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..53b90ed0 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/empty_config.yaml @@ -0,0 +1,60 @@ +--- +- ansible.builtin.debug: + msg: START junos_ntp_global empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ntp_global: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ntp_global: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ntp_global: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ntp_global: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ntp_global: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..6619c8d6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,156 @@ + + + + 18.4R1-S2.4 + + + + vagrant + 2000 + super-user + + $6$QiBkxU5N$QY11GzNuFs1sfY0OAacyJ/0WFmP9ciovUAmM425yYAo9OjccxvjWlEZNo8SeqCQxYeM86cfd9V.N1RiiHW2zN0 + + ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key + + + + + + $1$nq.N1UsY$JxA/ESAj3KuXseXE597gg0 + + ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key + + + + + + + + 830 + + + + + vsrx + + + * + + any + + + + + messages + + any + + + + authorization + + + + + interactive-commands + + interactive-commands + + + + + + + + https://ae1.juniper.net/junos/key_retrieval + + + + + 78.46.194.186 + + 2 + + + 78.44.194.186 + + + 172.44.194.186 + 10000 + 3 + + + + 48.46.194.186 + 34 + 2 + + rt1 + + + 48.45.194.186 + 34 + 2 + + + + 172.16.255.255 + rt1 + 50 + 3 + 200 + + + 192.16.255.255 + rt2 + 50 + 3 + 200 + + + +
224.0.0.1
+
+ 3000 + 2000 + + 300 + accept + + + 172.45.194.186 + rt1 + + + 171.45.194.186 + rt2 + +
+
+ + + fxp0 + + 0 + + + + + + + + + + + + rt1 + rt1 + + + rt2 + rt2 + + +
+
diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/gathered.yaml new file mode 100644 index 00000000..b14ab74f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/gathered.yaml @@ -0,0 +1,25 @@ +--- +- ansible.builtin.debug: + msg: START junos_ntp_global gathered integration tests on connection={{ ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Gather interfaces facts using gathered state + register: result + junipernetworks.junos.junos_ntp_global: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['gathered'] }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_ntp_global gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/merged.yaml new file mode 100644 index 00000000..b7e24df9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/merged.yaml @@ -0,0 +1,101 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ntp_global merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_ntp_global: &merged + config: + boot_server: "78.46.194.186" + broadcasts: + - address: "172.16.255.255" + key: "50" + ttl: 200 + version: 3 + routing_instance_name: "rt1" + - address: "192.16.255.255" + key: "50" + ttl: 200 + version: 3 + routing_instance_name: "rt2" + broadcast_client: true + interval_range: 2 + multicast_client: "224.0.0.1" + peers: + - peer: "78.44.194.186" + - peer: "172.44.194.186" + key_id: 10000 + prefer: true + version: 3 + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: "rt1" + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + source_addresses: + - source_address: "172.45.194.186" + routing_instance: "rt1" + - source_address: "171.45.194.186" + routing_instance: "rt2" + threshold: + value: 300 + action: "accept" + trusted_keys: + - key_id: 3000 + - key_id: 2000 + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['before'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['after'] == result['after'] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_ntp_global: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - name: Update the running configuration with providede configuration + junipernetworks.junos.junos_ntp_global: + config: + interval_range: 3 + peers: + - peer: "172.44.194.188" + key_id: 10000 + prefer: true + version: 3 + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['updated'] == result['after'] }}" + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ntp_global merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/overridden.yaml new file mode 100644 index 00000000..8d7530e1 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/overridden.yaml @@ -0,0 +1,47 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ntp_global overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Override configuration + junipernetworks.junos.junos_ntp_global: &overridden + config: + multicast_client: "224.0.0.1" + interval_range: 3 + peers: + - peer: "172.44.194.188" + key_id: 10000 + prefer: true + version: 3 + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result.after }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_ntp_global: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ntp_global overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/parsed.yaml new file mode 100644 index 00000000..821d2c13 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/parsed.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: + START junos_ntp_global parsed integration tests on connection={{ ansible_connection + }} + +- name: Parse externally provided ntp_global config to agnostic model + register: result + junipernetworks.junos.junos_ntp_global: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['parsed'] }}" +- ansible.builtin.debug: + msg: + END junos_ntp_global parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/rendered.yaml new file mode 100644 index 00000000..ba768e13 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/rendered.yaml @@ -0,0 +1,30 @@ +--- +- ansible.builtin.debug: + msg: START junos_ntp_global rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: '2224.0.0.178.44.194.186172.44.194.186100003' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_ntp_global: + config: + interval_range: 2 + multicast_client: "224.0.0.1" + peers: + - peer: "78.44.194.186" + - peer: "172.44.194.186" + key_id: 10000 + prefer: true + version: 3 + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_ntp_global rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/replaced.yaml new file mode 100644 index 00000000..160a8ba3 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/replaced.yaml @@ -0,0 +1,47 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ntp_global replaced integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Override configuration + junipernetworks.junos.junos_ntp_global: &replaced + config: + multicast_client: "224.0.0.1" + interval_range: 3 + peers: + - peer: "172.44.194.188" + key_id: 10000 + prefer: true + version: 3 + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result.after }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_ntp_global: *replaced + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ntp_global replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/rtt.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/rtt.yml new file mode 100644 index 00000000..8e24da5f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/tests/netconf/rtt.yml @@ -0,0 +1,105 @@ +--- +- ansible.builtin.debug: + msg: START junos_ntp_global round trip integration tests on connection={{ + ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_ntp_global: + config: + boot_server: "78.46.194.186" + broadcasts: + - address: "172.16.255.255" + key: "50" + ttl: 200 + version: 3 + routing_instance_name: "rt1" + - address: "192.16.255.255" + key: "50" + ttl: 200 + version: 3 + routing_instance_name: "rt2" + broadcast_client: true + interval_range: 2 + multicast_client: "224.0.0.1" + peers: + - peer: "78.44.194.186" + - peer: "172.44.194.186" + key_id: 10000 + prefer: true + version: 3 + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: "rt1" + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + source_addresses: + - source_address: "172.45.194.186" + routing_instance: "rt1" + - source_address: "171.45.194.186" + routing_instance: "rt2" + threshold: + value: 300 + action: "accept" + trusted_keys: + - key_id: 3000 + - key_id: 2000 + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - ntp_global + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_ntp_global: + config: + multicast_client: "224.0.0.1" + interval_range: 3 + peers: + - peer: "172.44.194.188" + key_id: 10000 + prefer: true + version: 3 + state: replaced + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_ntp_global: + config: "{{ ansible_facts['network_resources']['ntp_global'] }}" + state: replaced + + - name: Assert that before dicts are correct + ansible.builtin.assert: + that: + - result.changed == True + - "{{ result['after'] == revert['before'] }}" + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + - result.changed == True + - "{{ base_config['after'] == revert['after'] }}" + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_ntp_global round trip integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/vars/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/vars/main.yaml new file mode 100644 index 00000000..1122d40a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ntp_global/vars/main.yaml @@ -0,0 +1,104 @@ +--- +merged: + before: {} + + after: + boot_server: "78.46.194.186" + broadcast_client: true + broadcasts: + - address: "172.16.255.255" + key: "50" + routing_instance_name: "rt1" + ttl: 200 + version: 3 + - address: "192.16.255.255" + key: "50" + routing_instance_name: "rt2" + ttl: 200 + version: 3 + interval_range: 2 + multicast_client: "224.0.0.1" + peers: + - peer: "78.44.194.186" + - key_id: 10000 + peer: "172.44.194.186" + prefer: true + version: 3 + servers: + - key_id: 34 + prefer: true + routing_instance: "rt1" + server: "48.46.194.186" + version: 2 + - key_id: 34 + prefer: true + server: "48.45.194.186" + version: 2 + source_addresses: + - routing_instance: "rt1" + source_address: "172.45.194.186" + - routing_instance: "rt2" + source_address: "171.45.194.186" + threshold: + action: "accept" + value: 300 + trusted_keys: + - key_id: 2000 + - key_id: 3000 + + updated: + boot_server: "78.46.194.186" + broadcasts: + - address: "172.16.255.255" + key: "50" + ttl: 200 + version: 3 + routing_instance_name: "rt1" + - address: "192.16.255.255" + key: "50" + ttl: 200 + version: 3 + routing_instance_name: "rt2" + broadcast_client: true + interval_range: 3 + multicast_client: "224.0.0.1" + peers: + - peer: "78.44.194.186" + - peer: "172.44.194.186" + key_id: 10000 + prefer: true + version: 3 + - peer: "172.44.194.188" + key_id: 10000 + prefer: true + version: 3 + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: "rt1" + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + source_addresses: + - source_address: "172.45.194.186" + routing_instance: "rt1" + - source_address: "171.45.194.186" + routing_instance: "rt2" + threshold: + value: 300 + action: "accept" + trusted_keys: + - key_id: 2000 + - key_id: 3000 +replaced: + after: + interval_range: 3 + multicast_client: "224.0.0.1" + peers: + - peer: "172.44.194.188" + key_id: 10000 + prefer: true + version: 3 diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/meta/main.yaml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tasks/main.yaml new file mode 100644 index 00000000..e9b22ba6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tasks/main.yaml @@ -0,0 +1,4 @@ +--- +- name: Invoke netconf + ansible.builtin.include_tasks: netconf.yaml + tags: ["netconf"] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..8ee537f2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/_initial_config.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospf_interfaces initial config on connection={{ ansible_connection }}" + +- name: Set initial configuration for ospf interfaces + junipernetworks.junos.junos_ospf_interfaces: + config: + - router_id: "10.200.16.75" + name: "ge-0/0/2.0" + address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.2" + priority: 3 + metric: 5 + state: merged + +- ansible.builtin.debug: + msg: "END junos_ospf_interfaces initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..070a5775 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/_reset_config.yaml @@ -0,0 +1,11 @@ +--- +- ansible.builtin.debug: + msg: "START reset ospf and routing-options config on connection={{ ansible_connection }}" + +- name: Reset configuration for ospf and routing-options + junipernetworks.junos.junos_config: + lines: + - delete protocols ospf + - delete routing-options +- ansible.builtin.debug: + msg: "END ospf and routing-options reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/deleted.yaml new file mode 100644 index 00000000..3e19d1de --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/deleted.yaml @@ -0,0 +1,63 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospf_interfaces deleted integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_config: + - address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.2" + priority: 3 + metric: 5 + name: "ge-0/0/2.0" + router_id: "10.200.16.75" + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_ospf_interfaces: &merged + config: + - router_id: "10.200.16.75" + name: "ge-0/0/3.0" + address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.3" + priority: 3 + metric: 5 + state: merged + - name: Delete single ospf interface configuration + junipernetworks.junos.junos_ospf_interfaces: + config: + - router_id: 10.200.16.75 + name: "ge-0/0/3.0" + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: &changed + that: + - result.changed == True + - "{{ expected_config|symmetric_difference(result.after) == [] }}" + + - ansible.builtin.set_fact: + expected_config: [] + + - name: Delete all ospf config from the device + junipernetworks.junos.junos_ospf_interfaces: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: *changed + + tags: deleted + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospf_interfaces deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..4b865a5a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/empty_config.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: + START junos_ospf_interfaces empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospf_interfaces: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospf_interfaces: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospf_interfaces: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospf_interfaces: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/fixtures/parse_ospf_router_id.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/fixtures/parse_ospf_router_id.cfg new file mode 100644 index 00000000..750b3d81 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/fixtures/parse_ospf_router_id.cfg @@ -0,0 +1,23 @@ + + + + + + + 0.0.0.2 + + 200 + + + ge-0/0/2.0 + 5 + 3 + + + + + + 10.200.16.75 + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..dc2e6145 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,20 @@ + + + + + + + 0.0.0.2 + + 200 + + + ge-0/0/2.0 + 5 + 3 + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/gathered.yaml new file mode 100644 index 00000000..01e0c4b2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/gathered.yaml @@ -0,0 +1,39 @@ +--- +- ansible.builtin.debug: + msg: START junos_ospf_interfaces gathered integration tests on connection={{ + ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_gathered_output: + - address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.2" + priority: 3 + metric: 5 + name: "ge-0/0/2.0" + router_id: "10.200.16.75" + + - name: Gather interfaces facts using gathered state + register: result + junipernetworks.junos.junos_ospf_interfaces: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + "{{ expected_gathered_output | symmetric_difference(result['gathered']) |length\ + \ == 0 }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_ospf_interfaces gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/merged.yaml new file mode 100644 index 00000000..ca6099a5 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/merged.yaml @@ -0,0 +1,175 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospf_interfaces merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.set_fact: + expected_config: + - address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.100" + authentication: + md5: + - key_id: 56 + key_value: "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER" + start_time: "2023-7-1.02:00:00 +0000" + - key_id: 50 + key_value: "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER" + - key_id: 40 + key_value: "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER" + bandwidth_based_metrics: + - bandwidth: "1g" + metric: 5 + - bandwidth: "10g" + metric: 40 + dead_interval: 4 + demand_circuit: true + hello_interval: 2 + metric: 5 + no_advertise_adjacency_segment: true + no_eligible_backup: true + no_eligible_remote_backup: true + no_interface_state_traps: true + no_neighbor_down_notification: true + node_link_protection: true + passive: true + poll_interval: 2 + priority: 3 + retransmit_interval: 2 + name: "so-0/0/0.0" + router_id: "10.200.16.75" + - address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.200" + authentication: + simple_password: "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER" + priority: 3 + name: "so-0/1/0.0" + router_id: "10.200.16.75" + - address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.200" + authentication: + md5: + - key_id: 10 + key_value: "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER" + start_time: "2023-7-12.03:00:00 +0000" + priority: 2 + name: "so-0/2/0.0" + router_id: "10.200.16.75" + - address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.120" + authentication: + md5: + - key_id: 10 + key_value: "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER" + start_time: "2023-7-12.03:00:00 +0000" + priority: 2 + name: so-0/2/0.1 + router_id: "10.200.16.75" + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_ospf_interfaces: &merged + config: + - address_family: + - afi: ipv4 + processes: + area: + area_id: 0.0.0.100 + authentication: + md5: + - key_id: "56" + key_value: ansible56 + start_time: 2023-7-1.02:00:00 +0000 + - key_id: "50" + key_value: ansible50 + - key_id: "40" + key_value: ansible40 + bandwidth_based_metrics: + - bandwidth: 1g + metric: 5 + - bandwidth: 10g + metric: 40 + dead_interval: 4 + hello_interval: 2 + metric: 5 + passive: true + poll_interval: 2 + priority: 3 + retransmit_interval: 2 + no_advertise_adjacency_segment: true + node_link_protection: true + no_neighbor_down_notification: true + no_interface_state_traps: true + no_eligible_remote_backup: true + no_eligible_backup: true + demand_circuit: true + name: so-0/0/0.0 + router_id: 10.200.16.75 + - address_family: + - afi: ipv4 + processes: + area: + area_id: 0.0.0.200 + authentication: + simple_password: simple + priority: 3 + name: so-0/1/0.0 + router_id: 10.200.16.75 + - address_family: + - afi: ipv4 + processes: + area: + area_id: 0.0.0.200 + authentication: + md5: + - key_id: "10" + key_value: ansible10 + start_time: 2023-7-12.03:00:00 +0000 + priority: 2 + name: so-0/2/0.0 + router_id: 10.200.16.75 + - address_family: + - afi: ipv4 + processes: + area: + area_id: 0.0.0.120 + authentication: + md5: + - key_id: "10" + key_value: ansible10 + start_time: 2023-7-12.03:00:00 +0000 + priority: 2 + name: so-0/2/0.1 + router_id: 10.200.16.75 + state: merged + register: result + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_config | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_ospf_interfaces: *merged + register: result + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospf_interfaces merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/merged_update.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/merged_update.yaml new file mode 100644 index 00000000..fe3178e8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/merged_update.yaml @@ -0,0 +1,66 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospf_interfaces merged update integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_config: + - address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.2" + priority: 3 + metric: 5 + name: "ge-0/0/2.0" + router_id: "10.200.16.75" + - address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.3" + priority: 3 + metric: 5 + name: "ge-0/0/3.0" + router_id: "10.200.16.75" + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_ospf_interfaces: &merged + config: + - router_id: "10.200.16.75" + name: "ge-0/0/3.0" + address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.3" + priority: 3 + metric: 5 + state: merged + register: result + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_config | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_ospf_interfaces: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: merged_update + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospf_interfaces merged update integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/overridden.yaml new file mode 100644 index 00000000..c0eae03f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/overridden.yaml @@ -0,0 +1,69 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospf_interfaces overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_config: + - address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.1" + priority: 6 + metric: 7 + name: "ge-0/0/1.0" + router_id: "10.200.16.75" + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_ospf_interfaces: &merged + config: + - router_id: "10.200.16.75" + name: "ge-0/0/3.0" + address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.3" + priority: 3 + metric: 5 + state: merged + - name: Override configuration + junipernetworks.junos.junos_ospf_interfaces: &overridden + config: + - router_id: "10.200.16.75" + name: "ge-0/0/1.0" + address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.1" + priority: 6 + metric: 7 + state: overridden + register: result + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_config | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: Override the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_ospf_interfaces: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospf_interfaces overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/parsed.yaml new file mode 100644 index 00000000..6c0b740f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/parsed.yaml @@ -0,0 +1,57 @@ +--- +- ansible.builtin.debug: + msg: + START junos_ospf_interfaces parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + - address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.2" + metric: 5 + priority: 3 + name: "ge-0/0/2.0" + +- name: Parse externally provided interfaces config to agnostic model + register: result + junipernetworks.junos.junos_ospf_interfaces: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output | symmetric_difference(result['parsed']) |length ==\ + \ 0 }}" + +- ansible.builtin.set_fact: + expected_parsed_output: + - address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.2" + metric: 5 + priority: 3 + name: "ge-0/0/2.0" + router_id: "10.200.16.75" + +- name: Parse externally provided interfaces config to agnostic model + register: result + junipernetworks.junos.junos_ospf_interfaces: + running_config: "{{ lookup('file', './fixtures/parse_ospf_router_id.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output | symmetric_difference(result['parsed']) |length ==\ + \ 0 }}" + +- ansible.builtin.debug: + msg: + END junos_ospf_interfaces parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/rendered.yaml new file mode 100644 index 00000000..c837c8ba --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/rendered.yaml @@ -0,0 +1,31 @@ +--- +- ansible.builtin.debug: + msg: START junos_ospf_interfaces rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: '0.0.0.2ge-0/0/2.035' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_ospf_interfaces: + config: + - router_id: "10.200.16.75" + name: "ge-0/0/2.0" + address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.2" + priority: 3 + metric: 5 + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_ospf_interfaces rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/replaced.yaml new file mode 100644 index 00000000..488f9790 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospf_interfaces/tests/netconf/replaced.yaml @@ -0,0 +1,46 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospf_interfaces replaced integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_config: + - address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.1" + priority: 6 + metric: 7 + name: "ge-0/0/2.0" + router_id: "10.200.16.75" + + - name: Replace configuration + junipernetworks.junos.junos_ospf_interfaces: + config: + - router_id: "10.200.16.75" + name: "ge-0/0/2.0" + address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.1" + priority: 6 + metric: 7 + state: replaced + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - "{{ expected_config|symmetric_difference(result.after) == [] }}" + + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospf_interfaces replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/meta/main.yaml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tasks/main.yaml new file mode 100644 index 00000000..e9b22ba6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tasks/main.yaml @@ -0,0 +1,4 @@ +--- +- name: Invoke netconf + ansible.builtin.include_tasks: netconf.yaml + tags: ["netconf"] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..41932e7d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/_initial_config.yaml @@ -0,0 +1,18 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospfv2 initial config on connection={{ ansible_connection }}" + +- name: Set initial configuration for ospf + junos_ospfv2: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + - area_id: 0.0.0.200 + interfaces: + - name: ge-2/2/0.0 + +- ansible.builtin.debug: + msg: "END junos_ospfv2 initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..6c3974c8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/_reset_config.yaml @@ -0,0 +1,11 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospfv2 reset config on connection={{ ansible_connection }}" + +- name: Reset configuration for ospf and routing-options + junipernetworks.junos.junos_config: + lines: + - delete protocols ospf + - delete routing-options +- ansible.builtin.debug: + msg: "END junos_ospfv2 reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/deleted.yaml new file mode 100644 index 00000000..3318258e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/deleted.yaml @@ -0,0 +1,25 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospfv2 deleted integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Delete all ospf config from the device + junos_ospfv2: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: + that: + - result.changed == True + - "{{ []|symmetric_difference(result.after) == [] }}" + + tags: deleted + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospfv2 deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..8d455dba --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START junos_ospfv2 empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospfv2: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospfv2: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Override with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospfv2: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospfv2: + running_config: + state: parsed + +- ansible.builtin.debug: + msg: result +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospfv2: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..01d8294e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,32 @@ + + + + 18.4R1-S2.4 + + + + 0.0.0.200 + + so-0/0/0.1 + 3 + 5 + + + + 0.0.0.100 + + 200 + + + so-0/0/0.0 + 5 + 3 + + + + + + 10.200.16.7 + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/gathered.yaml new file mode 100644 index 00000000..30424638 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/gathered.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: START junos_ospfv2 gathered integration tests on connection={{ ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_gathered_output: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + - area_id: 0.0.0.200 + interfaces: + - name: ge-2/2/0.0 + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_ospfv2: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + - area_id: 0.0.0.200 + interfaces: + - name: ge-2/2/0.0 + state: merged + + - name: Gather OSPFv2 facts using gathered state + register: result + junipernetworks.junos.junos_ospfv2: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + "{{ expected_gathered_output | symmetric_difference(result['gathered']) |length\ + \ == 0 }}" + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_ospfv2 gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/merged.yaml new file mode 100644 index 00000000..4578127a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/merged.yaml @@ -0,0 +1,57 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospfv2 merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.set_fact: + config: + - areas: + - area_id: 0.0.0.100 + interfaces: + - metric: 5 + name: so-0/0/0.0 + priority: 3 + stub: + default_metric: 200 + set: true + router_id: 10.200.16.75 + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_ospfv2: &merged + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + state: merged + register: result + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config|symmetric_difference(result.after) == [] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_ospfv2: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospfv2 merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/overridden.yaml new file mode 100644 index 00000000..9716d3d4 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/overridden.yaml @@ -0,0 +1,64 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospfv2 overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: true + passive: true + - area_id: 0.0.0.200 + interfaces: + - name: ge-1/1/0.0 + - name: ge-2/2/0.0 + + - name: Override Junos OSPF config + junipernetworks.junos.junos_ospfv2: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: true + passive: true + - area_id: 0.0.0.200 + interfaces: + - name: ge-1/1/0.0 + - name: ge-2/2/0.0 + state: overridden + register: result + + - name: Assert changed + ansible.builtin.assert: &changed + that: + - result.changed == True + - "{{ config|symmetric_difference(result.after) == [] }}" + + - name: Assert changed + ansible.builtin.assert: *changed + + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospfv2 overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/parsed.yaml new file mode 100644 index 00000000..67e573c3 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/parsed.yaml @@ -0,0 +1,38 @@ +--- +- ansible.builtin.debug: + msg: + START junos_ospfv2 parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + - areas: + - area_id: 0.0.0.200 + interfaces: + - metric: 3 + name: so-0/0/0.1 + priority: 5 + - area_id: 0.0.0.100 + interfaces: + - metric: 5 + name: so-0/0/0.0 + priority: 3 + stub: + default_metric: 200 + set: true + router_id: 10.200.16.7 + +- name: Parse OSPFV2 running-config to agnostic model + register: result + junipernetworks.junos.junos_ospfv2: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output == result['parsed'] }}" +- ansible.builtin.debug: + msg: + END junos_ospfv2 parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/rendered.yaml new file mode 100644 index 00000000..8e123b74 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/rendered.yaml @@ -0,0 +1,38 @@ +--- +- ansible.builtin.debug: + msg: START junos_ospfv2 rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: '0.0.0.200so-0/0/0.1530.0.0.100so-0/0/0.035200' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_ospfv2: + config: + - areas: + - area_id: 0.0.0.200 + interfaces: + - metric: 3 + name: so-0/0/0.1 + priority: 5 + - area_id: 0.0.0.100 + interfaces: + - metric: 5 + name: so-0/0/0.0 + priority: 3 + stub: + default_metric: 200 + set: true + router_id: 10.200.16.7 + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + - result.changed == False + +- ansible.builtin.debug: + msg: END junos_ospfv2 rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/replaced.yaml new file mode 100644 index 00000000..5c7f1967 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/replaced.yaml @@ -0,0 +1,38 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospfv2 replaced integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + + - name: Replace configuration + junos_ospfv2: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + state: replaced + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - "{{ config|symmetric_difference(result.after) == [] }}" + + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospfv2 replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/rtt.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/rtt.yaml new file mode 100644 index 00000000..6aab4d34 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv2/tests/netconf/rtt.yaml @@ -0,0 +1,73 @@ +--- +- ansible.builtin.debug: + msg: START junos_ospfv2 round trip integration tests on connection={{ + ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_ospfv2: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - ospfv2 + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_ospfv2: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + state: replaced + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_ospfv2: + config: "{{ ansible_facts['network_resources']['ospfv2'] }}" + state: overridden + + - name: Assert that before dicts are correct + ansible.builtin.assert: + that: + - result.changed == True + - "{{ result['after'] | symmetric_difference( revert['before'])\ + \ |length == 0 }}" + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + - result.changed == True + - "{{ base_config['after'] | symmetric_difference( revert['after'])\ + \ |length == 0 }}" + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_ospfv2 round trip integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/meta/main.yaml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tasks/main.yaml new file mode 100644 index 00000000..e9b22ba6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tasks/main.yaml @@ -0,0 +1,4 @@ +--- +- name: Invoke netconf + ansible.builtin.include_tasks: netconf.yaml + tags: ["netconf"] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..36c3ef92 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/_initial_config.yaml @@ -0,0 +1,18 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospfv3 initial config on connection={{ ansible_connection }}" + +- name: Set initial configuration for ospf + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + - area_id: 0.0.0.200 + interfaces: + - name: ge-2/2/0.0 + +- ansible.builtin.debug: + msg: "END junos_ospfv3 initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..c5cab985 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/_reset_config.yaml @@ -0,0 +1,11 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospfv3 reset config on connection={{ ansible_connection }}" + +- name: Reset configuration for ospf3 and routing-options + junipernetworks.junos.junos_config: + lines: + - delete protocols ospf3 + - delete routing-options +- ansible.builtin.debug: + msg: "END junos_ospfv3 reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/deleted.yaml new file mode 100644 index 00000000..b2733d48 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/deleted.yaml @@ -0,0 +1,56 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospfv3 deleted integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.200 + interfaces: + - name: ge-2/2/0.0 + + - name: Delete an area + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + state: deleted + register: result + + - ansible.builtin.debug: + var: result.after + + - ansible.builtin.debug: + var: config + + - name: Assert changed + ansible.builtin.assert: &changed + that: + - result.changed == True + - "{{ config|symmetric_difference(result.after) == [] }}" + + - ansible.builtin.set_fact: + config: [] + + - name: Delete all ospf config from the device + junipernetworks.junos.junos_ospfv3: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: *changed + + tags: deleted + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospfv3 deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..b98618d1 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/empty_config.yaml @@ -0,0 +1,49 @@ +--- +- ansible.builtin.debug: + msg: START junos_ospfv3 empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospfv3: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospfv3: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospfv3: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_ospfv3: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..5f9a871f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,34 @@ + + + + + + + 0.0.0.100 + + 200 + + + so-0/0/0.0 + + 5 + 3 + + + + + 0.0.0.200 + + ge-1/1/0.0 + + + ge-2/2/0.0 + + + + + + 10.200.16.75 + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/gathered.yaml new file mode 100644 index 00000000..e8c32a8f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/gathered.yaml @@ -0,0 +1,38 @@ +--- +- ansible.builtin.debug: + msg: START junos_ospfv3 gathered integration tests on connection={{ + ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_gathered_output: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + - area_id: 0.0.0.200 + interfaces: + - name: ge-2/2/0.0 + + - name: Gather interfaces facts using gathered state + register: result + junipernetworks.junos.junos_ospfv3: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + "{{ expected_gathered_output | symmetric_difference(result['gathered']) |length\ + \ == 0 }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_ospfv3 gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/merged.yaml new file mode 100644 index 00000000..81f3e3ca --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/merged.yaml @@ -0,0 +1,57 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospfv3 merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.set_fact: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - metric: 5 + name: so-0/0/0.0 + priority: 3 + stub: + default_metric: 200 + set: true + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_ospfv3: &merged + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + state: merged + register: result + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config|symmetric_difference(result.after) == [] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_ospfv3: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospfv3 merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/overridden.yaml new file mode 100644 index 00000000..552c80fa --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/overridden.yaml @@ -0,0 +1,64 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospfv3 overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: true + passive: true + - area_id: 0.0.0.200 + interfaces: + - name: ge-1/1/0.0 + - name: ge-2/2/0.0 + + - name: Override Junos OSPF config + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: true + passive: true + - area_id: 0.0.0.200 + interfaces: + - name: ge-1/1/0.0 + - name: ge-2/2/0.0 + state: overridden + register: result + + - name: Assert changed + ansible.builtin.assert: &changed + that: + - result.changed == True + - "{{ config|symmetric_difference(result.after) == [] }}" + + - name: Assert changed + ansible.builtin.assert: *changed + + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospfv3 overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/parsed.yaml new file mode 100644 index 00000000..613ffd2c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/parsed.yaml @@ -0,0 +1,40 @@ +--- +- ansible.builtin.debug: + msg: + START junos_ospfv3 parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: true + passive: true + - area_id: 0.0.0.200 + interfaces: + - name: ge-1/1/0.0 + - name: ge-2/2/0.0 + +- name: Parse externally provided interfaces config to agnostic model + register: result + junipernetworks.junos.junos_ospfv3: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output | symmetric_difference(result['parsed']) |length ==\ + \ 0 }}" +- ansible.builtin.debug: + msg: + END junos_ospfv3 parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/rendered.yaml new file mode 100644 index 00000000..9bb6a48c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/rendered.yaml @@ -0,0 +1,38 @@ +--- +- ansible.builtin.debug: + msg: START junos_ospfv3 rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: '0.0.0.100so-0/0/0.0352000.0.0.200ge-1/1/0.0ge-2/2/0.0' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: true + passive: true + - area_id: 0.0.0.200 + interfaces: + - name: ge-1/1/0.0 + - name: ge-2/2/0.0 + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_ospfv3 rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/replaced.yaml new file mode 100644 index 00000000..6750990f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_ospfv3/tests/netconf/replaced.yaml @@ -0,0 +1,41 @@ +--- +- ansible.builtin.debug: + msg: "START junos_ospfv3 replaced integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.200 + interfaces: + - name: ge-2/2/0.0 + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + + - name: Replace configuration + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + state: replaced + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - "{{ config|symmetric_difference(result.after) == [] }}" + + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_ospfv3 replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..280b43ff --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/_reset_config.yaml @@ -0,0 +1,10 @@ +--- +- ansible.builtin.debug: + msg: "START junos_prefix_lists reset config on connection={{ ansible_connection }}" + +- name: Reset the prefix lists configuration + junipernetworks.junos.junos_config: + lines: + - delete policy-options +- ansible.builtin.debug: + msg: "END junos_prefix_lists reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/deleted.yaml new file mode 100644 index 00000000..b3010c2a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/deleted.yaml @@ -0,0 +1,78 @@ +--- +- ansible.builtin.debug: + msg: "START junos_prefix_lists deleted integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.set_fact: + expected_deleted_output: + - dynamic_db: true + name: Test1 + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_prefix_lists: &merged + config: + - name: Internal + address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + - name: Test1 + dynamic_db: true + - name: Test2 + address_prefixes: + - 172.16.2.16/28 + - 172.16.2.32/28 + - 172.16.2.48/28 + state: merged + + - name: Delete existing prefix list configuration identified with name + junipernetworks.junos.junos_prefix_lists: &deleted + config: + - name: Test2 + - name: Internal + state: deleted + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_deleted_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: Delete the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_prefix_lists: *deleted + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - ansible.builtin.set_fact: + expected_deleted_output: [] + + - name: Merge the existing config with provided configuration + junipernetworks.junos.junos_prefix_lists: *merged + register: result + + - name: Delete complete existing bgp address family configuration + junipernetworks.junos.junos_prefix_lists: &deleted_res + config: + state: deleted + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_deleted_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + tags: deleted + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_prefix_lists deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..c8df9e36 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/empty_config.yaml @@ -0,0 +1,62 @@ +--- +- ansible.builtin.debug: + msg: + START junos_prefix_lists empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_prefix_lists: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_prefix_lists: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Override with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_prefix_lists: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_prefix_lists: + running_config: + state: parsed + +- ansible.builtin.debug: + msg: result +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_prefix_lists: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..3ed5f856 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,21 @@ + + + + 18.4R1-S2.4 + + + 64510 + + + 64500 + + + 172.16.1.16/28 + + + 172.16.1.32/28 + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/gathered.yaml new file mode 100644 index 00000000..18c9d6f8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/gathered.yaml @@ -0,0 +1,56 @@ +--- +- ansible.builtin.debug: + msg: START junos_prefix_lists gathered integration tests on connection={{ ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.set_fact: + expected_gathered_output: + - address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + name: Internal + - dynamic_db: true + name: Test1 + - address_prefixes: + - 172.16.2.16/28 + - 172.16.2.32/28 + - 172.16.2.48/28 + name: Test2 + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_prefix_lists: &merged + config: + - name: Internal + address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + - name: Test1 + dynamic_db: true + - name: Test2 + address_prefixes: + - 172.16.2.16/28 + - 172.16.2.32/28 + - 172.16.2.48/28 + state: merged + register: result + + - name: Gather prefix-lists facts using gathered state + register: result + junipernetworks.junos.junos_prefix_lists: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + - "{{ expected_gathered_output | symmetric_difference(result['gathered']) |length\ + \ == 0 }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_prefix_lists gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/merged.yaml new file mode 100644 index 00000000..a780e097 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/merged.yaml @@ -0,0 +1,93 @@ +--- +- ansible.builtin.debug: + msg: "START junos_prefix_lists merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.set_fact: + expected_merged_output: + - address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + name: Internal + - dynamic_db: true + name: Test1 + - address_prefixes: + - 172.16.2.16/28 + - 172.16.2.32/28 + - 172.16.2.48/28 + name: Test2 + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_prefix_lists: &merged + config: + - name: Internal + address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + - name: Test1 + dynamic_db: true + - name: Test2 + address_prefixes: + - 172.16.2.16/28 + - 172.16.2.32/28 + - 172.16.2.48/28 + state: merged + register: result + + - name: Assert the correct configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_merged_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_prefix_lists: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - ansible.builtin.set_fact: + expected_merged_output: + - address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + - 172.16.1.48/28 + name: Internal + - dynamic_db: true + name: Test1 + - address_prefixes: + - 172.16.2.16/28 + - 172.16.2.32/28 + - 172.16.2.48/28 + name: Test2 + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_prefix_lists: + config: + - name: Internal + address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + - 172.16.1.48/28 + state: merged + register: result + + - name: Assert the correct configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_merged_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_prefix_lists merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/overridden.yaml new file mode 100644 index 00000000..9994c90c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/overridden.yaml @@ -0,0 +1,70 @@ +--- +- ansible.builtin.debug: + msg: "START junos_prefix_lists overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.set_fact: + expected_overridden_output: + - address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + name: Internal + - address_prefixes: + - 172.16.2.48/28 + - 172.16.3.32/28 + name: Test2 + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_prefix_lists: &merged + config: + - name: Internal + address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + - name: Test1 + dynamic_db: true + - name: Test2 + address_prefixes: + - 172.16.2.16/28 + - 172.16.2.32/28 + - 172.16.2.48/28 + state: merged + + - name: Override the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_prefix_lists: &overridden + config: + - name: Internal + address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + - name: Test2 + address_prefixes: + - 172.16.3.32/28 + - 172.16.2.48/28 + state: overridden + register: result + + - name: Assert the correct configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_overridden_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: Override existing running prefix lists configuration with provided (IDEMPOTENT) + junipernetworks.junos.junos_prefix_lists: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_prefix_lists overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/parsed.yaml new file mode 100644 index 00000000..18fec21b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/parsed.yaml @@ -0,0 +1,30 @@ +--- +- ansible.builtin.debug: + msg: + START junos_prefix_lists parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + - name: "64510" + - address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + dynamic_db: true + name: "64500" + +- name: Parse externally provided prefix_lists config to agnostic model + register: result + junipernetworks.junos.junos_prefix_lists: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output | symmetric_difference(result['parsed']) |length\ + \ == 0 }}" +- ansible.builtin.debug: + msg: + END junos_prefix_lists parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/rendered.yaml new file mode 100644 index 00000000..05650bfa --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/rendered.yaml @@ -0,0 +1,34 @@ +--- +- ansible.builtin.debug: + msg: START junos_prefix_lists rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: 'Internal172.16.1.16/28172.16.1.32/28Test1Test2172.16.2.16/28172.16.2.32/28172.16.2.48/28' +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_prefix_lists: + config: + - name: Internal + address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + - name: Test1 + dynamic_db: true + - name: Test2 + address_prefixes: + - 172.16.2.16/28 + - 172.16.2.32/28 + - 172.16.2.48/28 + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - result.changed == False + - "{{ expected_rendered_output | symmetric_difference(result['rendered']) |length\ + \ == 0 }}" + +- ansible.builtin.debug: + msg: END junos_prefix_lists rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/replaced.yaml new file mode 100644 index 00000000..f38cc9d4 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_prefix_lists/tests/netconf/replaced.yaml @@ -0,0 +1,72 @@ +--- +- ansible.builtin.debug: + msg: "START junos_prefix_lists replaced integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.set_fact: + expected_replaced_output: + - address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + name: Internal + - dynamic_db: true + name: Test1 + - address_prefixes: + - 172.16.2.48/28 + - 172.16.3.32/28 + name: Test2 + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_prefix_lists: &merged + config: + - name: Internal + address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + - name: Test1 + dynamic_db: true + - name: Test2 + address_prefixes: + - 172.16.2.16/28 + - 172.16.2.32/28 + - 172.16.2.48/28 + state: merged + + - name: Replace the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_prefix_lists: &replaced + config: + - name: Internal + address_prefixes: + - 172.16.1.16/28 + - 172.16.1.32/28 + - name: Test2 + address_prefixes: + - 172.16.3.32/28 + - 172.16.2.48/28 + state: replaced + register: result + + - name: Assert the correct configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_replaced_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: Replace existing running prefix lists configuration with provided (IDEMPOTENT) + junipernetworks.junos.junos_prefix_lists: *replaced + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_prefix_lists replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..c2ffc16e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/_initial_config.yaml @@ -0,0 +1,12 @@ +--- +- ansible.builtin.debug: + msg: "START junos_routing_instances reset config on connection={{ ansible_connection }}" + +- name: Configure policy options w.r.t routing-instances + junipernetworks.junos.junos_config: + lines: + - set policy-options policy-statement test-policy term t1 then reject + - set policy-options policy-statement test-policy-1 term t1 then reject + +- ansible.builtin.debug: + msg: "END junos_routing_instances reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..dd2e4faa --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/_reset_config.yaml @@ -0,0 +1,12 @@ +--- +- ansible.builtin.debug: + msg: "START junos_routing_instances reset config on connection={{ ansible_connection }}" + +- name: Reset the config releavent to bgp address family resource + junipernetworks.junos.junos_config: + lines: + - delete routing-instances + - delete policy-options + +- ansible.builtin.debug: + msg: "END junos_routing_instances reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/deleted.yaml new file mode 100644 index 00000000..4fb1f749 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/deleted.yaml @@ -0,0 +1,84 @@ +--- +- ansible.builtin.debug: + msg: "START junos_routing_instances deleted integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_deleted_output: + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_routing_instances: &merged + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + state: merged + + - name: Delete existing configuration with running configuration + junipernetworks.junos.junos_routing_instances: &deleted + config: + - name: "test" + state: deleted + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_deleted_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: Delete the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_routing_instances: *deleted + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - ansible.builtin.set_fact: + expected_deleted_rints_output: [] + + - name: Merge the existing config with provided configuration + junipernetworks.junos.junos_routing_instances: *merged + register: result + + - name: Delete complete existing bgp address family configuration + junipernetworks.junos.junos_routing_instances: &deleted_res + config: + state: deleted + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_deleted_rints_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + tags: deleted + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_routing_instances deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..2d4c4b63 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/empty_config.yaml @@ -0,0 +1,62 @@ +--- +- ansible.builtin.debug: + msg: + START junos_routing_instances empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_routing_instances: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_routing_instances: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Override with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_routing_instances: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_routing_instances: + running_config: + state: parsed + +- ansible.builtin.debug: + msg: result +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_routing_instances: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..bbbb4040 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,30 @@ + + + + 18.4R1-S2.4 + + + forwardinst + Configured by Ansible Content Team + forwarding + + + test + vrf + + gr-0/0/0.0 + + + sp-0/0/0.0 + + + 10.58.255.1:37 + + test-policy + test-policy + test-policy-1 + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/gathered.yaml new file mode 100644 index 00000000..a311f835 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/gathered.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: START junos_routing_instances gathered integration tests on connection={{ ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_gathered_output: + - description: "Configured by Ansible Content Team" + name: "forwardinst" + type: "forwarding" + + - connector_id_advertise: true + interfaces: + - name: "gr-0/0/0.0" + - name: "sp-0/0/0.0" + name: "test" + route_distinguisher: "10.58.255.1:37" + type: "vrf" + vrf_exports: + - "test-policy" + - "test-policy-1" + vrf_imports: + - "test-policy" + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_routing_instances: &merged + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + state: merged + + - name: Gather bgp address family facts using gathered state + register: result + junipernetworks.junos.junos_routing_instances: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + "{{ expected_gathered_output | symmetric_difference(result['gathered']) |length\ + \ == 0 }}" + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_routing_instances gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/merged.yaml new file mode 100644 index 00000000..b35b7767 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/merged.yaml @@ -0,0 +1,71 @@ +--- +- ansible.builtin.debug: + msg: "START junos_routing_instances merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_merged_output: + - description: "Configured by Ansible Content Team" + name: "forwardinst" + type: "forwarding" + + - connector_id_advertise: true + interfaces: + - name: "gr-0/0/0.0" + - name: "sp-0/0/0.0" + name: "test" + route_distinguisher: "10.58.255.1:37" + type: "vrf" + vrf_exports: + - "test-policy" + - "test-policy-1" + vrf_imports: + - "test-policy" + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_routing_instances: &merged + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + state: merged + register: result + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_merged_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_routing_instances: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_routing_instances merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/overridden.yaml new file mode 100644 index 00000000..8ccc0e22 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/overridden.yaml @@ -0,0 +1,111 @@ +--- +- ansible.builtin.debug: + msg: "START junos_routing_instances overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_overridden_output: + - description: "Configured by Ansible Content Team" + name: "forwardinst" + type: "forwarding" + - connector_id_advertise: true + interfaces: + - name: "gr-0/0/0.0" + - name: "sp-0/0/0.0" + name: "test" + route_distinguisher: "10.58.255.1:37" + type: "vrf" + vrf_exports: + - "test-policy" + - "test-policy-1" + vrf_imports: + - "test-policy" + - name: "vtest1" + type: "virtual-router" + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_routing_instances: &merged + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + state: merged + + - name: Replace existing configuration with running configuration + junipernetworks.junos.junos_routing_instances: &replaced + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.57.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: false + description: "Configured by Ansible Content Team" + state: replaced + + - name: Override existing configuration with running configuration + junipernetworks.junos.junos_routing_instances: &overridden + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + - name: "vtest1" + type: "virtual-router" + state: overridden + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_overridden_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: Override the existing running configuration with the provided configuration (IDEMPOTENT) + junipernetworks.junos.junos_routing_instances: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_routing_instances overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/parsed.yaml new file mode 100644 index 00000000..e88c5730 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/parsed.yaml @@ -0,0 +1,39 @@ +--- +- ansible.builtin.debug: + msg: + START junos_routing_instances parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + - description: "Configured by Ansible Content Team" + name: "forwardinst" + type: "forwarding" + + - connector_id_advertise: true + interfaces: + - name: "gr-0/0/0.0" + - name: "sp-0/0/0.0" + name: "test" + route_distinguisher: "10.58.255.1:37" + type: "vrf" + vrf_exports: + - "test-policy" + - "test-policy-1" + vrf_imports: + - "test-policy" + +- name: Parse externally provided routing_instances config to agnostic model + register: result + junipernetworks.junos.junos_routing_instances: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output == result['parsed'] }}" +- ansible.builtin.debug: + msg: + END junos_routing_instances parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/rendered.yaml new file mode 100644 index 00000000..60081f95 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/rendered.yaml @@ -0,0 +1,37 @@ +--- +- ansible.builtin.debug: + msg: + START junos_routing_instances rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: 'testvrfsp-0/0/0.0gr-0/0/0.010.58.255.1:37test-policytest-policytest-policy-1forwardinstConfigured by Ansible Content Teamforwarding' +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_routing_instances rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/replaced.yaml new file mode 100644 index 00000000..82e17808 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_instances/tests/netconf/replaced.yaml @@ -0,0 +1,87 @@ +--- +- ansible.builtin.debug: + msg: "START junos_routing_instances replaced integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_replaced_output: + - description: "Configured by Ansible Content Team" + name: "forwardinst" + type: "forwarding" + + - description: "Configured by Ansible Content Team" + interfaces: + - name: "gr-0/0/0.0" + - name: "sp-0/0/0.0" + name: "test" + route_distinguisher: "10.57.255.1:37" + type: "vrf" + vrf_exports: + - "test-policy" + vrf_imports: + - "test-policy" + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_routing_instances: &merged + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + state: merged + + - name: Replace existing configuration with running configuration + junipernetworks.junos.junos_routing_instances: &replaced + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.57.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: false + description: "Configured by Ansible Content Team" + state: replaced + register: result + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ expected_replaced_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_routing_instances: *replaced + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_routing_instances replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/_populate_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/_populate_config.yaml new file mode 100644 index 00000000..5b2bacc9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/_populate_config.yaml @@ -0,0 +1,8 @@ +--- +- name: Populate config + junipernetworks.junos.junos_config: + lines: + - "set routing-options autonomous-system asdot-notation" + - "set routing-options autonomous-system loops 4" + - "set routing-options autonomous-system 2" + - "set routing-options router-id 12.12.12.12" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..46c86164 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/_reset_config.yaml @@ -0,0 +1,12 @@ +--- +- ansible.builtin.debug: + msg: "START junos_routing_options reset config on connection={{ ansible_connection }}" + +- name: Reset routing options configuration + junipernetworks.junos.junos_config: + lines: + - delete routing-options router-id + - delete routing-options autonomous-system + +- ansible.builtin.debug: + msg: "END junos_routing_options reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/deleted.yaml new file mode 100644 index 00000000..bf5a7906 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/deleted.yaml @@ -0,0 +1,25 @@ +--- +- ansible.builtin.debug: + msg: "START junos_routing_options deleted integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + - ansible.builtin.set_fact: + config: {} + - name: Delete all ospf config from the device + junipernetworks.junos.junos_routing_options: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config == result.after }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_routing_options deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..3065f768 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: + START junos_routing_options empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_routing_options: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_routing_options: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_routing_options: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_routing_options: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_routing_options: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..c430edf7 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,14 @@ + + + + 18.4R1-S2.4 + + 12.12.12.12 + + 2 + 4 + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/gathered.yaml new file mode 100644 index 00000000..cc2369a2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/gathered.yaml @@ -0,0 +1,24 @@ +--- +- ansible.builtin.debug: + msg: START junos_routing_options gathered integration tests on connection={{ ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Gather interfaces facts using gathered state + register: result + junipernetworks.junos.junos_routing_options: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ merged['updated'] == result['gathered'] }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_routing_options gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/merged.yaml new file mode 100644 index 00000000..a924e8d0 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/merged.yaml @@ -0,0 +1,59 @@ +--- +- ansible.builtin.debug: + msg: "START junos_routing_options merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_routing_options: &merged + config: + autonomous_system: + as_number: 2 + asdot_notation: true + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['before'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['after'] == result['after'] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_routing_options: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - name: Update the running configuration with providede configuration + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + loops: 4 + router_id: "12.12.12.12" + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['updated'] == result['after'] }}" + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_routing_options merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/overridden.yaml new file mode 100644 index 00000000..789cf05f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/overridden.yaml @@ -0,0 +1,44 @@ +--- +- ansible.builtin.debug: + msg: "START junos_routing_options overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Override configuration + junipernetworks.junos.junos_routing_options: &overridden + config: + autonomous_system: + as_number: 1 + asdot_notation: true + router_id: "10.10.10.10" + + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['updated'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result.after }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_routing_options: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_routing_options overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/parsed.yaml new file mode 100644 index 00000000..04e98a0a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/parsed.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: + START junos_routing_options parsed integration tests on connection={{ ansible_connection + }} + +- name: Parse externally provided routing_options config to agnostic model + register: result + junipernetworks.junos.junos_routing_options: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['updated'] == result['parsed'] }}" +- ansible.builtin.debug: + msg: + END junos_routing_options parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/rendered.yaml new file mode 100644 index 00000000..6429cb1c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/rendered.yaml @@ -0,0 +1,27 @@ +--- +- ansible.builtin.debug: + msg: START junos_routing_options rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: '2412.12.12.12' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + loops: 4 + router_id: 12.12.12.12 + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_routing_options rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/replaced.yaml new file mode 100644 index 00000000..4a6a9a2f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/replaced.yaml @@ -0,0 +1,44 @@ +--- +- ansible.builtin.debug: + msg: "START junos_routing_options overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Override configuration + junipernetworks.junos.junos_routing_options: &replaced + config: + autonomous_system: + as_number: 1 + asdot_notation: true + router_id: "10.10.10.10" + + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['updated'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result.after }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_routing_options: *replaced + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_routing_options overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/rtt.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/rtt.yml new file mode 100644 index 00000000..b23153fd --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/tests/netconf/rtt.yml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: + START junos_routing_options round trip integration tests on connection={{ + ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + lo ops: 4 + router_id: 12.12.12.12 + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - routing_options + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 1 + asdot_notation: true + router_id: "10.10.10.10" + state: replaced + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_routing_options: + config: "{{ ansible_facts['network_resources']['routing_options'] }}" + state: replaced + + - name: Assert that before dicts are correct + ansible.builtin.assert: + that: + - result.changed == True + - "{{ result['after'] == revert['before'] }}" + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + - result.changed == True + - "{{ base_config['after'] == revert['after'] }}" + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_routing_options round trip integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/vars/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/vars/main.yaml new file mode 100644 index 00000000..d9e9d26f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_routing_options/vars/main.yaml @@ -0,0 +1,21 @@ +--- +merged: + before: {} + + after: + autonomous_system: + as_number: "2" + asdot_notation: true + + updated: + autonomous_system: + as_number: "2" + asdot_notation: true + loops: 4 + router_id: "12.12.12.12" +replaced: + after: + autonomous_system: + as_number: "1" + asdot_notation: true + router_id: "10.10.10.10" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/defaults/main.yaml new file mode 100644 index 00000000..9ef5ba51 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/tasks/main.yaml new file mode 100644 index 00000000..ac951c8f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/tasks/main.yaml @@ -0,0 +1,3 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/tasks/netconf.yaml new file mode 100644 index 00000000..3fa0553b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/tasks/netconf.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + register: test_cases + connection: local + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/tests/netconf/rpc.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/tests/netconf/rpc.yaml new file mode 100644 index 00000000..3036980c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_rpc/tests/netconf/rpc.yaml @@ -0,0 +1,69 @@ +--- +- ansible.builtin.debug: msg="START netconf/rpc.yaml on connection={{ ansible_connection }}" + +- name: Execute RPC on device + register: result + junipernetworks.junos.junos_rpc: + rpc: get-interface-information + +- ansible.builtin.assert: + that: + - result.changed == false + - "'\nlo0\n
' in result['xml']" + - "'\nem0\n' not in result['xml']" + - "'\fxp0\n' not in result['xml']" + +- name: Execute RPC on device and get output in text format + register: result + junipernetworks.junos.junos_rpc: + rpc: get-interface-information + output: text + +- ansible.builtin.assert: + that: + - result.changed == false + - result.output is defined + - result.output_lines is defined + - "'Physical interface' in result['output']" + +- name: Execute RPC on device and get output in json format + register: result + junipernetworks.junos.junos_rpc: + rpc: get-interface-information + output: json + args: + interface-name: lo0 + media: true + +- ansible.builtin.assert: + that: + - result.changed == false + - result.output is defined + - result['output']['interface-information'][0]['physical-interface'][0]['name'][0]['data'] + == "lo0" + +- name: Execute invalid RPC + register: result + ignore_errors: true + junipernetworks.junos.junos_rpc: + rpc: show-interface-information + +- ansible.builtin.assert: + that: + - result.failed == true + +- ansible.builtin.debug: msg="END netconf/rpc.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..11b82c1a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/_initial_config.yaml @@ -0,0 +1,37 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies initial config on connection={{ ansible_connection }}" + +- name: Generate ssl certificates for ssl proxy profile-name + junipernetworks.junos.junos_command: + commands: + - request security pki generate-key-pair certificate-id SECURITY-cert size 2048 type rsa + - request security pki local-certificate generate-self-signed certificate-id SECURITY-cert domain-name labs.abc.net subject DC=mydomain.net,L=Sunnyvale,O=Mydomain,OU=LAB,CN=SECURITY email lab@labs.abc.net add-ca-constraint + +- name: Configure basic config relevant to security policies + junipernetworks.junos.junos_config: + lines: + - set class-of-service application-traffic-control rule-sets test_traffic_control rule test_rule match application-known + - set class-of-service application-traffic-control rule-sets test_traffic_control rule test_rule then log + - set security address-book global address a1 200.0.113.0/24 + - set security address-book global address a2 201.0.113.0/24 + - set security address-book global address a3 202.0.113.0/24 + - set security address-book global address a4 203.0.113.0/24 + - set security dynamic-application profile test_dyn_app redirect-message type custom-text content hello_world + - set security gprs gtp profile gtp1 + - set interfaces ge-0/0/0 unit 0 family inet address 200.0.113.1/24 + - set interfaces ge-0/0/1 unit 0 family inet address 201.0.113.1/24 + - set interfaces ge-0/0/2 unit 0 family inet address 202.0.113.1/24 + - set security zones security-zone one interfaces ge-0/0/0 + - set security zones security-zone two interfaces ge-0/0/1 + - set security zones security-zone three interfaces ge-0/0/2 + - set services icap-redirect profile test_icap server test_icap_server host 10.10.10.11 + - set services user-identification device-information end-user-profile profile-name test_end_user_profile attribute device-identity string Windows + - set services user-identification device-information end-user-profile profile-name test_end_user_profile domain-name test_domain + - set services ssl proxy profile SECURITY-SSL-PROXY root-ca SECURITY-cert + - set access profile WEBAUTH client FWClient1 firewall-user password pwd + - set access firewall-authentication web-authentication default-profile WEBAUTH + - set services ssl termination profile test_ssl_term server-certificate SECURITY-cert + +- ansible.builtin.debug: + msg: "END junos_security_policies initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/_populate_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/_populate_config.yaml new file mode 100644 index 00000000..b32dc1af --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/_populate_config.yaml @@ -0,0 +1,53 @@ +--- +- name: Populate config + junipernetworks.junos.junos_config: + lines: + - set security policies from-zone one to-zone two policy test_policy_1 match source-address a1 + - set security policies from-zone one to-zone two policy test_policy_1 match source-address a3 + - set security policies from-zone one to-zone two policy test_policy_1 match destination-address a2 + - set security policies from-zone one to-zone two policy test_policy_1 match destination-address a4 + - set security policies from-zone one to-zone two policy test_policy_1 match application junos-dhcp-relay + - set security policies from-zone one to-zone two policy test_policy_1 match application junos-finger + - set security policies from-zone one to-zone two policy test_policy_1 match source-identity authenticated-user + - set security policies from-zone one to-zone two policy test_policy_1 match source-identity unknown-user + - set security policies from-zone one to-zone two policy test_policy_1 match source-end-user-profile test_end_user_profile + - set security policies from-zone one to-zone two policy test_policy_1 match source-address-excluded + - set security policies from-zone one to-zone two policy test_policy_1 match destination-address-excluded + - set security policies from-zone one to-zone two policy test_policy_1 match dynamic-application any + - set security policies from-zone one to-zone two policy test_policy_1 match url-category Enhanced_Web_Chat + - set security policies from-zone one to-zone two policy test_policy_1 then deny + - set security policies from-zone one to-zone two policy test_policy_1 then log session-close + - set security policies from-zone one to-zone two policy test_policy_1 then count + - set security policies from-zone one to-zone two policy test_policy_2 match source-address a1 + - set security policies from-zone one to-zone two policy test_policy_2 match destination-address any-ipv6 + - set security policies from-zone one to-zone two policy test_policy_2 match application any + - set security policies from-zone one to-zone two policy test_policy_2 then reject + - set security policies from-zone one to-zone two policy test_policy_2 then reject profile test_dyn_app + - set security policies from-zone one to-zone two policy test_policy_2 then reject ssl-proxy profile-name SECURITY-SSL-PROXY + - set security policies from-zone one to-zone three policy test_policy_3 match source-address a1 + - set security policies from-zone one to-zone three policy test_policy_3 match destination-address a2 + - set security policies from-zone one to-zone three policy test_policy_3 match application any + - set security policies from-zone one to-zone three policy test_policy_3 then permit application-services application-traffic-control rule-set test_traffic_control + - set security policies from-zone one to-zone three policy test_policy_3 then permit application-services gprs-gtp-profile gtp1 + - set security policies from-zone one to-zone three policy test_policy_3 then permit application-services icap-redirect test_icap + - set security policies from-zone one to-zone three policy test_policy_3 then permit application-services reverse-redirect-wx + - set security policies from-zone one to-zone three policy test_policy_3 then permit application-services uac-policy + - set security policies from-zone one to-zone three policy test_policy_3 then permit destination-address drop-untranslated + - set security policies from-zone one to-zone three policy test_policy_3 then permit firewall-authentication pass-through auth-user-agent Opera1 + - set security policies from-zone one to-zone three policy test_policy_3 then permit firewall-authentication pass-through auth-only-browser + - set security policies from-zone one to-zone three policy test_policy_3 then permit firewall-authentication push-to-identity-management + - set security policies from-zone one to-zone three policy test_policy_3 then permit firewall-authentication user-firewall access-profile WEBAUTH + - set security policies from-zone one to-zone three policy test_policy_3 then permit firewall-authentication user-firewall auth-only-browser + - set security policies from-zone one to-zone three policy test_policy_3 then permit firewall-authentication user-firewall auth-user-agent Opera1 + - set security policies from-zone one to-zone three policy test_policy_3 then permit firewall-authentication user-firewall web-redirect-to-https + - set security policies from-zone one to-zone three policy test_policy_3 then permit firewall-authentication web-authentication client-match FWClient1 + - set security policies from-zone one to-zone three policy test_policy_3 then permit tcp-options initial-tcp-mss 64 + - set security policies from-zone one to-zone three policy test_policy_3 then permit tcp-options window-scale + - set security policies global policy test_glob_1 match source-address any-ipv6 + - set security policies global policy test_glob_1 match destination-address any-ipv6 + - set security policies global policy test_glob_1 match application any + - set security policies global policy test_glob_1 then deny + - set security policies global policy test_glob_2 match source-address any-ipv6 + - set security policies global policy test_glob_2 match destination-address any-ipv6 + - set security policies global policy test_glob_2 match application any + - set security policies global policy test_glob_2 then deny diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..746e6409 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/_reset_config.yaml @@ -0,0 +1,22 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies reset config on connection={{ ansible_connection }}" + +- name: Reset the config releavent to security policies resources + junipernetworks.junos.junos_config: + lines: + - delete security + - delete services + - delete class-of-service + - delete access + - delete interfaces ge-0/0/0 + - delete interfaces ge-0/0/1 + - delete interfaces ge-0/0/2 + +- name: Reset the generated security certificates + junipernetworks.junos.junos_command: + commands: + - clear security pki local-certificate all + +- ansible.builtin.debug: + msg: "END junos_security_policies reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/deleted.yaml new file mode 100644 index 00000000..caf0ec02 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/deleted.yaml @@ -0,0 +1,27 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies deleted integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + - ansible.builtin.set_fact: + config: {} + + - name: Delete all security policies from the device + junipernetworks.junos.junos_security_policies: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config == result.after }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_security_policies deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..c4e646fa --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: + START junos_security_policies empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_policies: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_policies: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_policies: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_policies: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_policies: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/fixtures/parsed.xml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/fixtures/parsed.xml new file mode 100644 index 00000000..48895bce --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/fixtures/parsed.xml @@ -0,0 +1,301 @@ + + + + 18.4R1-S3.1 + + + + + test_ssl_term + SECURITY-cert + + + + + SECURITY-SSL-PROXY + SECURITY-cert + + + + + + test_icap + + test_icap_server + 10.10.10.11 + + + + + + + + test_end_user_profile + test_domain + + device-identity + Windows + + + + + + + + + global +
+ a1 + 200.0.113.0/24 +
+
+ a2 + 201.0.113.0/24 +
+
+ a3 + 202.0.113.0/24 +
+
+ a4 + 203.0.113.0/24 +
+
+ + + test_dyn_app + + + + hello_world + + + + + + + + one + two + + test_policy_1 + + a1 + a3 + a2 + a4 + + + junos-dhcp-relay + junos-finger + authenticated-user + unknown-user + + test_end_user_profile + + any + Enhanced_Web_Chat + + + + + + + + + + + test_policy_2 + + a1 + any-ipv6 + any + + + + test_dyn_app + + SECURITY-SSL-PROXY + + + + + + + one + three + + test_policy_3 + + a1 + a2 + any + + + + + + FWClient1 + + + + + + + + gtp1 + + test_icap + + test_traffic_control + + + + + 64 + + + + + + + + + test_glob_1 + + any-ipv6 + any-ipv6 + any + + + + + + + test_glob_2 + + any-ipv6 + any-ipv6 + any + + + + + + + + + + one + + ge-0/0/0.0 + + + + two + + ge-0/0/1.0 + + + + three + + ge-0/0/2.0 + + + + + + + gtp1 + + + +
+ + + ge-0/0/0 + + 0 + + +
+ 200.0.113.1/24 +
+
+
+
+
+ + ge-0/0/1 + + 0 + + +
+ 201.0.113.1/24 +
+
+
+
+
+ + ge-0/0/2 + + 0 + + +
+ 202.0.113.1/24 +
+
+
+
+
+ + fxp0 + + 0 + + + + + + + +
+ + + + test_traffic_control + + test_rule + + + + + + + + + + + + + WEBAUTH + + FWClient1 + + $9$kq5Ftu1cSe + + + + + + WEBAUTH + + + +
+ +
diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/gathered.yaml new file mode 100644 index 00000000..8cde24c6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/gathered.yaml @@ -0,0 +1,25 @@ +--- +- ansible.builtin.debug: + msg: START junos_security_policies gathered integration tests on connection={{ ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Gather security policies facts using gathered state + register: result + junipernetworks.junos.junos_security_policies: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['gathered'] }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_security_policies gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/merged.yaml new file mode 100644 index 00000000..bbf1b26a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/merged.yaml @@ -0,0 +1,171 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_security_policies: &merged + config: + from_zones: + - name: one + to_zones: + - name: two + policies: + - match: + application: + names: + - junos-dhcp-relay + - junos-finger + destination_address: + addresses: + - a2 + - a4 + destination_address_excluded: true + dynamic_application: + names: + - any + source_address: + addresses: + - a1 + - a3 + source_address_excluded: true + source_end_user_profile: test_end_user_profile + source_identity: + authenticated_user: true + unknown_user: true + url_category: + names: + - Enhanced_Web_Chat + name: test_policy_1 + then: + count: true + deny: true + log: + session_close: true + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + addresses: + - a1 + name: test_policy_2 + then: + reject: + enable: true + profile: test_dyn_app + ssl_proxy: + enable: true + profile_name: SECURITY-SSL-PROXY + - name: three + policies: + - match: + application: + any: true + destination_address: + addresses: + - a2 + source_address: + addresses: + - a1 + name: test_policy_3 + then: + permit: + application_services: + application_traffic_control_rule_set: test_traffic_control + gprs_gtp_profile: gtp1 + icap_redirect: test_icap + reverse_redirect_wx: "True" + uac_policy: + enable: true + firewall_authentication: + push_to_identity_management: true + web_authentication: + - FWClient1 + tcp_options: + initial_tcp_mss: 64 + window_scale: true + global: + policies: + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any_ipv6: true + name: test_glob_1 + then: + deny: true + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any_ipv6: true + name: test_glob_2 + then: + deny: true + + state: merged + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['before'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['after'] == result['after'] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_security_policies: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - name: Update the running configuration with provided configuration + junipernetworks.junos.junos_security_policies: + config: + global: + policies: + - name: test_glob_3 + description: test update + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any: true + then: + deny: true + state: merged + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['updated'] == result['after'] }}" + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_security_policies merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/overridden.yaml new file mode 100644 index 00000000..90434091 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/overridden.yaml @@ -0,0 +1,53 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Override configuration + junipernetworks.junos.junos_security_policies: &overridden + config: + global: + policies: + - description: test update + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any: true + name: test_glob_3 + then: + deny: true + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result['changed'] == True + - "{{ replaced['after'] == result['after'] }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_security_policies: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_security_policies overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/parsed.yaml new file mode 100644 index 00000000..08e14d1b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/parsed.yaml @@ -0,0 +1,23 @@ +--- +- ansible.builtin.debug: + msg: + START junos_security_policies parsed integration tests on connection={{ ansible_connection + }} + +- name: Parse externally provided security_policies config to agnostic model + register: result + junipernetworks.junos.junos_security_policies: + running_config: "{{ lookup('file', './fixtures/parsed.xml') }}" + state: parsed + +- ansible.builtin.debug: + msg: "{{ result['parsed'] }}" + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['parsed'] }}" +- ansible.builtin.debug: + msg: + END junos_security_policies parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/rendered.yaml new file mode 100644 index 00000000..acb1b00e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/rendered.yaml @@ -0,0 +1,124 @@ +--- +- ansible.builtin.debug: + msg: + START junos_security_policies rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: 'onetwotest_policy_1a1a3a2a4junos-dhcp-relayjunos-fingertest_end_user_profileunknown-userEnhanced_Web_Chatany test_policy_2a1any-ipv6any test_dyn_app SECURITY-SSL-PROXYonethreetest_policy_3a1a2anytest_traffic_controlgtp1test_icap FWClient1 64test_glob_1any-ipv6any-ipv6anytest_glob_2any-ipv6any-ipv6any' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_security_policies: + config: + from_zones: + - name: one + to_zones: + - name: two + policies: + - match: + application: + names: + - junos-dhcp-relay + - junos-finger + destination_address: + addresses: + - a2 + - a4 + destination_address_excluded: true + dynamic_application: + names: + - any + source_address: + addresses: + - a1 + - a3 + source_address_excluded: true + source_end_user_profile: test_end_user_profile + source_identity: + unknown_user: true + url_category: + names: + - Enhanced_Web_Chat + name: test_policy_1 + then: + count: true + deny: true + log: + session_close: true + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + addresses: + - a1 + name: test_policy_2 + then: + reject: + enable: true + profile: test_dyn_app + ssl_proxy: + enable: true + profile_name: SECURITY-SSL-PROXY + - name: three + policies: + - match: + application: + any: true + destination_address: + addresses: + - a2 + source_address: + addresses: + - a1 + name: test_policy_3 + then: + permit: + application_services: + application_traffic_control_rule_set: test_traffic_control + gprs_gtp_profile: gtp1 + icap_redirect: test_icap + reverse_redirect_wx: "True" + uac_policy: + enable: true + firewall_authentication: + push_to_identity_management: true + web_authentication: + - FWClient1 + tcp_options: + initial_tcp_mss: 64 + window_scale: true + global: + policies: + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any_ipv6: true + name: test_glob_1 + then: + deny: true + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any_ipv6: true + name: test_glob_2 + then: + deny: true + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_security_policies rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/replaced.yaml new file mode 100644 index 00000000..f4682e91 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/replaced.yaml @@ -0,0 +1,53 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies replaced integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Replace configuration + junipernetworks.junos.junos_security_policies: &replaced + config: + global: + policies: + - description: test update + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any: true + name: test_glob_3 + then: + deny: true + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result.after }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_security_policies: *replaced + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_security_policies replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/rtt.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/rtt.yml new file mode 100644 index 00000000..a35e2e9a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/tests/netconf/rtt.yml @@ -0,0 +1,197 @@ +--- +- ansible.builtin.debug: + msg: + START junos_security_policies round trip integration tests on connection={{ + ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_security_policies: + config: + from_zones: + - name: one + to_zones: + - name: two + policies: + - name: test_policy_1 + description: "hello world" + match: + application: + names: + - junos-dhcp-relay + - junos-finger + destination_address: + any_ipv6: true + source_address: + addresses: + - a1 + - a2 + source_identity: + authenticated_user: true + unknown_user: true + source_end_user_profile: test_end_user_profile + source_address_excluded: true + destination_address_excluded: true + dynamic_application: + any: true + url_category: + names: + - Enhanced_Web_Chat + then: + deny: true + log: + session_close: true + count: true + - name: test_policy_2 + description: hello world + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + addresses: + - a1 + then: + reject: + profile: test_dyn_app + ssl_proxy: + profile_name: SECURITY-SSL-PROXY + - name: two + policies: + - name: test_policy_2 + description: hello world + match: + application: + any: true + destination_address: + addresses: + - a2 + source_address: + addresses: + - a1 + then: + permit: + application_services: + application_traffic_control_rule_set: test_traffic_control + gprs_gtp_profile: gtp1 + icap_redirect: test_icap + reverse_redirect_wx: true + uac_policy: + enable: true + destination_address: drop-untranslated + firewall_authentication: + pass_through: + auth_user_agent: Opera1 + auth_only_browser: true + push_to_identity_management: true + user_firewall: + access_profile: WEBAUTH + auth_only_browser: true + auth_user_agent: Opera1 + web_redirect_to_https: true + web_authentication: + - client_match: FWClient1 + tcp_options: + initial_tcp_mss: 64 + window_scale: true + - name: two + to_zones: + - name: three + policies: + - name: test_policy_4 + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + addresses: + - a1 + then: + deny: true + global: + policies: + - name: test_glob_1 + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + addresses: + - a1 + then: + deny: true + - name: test_glob_2 + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + addresses: + - a1 + then: + deny: true + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - security_policies + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_security_policies: + config: + global: + policies: + - name: test_glob_1 + description: replaced + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + addresses: + - a1 + then: + deny: true + state: replaced + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_security_policies: + config: "{{ ansible_facts['network_resources']['security_policies'] }}" + state: replaced + + - name: Assert that before dicts are correct + ansible.builtin.assert: + that: + - result.changed == True + - "{{ result['after'] == revert['before'] }}" + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + - result.changed == True + - "{{ base_config['after'] == revert['after'] }}" + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_security_policies round trip integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/vars/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/vars/main.yaml new file mode 100644 index 00000000..9076a631 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies/vars/main.yaml @@ -0,0 +1,235 @@ +--- +merged: + before: {} + + after: + from_zones: + - name: one + to_zones: + - name: two + policies: + - match: + application: + names: + - junos-dhcp-relay + - junos-finger + destination_address: + addresses: + - a2 + - a4 + destination_address_excluded: true + dynamic_application: + any: true + source_address: + addresses: + - a1 + - a3 + source_address_excluded: true + source_end_user_profile: test_end_user_profile + source_identity: + authenticated_user: true + unknown_user: true + url_category: + names: + - Enhanced_Web_Chat + name: test_policy_1 + then: + count: true + deny: true + log: + session_close: true + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + addresses: + - a1 + name: test_policy_2 + then: + reject: + enable: true + profile: test_dyn_app + ssl_proxy: + enable: true + profile_name: SECURITY-SSL-PROXY + - name: three + policies: + - match: + application: + any: true + destination_address: + addresses: + - a2 + source_address: + addresses: + - a1 + name: test_policy_3 + then: + permit: + application_services: + application_traffic_control_rule_set: test_traffic_control + gprs_gtp_profile: gtp1 + icap_redirect: test_icap + reverse_redirect_wx: true + uac_policy: + enable: true + firewall_authentication: + push_to_identity_management: true + web_authentication: + - FWClient1 + tcp_options: + initial_tcp_mss: 64 + window_scale: true + global: + policies: + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any_ipv6: true + name: test_glob_1 + then: + deny: true + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any_ipv6: true + name: test_glob_2 + then: + deny: true + updated: + from_zones: + - name: one + to_zones: + - name: two + policies: + - match: + application: + names: + - junos-dhcp-relay + - junos-finger + destination_address: + addresses: + - a2 + - a4 + destination_address_excluded: true + dynamic_application: + any: true + source_address: + addresses: + - a1 + - a3 + source_address_excluded: true + source_end_user_profile: test_end_user_profile + source_identity: + authenticated_user: true + unknown_user: true + url_category: + names: + - Enhanced_Web_Chat + name: test_policy_1 + then: + count: true + deny: true + log: + session_close: true + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + addresses: + - a1 + name: test_policy_2 + then: + reject: + enable: true + profile: test_dyn_app + ssl_proxy: + enable: true + profile_name: SECURITY-SSL-PROXY + - name: three + policies: + - match: + application: + any: true + destination_address: + addresses: + - a2 + source_address: + addresses: + - a1 + name: test_policy_3 + then: + permit: + application_services: + application_traffic_control_rule_set: test_traffic_control + gprs_gtp_profile: gtp1 + icap_redirect: test_icap + reverse_redirect_wx: true + uac_policy: + enable: true + firewall_authentication: + push_to_identity_management: true + web_authentication: + - FWClient1 + tcp_options: + initial_tcp_mss: 64 + window_scale: true + global: + policies: + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any_ipv6: true + name: test_glob_1 + then: + deny: true + - match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any_ipv6: true + name: test_glob_2 + then: + deny: true + - description: test update + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any: true + name: test_glob_3 + then: + deny: true + +replaced: + after: + global: + policies: + - description: test update + match: + application: + any: true + destination_address: + any_ipv6: true + source_address: + any: true + name: test_glob_3 + then: + deny: true diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..abfb5cff --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/_initial_config.yaml @@ -0,0 +1,11 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies_global initial config on connection={{ ansible_connection }}" + +- name: Configure basic config relevant to security policies global + junipernetworks.junos.junos_config: + lines: + - set system tracing destination-override syslog host 10.0.0.4 + +- ansible.builtin.debug: + msg: "END junos_security_policies_global initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/_populate_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/_populate_config.yaml new file mode 100644 index 00000000..47fc2c9e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/_populate_config.yaml @@ -0,0 +1,22 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies_global populate config on connection={{ ansible_connection }}" + +- name: Populate config + junipernetworks.junos.junos_config: + lines: + - set security policies default-policy permit-all + - set security policies policy-rematch extensive + - set security policies policy-stats system-wide enable + - set security policies pre-id-default-policy then log session-init + - set security policies pre-id-default-policy then session-timeout icmp 10 + - set security policies pre-id-default-policy then session-timeout others 10 + - set security policies traceoptions no-remote-trace + - set security policies traceoptions flag all + - set security policies traceoptions file files 3 + - set security policies traceoptions file match /[A-Z]*/gm + - set security policies traceoptions file size 10240 + - set security policies traceoptions file no-world-readable + +- ansible.builtin.debug: + msg: "END junos_security_policies_global populate config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..d925b154 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/_reset_config.yaml @@ -0,0 +1,12 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies_global reset config on connection={{ ansible_connection }}" + +- name: Reset the config releavent to security policies global resource + junipernetworks.junos.junos_config: + lines: + - delete security policies + - delete system tracing + +- ansible.builtin.debug: + msg: "END junos_security_policies_global reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/deleted.yaml new file mode 100644 index 00000000..086dda3a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/deleted.yaml @@ -0,0 +1,26 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies_global deleted integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + - ansible.builtin.set_fact: + config: {} + - name: Delete all security policy config from the device + junipernetworks.junos.junos_security_policies_global: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config == result.after }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_security_policies_global deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..e9b49b59 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: + START junos_security_policies_global empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_policies_global: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_policies_global: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_policies_global: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_policies_global: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_policies_global: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..72bd2d81 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,42 @@ + + + + 18.4R1-S2.4 + + + + + + 10k + 3 + + /[A-Z]*/gm + + + all + + + + + + + + + + enable + + + + + + + + 10 + 10 + + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/gathered.yaml new file mode 100644 index 00000000..3bfd2f37 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/gathered.yaml @@ -0,0 +1,25 @@ +--- +- ansible.builtin.debug: + msg: START junos_security_policies_global gathered integration tests on connection={{ ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Gather interfaces facts using gathered state + register: result + junipernetworks.junos.junos_security_policies_global: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['gathered'] }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_security_policies_global gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/merged.yaml new file mode 100644 index 00000000..c03a1e26 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/merged.yaml @@ -0,0 +1,95 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies_global merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_security_policies_global: &merged + config: + default_policy: permit-all + policy_rematch: + enable: true + extensive: true + policy_stats: + enable: true + system_wide: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 3 + match: /[A-Z]*/gm + size: 10k + no_world_readable: true + flag: all + no_remote_trace: true + state: merged + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['before'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['after'] == result['after'] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_security_policies_global: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - name: Update the running configuration with provided configuration + junipernetworks.junos.junos_security_policies_global: + config: + default_policy: deny-all + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + no_world_readable: true + flag: all + no_remote_trace: true + state: merged + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['updated'] == result['after'] }}" + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_security_policies_global merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/overridden.yaml new file mode 100644 index 00000000..fe53769d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/overridden.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies_global overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Override configuration + junipernetworks.junos.junos_security_policies_global: + config: + state: gathered + + - name: Override configuration + junipernetworks.junos.junos_security_policies_global: &overridden + config: + default_policy: deny-all + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + flag: all + state: overridden + register: result + + - ansible.builtin.debug: + msg: "{{ merged['after'] }}" + + - ansible.builtin.debug: + msg: "{{ result['before'] }}" + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result.after }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_security_policies_global: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_security_policies_global overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/parsed.yaml new file mode 100644 index 00000000..115a5d07 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/parsed.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: + START junos_security_policies_global parsed integration tests on connection={{ ansible_connection + }} + +- name: Parse externally provided security_policies_global config to agnostic model + register: result + junipernetworks.junos.junos_security_policies_global: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['parsed'] }}" +- ansible.builtin.debug: + msg: + END junos_security_policies_global parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/rendered.yaml new file mode 100644 index 00000000..82db5881 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/rendered.yaml @@ -0,0 +1,44 @@ +--- +- ansible.builtin.debug: + msg: + START junos_security_policies_global rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: ' enable10103/[A-Z]*/gm10k' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_security_policies_global: + config: + default_policy: permit-all + policy_rematch: + enable: true + extensive: true + policy_stats: + enable: true + system_wide: true + pre_id_default_policy_action: + log: + session_close: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 3 + match: "/[A-Z]*/gm" + no_world_readable: true + size: 10k + no_remote_trace: true + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: + END junos_security_policies_global rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/replaced.yaml new file mode 100644 index 00000000..d475025a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/replaced.yaml @@ -0,0 +1,54 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_policies_global replaced integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Replace configuration + junipernetworks.junos.junos_security_policies_global: &replaced + config: + default_policy: deny-all + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + flag: all + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result.after }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_security_policies_global: *replaced + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_security_policies_global replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/rtt.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/rtt.yml new file mode 100644 index 00000000..83aaecee --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/tests/netconf/rtt.yml @@ -0,0 +1,91 @@ +--- +- ansible.builtin.debug: + msg: + START junos_security_policies_global round trip integration tests on connection={{ + ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_security_policies_global: + config: + default_policy: permit-all + policy_rematch: + enable: true + extensive: true + policy_stats: + enable: true + system_wide: true + pre_id_default_policy_action: + log: + session_close: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 3 + match: "/[A-Z]*/gm" + no_world_readable: true + size: 10k + no_remote_trace: true + state: merged + + - name: Gather security policy facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - security_policies_global + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_security_policies_global: + config: + default_policy: deny-all + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + flag: all + state: replaced + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_security_policies_global: + config: "{{ ansible_facts['network_resources']['security_policies_global'] }}" + state: replaced + + - name: Assert that before dicts are correct + ansible.builtin.assert: + that: + - result.changed == True + - "{{ result['after'] == revert['before'] }}" + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + - result.changed == True + - "{{ base_config['after'] == revert['after'] }}" + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_security_policies_global round trip integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/vars/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/vars/main.yaml new file mode 100644 index 00000000..76ea4dfc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_policies_global/vars/main.yaml @@ -0,0 +1,65 @@ +--- +merged: + before: {} + + after: + default_policy: permit-all + policy_rematch: + enable: true + extensive: true + policy_stats: + enable: true + system_wide: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 3 + match: "/[A-Z]*/gm" + no_world_readable: true + size: 10k + flag: all + no_remote_trace: true + + updated: + default_policy: deny-all + policy_rematch: + enable: true + extensive: true + policy_stats: + enable: true + system_wide: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + no_world_readable: true + flag: all + no_remote_trace: true +replaced: + after: + default_policy: deny-all + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + flag: all diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..aa0bb0a7 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/_initial_config.yaml @@ -0,0 +1,18 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_zones initial config on connection={{ ansible_connection }}" + +- name: Configure basic config relevant to security zones + junipernetworks.junos.junos_config: + lines: + - set security screen ids-option test_screen ip block-frag + - set interfaces ge-0/0/1 unit 0 family inet address 200.0.0.1/24 + - set interfaces ge-0/0/2 unit 0 family inet address 201.0.0.1/24 + - set interfaces ge-0/0/3 unit 0 family inet address 202.0.0.1/24 + - set interfaces ge-0/0/4 unit 0 family inet address 204.0.0.1/24 + - set security advance-policy-based-routing profile test_profile rule test_rule match category Enhanced_Bandwidth + - set routing-instances test_inst instance-type forwarding + - set security advance-policy-based-routing profile test_profile rule test_rule then routing-instance test_inst + +- ansible.builtin.debug: + msg: "END junos_security_zones initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/_populate_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/_populate_config.yaml new file mode 100644 index 00000000..77d36131 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/_populate_config.yaml @@ -0,0 +1,38 @@ +--- +- name: Populate config + junipernetworks.junos.junos_config: + lines: + - set security zones functional-zone management description "test description" + - set security zones functional-zone management screen test_screen + - set security zones functional-zone management interfaces ge-0/0/1 + - set security zones functional-zone management interfaces ge-0/0/2 + - set security zones functional-zone management host-inbound-traffic protocols all + - set security zones functional-zone management host-inbound-traffic protocols bgp except + - set security zones functional-zone management host-inbound-traffic system-services all + - set security zones functional-zone management host-inbound-traffic system-services dhcp except + - set security zones security-zone test_sec_zone1 screen test_screen + - set security zones security-zone test_sec_zone1 interfaces ge-0/0/3 + - set security zones security-zone test_sec_zone1 interfaces ge-0/0/4 + - set security zones security-zone test_sec_zone1 source-identity-log + - set security zones security-zone test_sec_zone1 tcp-rst + - set security zones security-zone test_sec_zone1 enable-reverse-reroute + - set security zones security-zone test_sec_zone1 description "test description" + - set security zones security-zone test_sec_zone1 application-tracking + - set security zones security-zone test_sec_zone1 advance-policy-based-routing-profile test_profile + - set security zones security-zone test_sec_zone1 host-inbound-traffic protocols all + - set security zones security-zone test_sec_zone1 host-inbound-traffic protocols bgp except + - set security zones security-zone test_sec_zone1 host-inbound-traffic system-services all + - set security zones security-zone test_sec_zone1 host-inbound-traffic system-services dhcp except + - set security zones security-zone test_sec_zone1 address-book address test_adr1 10.0.0.0/24 description "test desc" + - set security zones security-zone test_sec_zone1 address-book address test_adr2 dns-name 1.1.1.1 ipv6-only + - set security zones security-zone test_sec_zone1 address-book address test_adr3 range-address 10.2.0.1 to 10.2.0.2 + - set security zones security-zone test_sec_zone1 address-book address test_adr4 wildcard-address 10.3.0.1/24 + - set security zones security-zone test_sec_zone1 address-book address test_adr5 10.1.0.0/24 description "test desc" + - set security zones security-zone test_sec_zone1 address-book address-set test_adrset1 address test_adr1 + - set security zones security-zone test_sec_zone1 address-book address-set test_adrset1 address test_adr2 + - set security zones security-zone test_sec_zone1 address-book address-set test_adrset2 address test_adr3 + - set security zones security-zone test_sec_zone1 address-book address-set test_adrset2 address test_adr4 + - set security zones security-zone test_sec_zone1 address-book address-set test_adrset3 address test_adr5 + - set security zones security-zone test_sec_zone1 address-book address-set test_adrset3 address-set test_adrset1 + - set security zones security-zone test_sec_zone1 address-book address-set test_adrset3 address-set test_adrset2 + - set security zones security-zone test_sec_zone1 address-book address-set test_adrset3 description "test description" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..309e0d57 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/_reset_config.yaml @@ -0,0 +1,16 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_zones reset config on connection={{ ansible_connection }}" + +- name: Reset the config releavent to security zones resource + junipernetworks.junos.junos_config: + lines: + - delete security + - delete routing-instances + - delete interfaces ge-0/0/1 + - delete interfaces ge-0/0/2 + - delete interfaces ge-0/0/3 + - delete interfaces ge-0/0/4 + +- ansible.builtin.debug: + msg: "END junos_security_zones reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/deleted.yaml new file mode 100644 index 00000000..1fc72a49 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/deleted.yaml @@ -0,0 +1,26 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_zones deleted integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + - ansible.builtin.set_fact: + config: {} + - name: Delete all security zones config from the device + junipernetworks.junos.junos_security_zones: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config == result.after }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_security_zones deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..b2deccd4 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: + START junos_security_zones empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_zones: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_zones: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_zones: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_zones: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_security_zones: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..4c346a09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,137 @@ + + + + 18.4R1-S2.4 + + + + + test description + + + all + + + bgp + + + + all + + + dhcp + + + + + ge-0/0/1.0 + + + ge-0/0/2.0 + + test_screen + + + + test_sec_zone1 + +
+ test_adr1 + 10.0.0.0/24 + test desc +
+
+ test_adr2 + + 1.1.1.1 + + +
+
+ test_adr3 + + 10.2.0.1 + + 10.2.0.2 + + +
+
+ test_adr4 + + 10.3.0.1/24 + +
+
+ test_adr5 + 10.1.0.0/24 + test desc +
+ + test_adrset1 +
+ test_adr1 +
+
+ test_adr2 +
+
+ + test_adrset2 +
+ test_adr3 +
+
+ test_adr4 +
+
+ + test_adrset3 +
+ test_adr5 +
+ + test_adrset1 + + + test_adrset2 + + test description +
+
+ + test_profile + + + test description + + + + all + + + bgp + + + + all + + + dhcp + + + + + ge-0/0/3.0 + + + ge-0/0/4.0 + + test_screen + + +
+
+
+
+
diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/gathered.yaml new file mode 100644 index 00000000..5c389667 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/gathered.yaml @@ -0,0 +1,23 @@ +--- +- ansible.builtin.debug: + msg: START junos_security_zones gathered integration tests on connection={{ ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Gather interfaces facts using gathered state + register: result + junipernetworks.junos.junos_security_zones: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['gathered'] }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: END junos_security_zones gathered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/merged.yaml new file mode 100644 index 00000000..d9099f67 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/merged.yaml @@ -0,0 +1,143 @@ +--- +- ansible.builtin.debug: + msg: "START junos_security_zones merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_security_zones: &merged + config: + functional_zone_management: + description: test description + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true + state: merged + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['before'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['after'] == result['after'] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_security_zones: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - name: Update the running configuration with providede configuration + junipernetworks.junos.junos_security_zones: + config: + functional_zone_management: + description: test description 2 + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + - name: bfd + except: true + system_services: + - except: true + name: dhcp + - except: true + name: dhcpv6 + - name: all + zones: + - name: test_sec_zone2 + source_identity_log: true + tcp_rst: true + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['updated'] == result['after'] }}" + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_security_zones merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/overridden.yaml new file mode 100644 index 00000000..375d0fd5 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/overridden.yaml @@ -0,0 +1,104 @@ +--- +- ansible.builtin.debug: + msg: >- + START junos_security_zones overridden integration tests on connection={{ + ansible_connection }} +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + - name: Override configuration + junipernetworks.junos.junos_security_zones: &ref_0 + config: + functional_zone_management: + description: test description 2 + host_inbound_traffic: + protocols: + - name: all + system_services: + - name: all + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true + state: overridden + register: result + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result.after }}" + - name: >- + Replaced the provided configuration with the existing running + configuration (IDEMPOTENT) + junipernetworks.junos.junos_security_zones: *ref_0 + register: result + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml +- ansible.builtin.debug: + msg: >- + END junos_security_zones overridden integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/parsed.yaml new file mode 100644 index 00000000..63e8dc39 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/parsed.yaml @@ -0,0 +1,18 @@ +--- +- ansible.builtin.debug: + msg: >- + START junos_security_zones parsed integration tests on connection={{ + ansible_connection }} +- name: Parse externally provided security_zones config to agnostic model + register: result + junipernetworks.junos.junos_security_zones: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['parsed'] }}" +- ansible.builtin.debug: + msg: >- + END junos_security_zones parsed integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/rendered.yaml new file mode 100644 index 00000000..c144a48f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/rendered.yaml @@ -0,0 +1,90 @@ +--- +- ansible.builtin.debug: + msg: >- + START junos_security_zones rendered integration tests on connection={{ + ansible_connection }} +- ansible.builtin.set_fact: + expected_rendered_output: 'test descriptionallbgpalldhcpge-0/0/1.0ge-0/0/2.0test_screentest_sec_zone1test_adr110.0.0.0/24test desctest_adr21.1.1.1test_adr310.2.0.110.2.0.2test_adr410.3.0.1/24test_adr510.1.0.0/24test desctest_adrset1test_adr1test_adr2test_adrset2test_adr3test_adr4test_adrset3test_adr5test_adrset1test_adrset2test descriptiontest_profiletest descriptionallbgpalldhcpge-0/0/3.0ge-0/0/4.0test_screen' +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_security_zones: + config: + functional_zone_management: + description: test description + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true + state: rendered +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" +- ansible.builtin.debug: + msg: >- + END junos_security_zones rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/replaced.yaml new file mode 100644 index 00000000..16846357 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/replaced.yaml @@ -0,0 +1,104 @@ +--- +- ansible.builtin.debug: + msg: >- + START junos_security_zones replaced integration tests on connection={{ + ansible_connection }} +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + - name: Override configuration + junipernetworks.junos.junos_security_zones: &ref_0 + config: + functional_zone_management: + description: test description 2 + host_inbound_traffic: + protocols: + - name: all + system_services: + - name: all + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true + state: replaced + register: result + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result.after }}" + - name: >- + Replaced the provided configuration with the existing running + configuration (IDEMPOTENT) + junipernetworks.junos.junos_security_zones: *ref_0 + register: result + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml +- ansible.builtin.debug: + msg: >- + END junos_security_zones replaced integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/rtt.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/rtt.yml new file mode 100644 index 00000000..30ba201b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/tests/netconf/rtt.yml @@ -0,0 +1,184 @@ +--- +- ansible.builtin.debug: + msg: >- + START junos_security_zones round trip integration tests on connection={{ + ansible_connection }} +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_security_zones: + config: + functional_zone_management: + description: test description + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true + state: merged + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - security_zones + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_security_zones: + config: + functional_zone_management: + description: test description 2 + host_inbound_traffic: + protocols: + - name: all + system_services: + - name: all + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true + state: replaced + - name: Assert that changes were applied + ansible.builtin.assert: + that: "result['changed'] == true" + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_security_zones: + config: "{{ ansible_facts['network_resources']['security_zones'] }}" + state: replaced + - name: Assert that before dicts are correct + ansible.builtin.assert: + that: + - result.changed == True + - "{{ result['after'] == revert['before'] }}" + - name: Assert that config was reverted + ansible.builtin.assert: + that: + - result.changed == True + - "{{ base_config['after'] == revert['after'] }}" + always: + - ansible.builtin.include_tasks: _reset_config.yaml +- ansible.builtin.debug: + msg: >- + END junos_security_zones round trip integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/vars/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/vars/main.yaml new file mode 100644 index 00000000..418236a9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_security_zones/vars/main.yaml @@ -0,0 +1,220 @@ +--- +merged: + before: {} + after: + functional_zone_management: + description: test description + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true + updated: + functional_zone_management: + description: test description 2 + host_inbound_traffic: + protocols: + - name: all + - name: bgp + except: true + - name: bfd + except: true + system_services: + - name: all + - except: true + name: dhcp + - except: true + name: dhcpv6 + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true + - name: test_sec_zone2 + source_identity_log: true + tcp_rst: true +replaced: + after: + functional_zone_management: + description: test description 2 + host_inbound_traffic: + protocols: + - name: all + system_services: + - name: all + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 + screen: test_screen + zones: + - address_book: + address_sets: + - addresses: + - test_adr1 + - test_adr2 + name: test_adrset1 + - addresses: + - test_adr3 + - test_adr4 + name: test_adrset2 + - address_sets: + - test_adrset1 + - test_adrset2 + addresses: + - test_adr5 + description: test description + name: test_adrset3 + addresses: + - description: test desc + ip_prefix: 10.0.0.0/24 + name: test_adr1 + - dns_name: + ipv6_only: true + name: 1.1.1.1 + name: test_adr2 + - name: test_adr3 + range_address: + from: 10.2.0.1 + to: 10.2.0.2 + - name: test_adr4 + wildcard_address: 10.3.0.1/24 + - description: test desc + ip_prefix: 10.1.0.0/24 + name: test_adr5 + advance_policy_based_routing_profile: test_profile + application_tracking: true + description: test description + enable_reverse_reroute: true + host_inbound_traffic: + protocols: + - name: all + - except: true + name: bgp + system_services: + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/3.0 + - ge-0/0/4.0 + name: test_sec_zone1 + screen: test_screen + source_identity_log: true + tcp_rst: true diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/defaults/main.yaml new file mode 100644 index 00000000..9ef5ba51 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tasks/cli.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tasks/cli.yaml new file mode 100644 index 00000000..d3ff7cec --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tasks/cli.yaml @@ -0,0 +1,28 @@ +--- +- name: Collect cli test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + +- name: Run test cases with single_user_mode (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ role_path }}/tests/cli/caching.yaml" + vars: + ansible_connection: ansible.netcommon.network_cli + ansible_network_single_user_mode: "True" + test_connection: "{{ cli }}" + tags: + - network_cli diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tasks/main.yaml new file mode 100644 index 00000000..08ec42d9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tasks/main.yaml @@ -0,0 +1,8 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: cli.yaml + tags: ["network_cli"] + +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: ["netconf"] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tasks/netconf.yaml new file mode 100644 index 00000000..ab7d6689 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tasks/netconf.yaml @@ -0,0 +1,19 @@ +--- +- name: Collect netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/cli/caching.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/cli/caching.yaml new file mode 100644 index 00000000..86d00503 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/cli/caching.yaml @@ -0,0 +1,52 @@ +--- +- block: + - ansible.builtin.debug: msg="START connection={{ ansible_connection }} cli/caching.yaml" + + - name: Remove description from interface + ignore_errors: true + junipernetworks.junos.junos_command: &rem + commands: + - configure + - delete interfaces ge-0/0/1 description + - commit + - exit + + - name: Fetch configuration + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show configuration interfaces ge-0/0/1 + register: result + + - ansible.builtin.assert: + that: + - '"description test-1;" not in result.stdout_lines' + + - name: Fetch configuration again (from cache) + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show configuration interfaces ge-0/0/1 + + - name: Configure description on interface + ignore_errors: true + junipernetworks.junos.junos_command: + commands: + - configure + - set interfaces ge-0/0/1 description test-1 + - commit + - exit + + - name: Fetch configuration from appliance + ignore_errors: true + junipernetworks.junos.junos_command: + commands: show configuration interfaces ge-0/0/1 + register: result + + - ansible.builtin.assert: + that: + - '"description test-1;" in result.stdout_lines[0]' + + always: + - name: Remove description from interface + ignore_errors: true + junipernetworks.junos.junos_command: *rem + when: ansible_connection == "ansible.netcommon.network_cli" and ansible_network_single_user_mode|d(False) diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/cli/reboot.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/cli/reboot.yaml new file mode 100644 index 00000000..2aa32655 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/cli/reboot.yaml @@ -0,0 +1,22 @@ +--- +- ansible.builtin.debug: + msg: START cli/cli_reboot.yaml on connection={{ ansible_connection }} +- block: + - ansible.netcommon.cli_command: + command: request system reboot + prompt: + - Reboot the system? + answer: + - y + + tags: + - reboot + - wait_for_connection: + delay: 60 + sleep: 40 + + - ansible.netcommon.cli_command: + command: show version + when: ansible_connection == 'ansible.netcommon.network_cli' + +- ansible.builtin.debug: msg="END cli/reboot.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/netconf/common_utils.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/netconf/common_utils.yaml new file mode 100644 index 00000000..015c05ad --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/netconf/common_utils.yaml @@ -0,0 +1,24 @@ +--- +# junos interface -> remove_default_spec() conditional() +- ansible.builtin.debug: msg="START junos_interface netconf/common_utils.yaml on connection={{ ansible_connection }}" + +- name: get facts + junos_facts: + register: result + +- name: Define interface name for vSRX + ansible.builtin.set_fact: + intf_name: pp0 + when: result['ansible_facts']['ansible_net_model'] is search("vSRX*") + +- name: Define interface name for vsrx + ansible.builtin.set_fact: + intf_name: pp0 + when: result['ansible_facts']['ansible_net_model'] is search("vsrx") + +- name: Define interface name for vQFX + ansible.builtin.set_fact: + intf_name: gr-0/0/0 + when: result['ansible_facts']['ansible_net_model'] is search("vqfx*") + +- ansible.builtin.debug: msg="END junos_interface netconf/common_utils.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/netconf/module_utils_junos.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/netconf/module_utils_junos.yaml new file mode 100644 index 00000000..b5549a21 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_smoke/tests/netconf/module_utils_junos.yaml @@ -0,0 +1,53 @@ +--- +- ansible.builtin.debug: msg="START netconf/module_utils_junos.yaml on connection={{ ansible_connection }}" + +# hit get_capabilities() + +- name: get output for single command + junos_command: + commands: ["show version"] + format: json + register: result + +- ansible.builtin.assert: + that: + - "result.changed == false" + - "result.stdout is defined" + - "result.stdout_lines is defined" + +# hit commit_configuration() +- name: setup - remove login banner + junos_banner: + banner: login + state: absent + +- name: Create login banner + junos_banner: + banner: login + text: this is my login banner + state: present + register: result + +- name: Get running configuration + junos_rpc: + rpc: get-configuration + register: config + +- ansible.builtin.assert: + that: + - "result.changed == true" + - "'this is my login banner' in config.xml" + +# hit discard_changes() +- name: check mode + junos_banner: + banner: login + text: this is not the banner you're looking for + state: present + register: result + check_mode: true + +- ansible.builtin.assert: + that: + - "result.changed == true" + - "result.failed == false" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..ab69bef6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/_initial_config.yaml @@ -0,0 +1,14 @@ +--- +- ansible.builtin.debug: + msg: "START junos_snmp_server initial config on connection={{ ansible_connection }}" + +- name: Configure basic config relevant to ntp global + junipernetworks.junos.junos_config: + lines: + - set routing-instances clv1 instance-type virtual-router + - set routing-instances clv1 description "clv1" + - set routing-instances clv2 instance-type virtual-router + - set routing-instances clv2 description "clv2" + +- ansible.builtin.debug: + msg: "END junos_snmp_server initial config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/_populate_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/_populate_config.yaml new file mode 100644 index 00000000..9c003823 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/_populate_config.yaml @@ -0,0 +1,23 @@ +--- +- name: Populate config + junipernetworks.junos.junos_config: + lines: + - "set snmp arp" + - "set snmp arp host-name-resolution" + - "set snmp client-list cl1" + - "set snmp client-list cl2" + - "set snmp client-list cl1 192.16.1.0/24" + - "set snmp client-list cl1 192.16.2.0/24" + - "set snmp client-list cl1 11.11.11.11 restrict" + - "set snmp client-list cl2 192.16.4.0/24" + - "set snmp community comm1" + - "set snmp community comm2" + - "set snmp community comm1 authorization read-write" + - "set snmp community comm1 client-list-name cl1" + - "set snmp community comm1 clients 24.0.0.0/32 restrict" + - "set snmp community comm1 clients 30.0.0.0/32 restrict" + - 'set routing-instances clv1 description "clv1"' + - 'set routing-instances clv2 description "clv2"' + - "set snmp routing-instance-access" + - "set snmp routing-instance-access access-list clv1" + - "set snmp routing-instance-access access-list clv2" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/_reset_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/_reset_config.yaml new file mode 100644 index 00000000..07575c60 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/_reset_config.yaml @@ -0,0 +1,12 @@ +--- +- ansible.builtin.debug: + msg: "START junos_snmp_server reset config on connection={{ ansible_connection }}" + +- name: Reset the config releavent to snmp resource + junipernetworks.junos.junos_config: + lines: + - delete snmp + - delete routing-instances + +- ansible.builtin.debug: + msg: "END junos_snmp_server reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/backups/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/backups/empty_config.yaml new file mode 100644 index 00000000..c2d74d60 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/backups/empty_config.yaml @@ -0,0 +1,49 @@ +--- +- ansible.builtin.debug: + msg: START junos_bgp_global empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_bgp_global: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/deleted.yaml new file mode 100644 index 00000000..a3651cc0 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/deleted.yaml @@ -0,0 +1,26 @@ +--- +- ansible.builtin.debug: + msg: "START junos_snmp_server deleted integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + - ansible.builtin.set_fact: + config: {} + - name: Delete all snmp_server config from the device + junipernetworks.junos.junos_snmp_server: + state: deleted + register: result + + - name: Assert changed + ansible.builtin.assert: + that: + - result.changed == True + - "{{ config == result.after }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_snmp_server deleted integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..472ad0e3 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/empty_config.yaml @@ -0,0 +1,60 @@ +--- +- ansible.builtin.debug: + msg: START junos_snmp_server empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_snmp_server: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_snmp_server: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_snmp_server: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_snmp_server: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_snmp_server: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..9c1a5a96 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,62 @@ + + + + 18.4R1-S2.4 + + + cl1 + + 192.16.1.0/24 + + + 192.16.2.0/24 + + + 11.11.11.11/32 + + + + + cl2 + + 192.16.4.0/24 + + + + + clv1 + + + clv2 + + + + + + + + + fxp0 + + 0 + + + + + + + + + + + + rt1 + rt1 + + + rt2 + rt2 + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/gathered.yaml new file mode 100644 index 00000000..819e63cc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/gathered.yaml @@ -0,0 +1,25 @@ +--- +- ansible.builtin.debug: + msg: START junos_snmp_server gathered integration tests on connection={{ ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Gather interfaces facts using gathered state + register: result + junipernetworks.junos.junos_snmp_server: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ gathered['facts'] == result['gathered'] }}" + + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_snmp_server gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/merged.yaml new file mode 100644 index 00000000..8c0d3ffe --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/merged.yaml @@ -0,0 +1,88 @@ +--- +- ansible.builtin.debug: + msg: "START junos_snmp_server merged integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Merge the provided configuration with the exisiting running configuration + junipernetworks.junos.junos_snmp_server: &merged + config: + arp: + set: true + host_name_resolution: true + client_lists: + - name: cl1 + addresses: + - address: "192.16.1.0/24" + - address: "192.16.2.0/24" + - address: "11.11.11.11" + restrict: true + - name: cl2 + addresses: + - address: "192.16.4.0/24" + routing_instance_access: + set: true + access_lists: + - "clv1" + - "clv2" + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['before'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['after'] == result['after'] }}" + + - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_snmp_server: *merged + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + - name: Update the running configuration with providede configuration + junipernetworks.junos.junos_snmp_server: + config: + communities: + - name: "comm1" + clients: + - address: "24.0.0.0/32" + restrict: true + - address: "30.0.0.0/32" + restrict: true + routing_instances: + - name: "clv1" + clients: + - address: "13.13.13.13/24" + restrict: true + - address: "24.0.0.0/32" + - address: "30.0.0.0/32" + - name: "clv2" + clients: + - address: "15.15.15.15/24" + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after'] == result['before'] }}" + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - result.changed == True + - "{{ merged['updated'] == result['after'] }}" + + tags: merged + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_snmp_server merged integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/overridden.yaml new file mode 100644 index 00000000..679d9dd8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/overridden.yaml @@ -0,0 +1,57 @@ +--- +- ansible.builtin.debug: + msg: "START junos_snmp_server overridden integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Override configuration + junipernetworks.junos.junos_snmp_server: &overridden + config: + contact: "ansiblesupport11@redhat.com" + customization: + ether_stats_ifd_only: true + description: "Local SNMP Server" + engine_id: + use_mac_address: true + filter_duplicates: true + filter_interfaces: + all_internal_interfaces: true + interfaces: + - "eth1" + - "eth2" + set: true + views: + - name: "all" + oids: + - oid: ".1" + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ gathered['facts'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result['after'] }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_snmp_server: *overridden + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: overridden + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_snmp_server overridden integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/parsed.yaml new file mode 100644 index 00000000..209a7acf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/parsed.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: + START junos_snmp_server parsed integration tests on connection={{ ansible_connection + }} + +- name: Parse externally provided snmp_server config to agnostic model + register: result + junipernetworks.junos.junos_snmp_server: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['parsed'] }}" +- ansible.builtin.debug: + msg: + END junos_snmp_server parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/rendered.yaml new file mode 100644 index 00000000..abd27545 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/rendered.yaml @@ -0,0 +1,30 @@ +--- +- ansible.builtin.debug: + msg: START junos_snmp_server rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: 'clv1clv2' + +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_snmp_server: + config: + arp: + set: true + host_name_resolution: true + routing_instance_access: + set: true + access_lists: + - "clv1" + - "clv2" + state: rendered + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + +- ansible.builtin.debug: + msg: END junos_snmp_server rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/replaced.yaml new file mode 100644 index 00000000..5bdbf72f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/replaced.yaml @@ -0,0 +1,57 @@ +--- +- ansible.builtin.debug: + msg: "START junos_snmp_server replaced integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Override configuration + junipernetworks.junos.junos_snmp_server: &replaced + config: + contact: "ansiblesupport11@redhat.com" + customization: + ether_stats_ifd_only: true + description: "Local SNMP Server" + engine_id: + use_mac_address: true + filter_duplicates: true + filter_interfaces: + all_internal_interfaces: true + interfaces: + - "eth1" + - "eth2" + set: true + views: + - name: "all" + oids: + - oid: ".1" + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ gathered['facts'] == result['before'] }}" + + - name: Assert configuration + ansible.builtin.assert: + that: + - result.changed == True + - "{{ replaced['after'] == result['after'] }}" + + - name: Replaced the provided configuration with the existing running configuration (IDEMPOTENT) + junipernetworks.junos.junos_snmp_server: *replaced + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result.changed == False + + tags: replaced + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: "END junos_snmp_server replaced integration tests on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/rtt.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/rtt.yaml new file mode 100644 index 00000000..581b874f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/tests/netconf/rtt.yaml @@ -0,0 +1,86 @@ +--- +- ansible.builtin.debug: + msg: START junos_snmp_server round trip integration tests on connection={{ + ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _reset_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_snmp_server: + config: + arp: + set: true + host_name_resolution: true + client_lists: + - name: cl1 + addresses: + - address: "192.16.1.0/24" + - address: "192.16.2.0/24" + - address: "11.11.11.11" + restrict: true + - name: cl2 + addresses: + - address: "192.16.4.0/24" + routing_instance_access: + set: true + access_lists: + - "clv1" + - "clv2" + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - snmp_server + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_snmp_server: + config: + contact: "ansiblesupport11@redhat.com" + customization: + ether_stats_ifd_only: true + description: "Local SNMP Server" + engine_id: + use_mac_address: true + filter_duplicates: true + filter_interfaces: + set: true + all_internal_interfaces: true + interfaces: + - "eth1" + - "eth2" + state: replaced + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_snmp_server: + config: "{{ ansible_facts['network_resources']['snmp_server'] }}" + state: replaced + + - name: Assert that before dicts are correct + ansible.builtin.assert: + that: + - result.changed == True + - "{{ result['after'] == revert['before'] }}" + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + - result.changed == True + - "{{ base_config['after'] == revert['after'] }}" + always: + - ansible.builtin.include_tasks: _reset_config.yaml + +- ansible.builtin.debug: + msg: + END junos_snmp_server round trip integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/vars/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/vars/main.yaml new file mode 100644 index 00000000..86a29df2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_snmp_server/vars/main.yaml @@ -0,0 +1,101 @@ +--- +merged: + before: {} + after: + arp: + host_name_resolution: true + client_lists: + - addresses: + - address: "192.16.1.0/24" + - address: "192.16.2.0/24" + - address: "11.11.11.11/32" + restrict: true + name: "cl1" + - addresses: + - address: "192.16.4.0/24" + name: "cl2" + routing_instance_access: + access_lists: + - "clv1" + - "clv2" + + updated: + arp: + host_name_resolution: true + client_lists: + - addresses: + - address: "192.16.1.0/24" + - address: "192.16.2.0/24" + - address: "11.11.11.11/32" + restrict: true + name: "cl1" + - addresses: + - address: "192.16.4.0/24" + name: "cl2" + communities: + - clients: + - address: "24.0.0.0/32" + restrict: true + - address: "30.0.0.0/32" + restrict: true + name: "comm1" + routing_instances: + - clients: + - address: "13.13.13.13/24" + restrict: true + - address: "24.0.0.0/32" + - address: "30.0.0.0/32" + name: "clv1" + - clients: + - address: "15.15.15.15/24" + name: "clv2" + routing_instance_access: + access_lists: + - "clv1" + - "clv2" +gathered: + facts: + arp: + host_name_resolution: true + client_lists: + - addresses: + - address: "192.16.1.0/24" + - address: "192.16.2.0/24" + - address: "11.11.11.11/32" + restrict: true + name: "cl1" + - addresses: + - address: "192.16.4.0/24" + name: "cl2" + communities: + - authorization: "read-write" + clients: + - address: "24.0.0.0/32" + restrict: true + - address: "30.0.0.0/32" + restrict: true + name: "comm1" + - name: "comm2" + routing_instance_access: + access_lists: + - "clv1" + - "clv2" + +replaced: + after: + contact: "ansiblesupport11@redhat.com" + customization: + ether_stats_ifd_only: true + description: "Local SNMP Server" + engine_id: + use_mac_address: true + filter_duplicates: true + filter_interfaces: + all_internal_interfaces: true + interfaces: + - "eth1" + - "eth2" + views: + - name: "all" + oids: + - oid: ".1" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/meta/main.yaml new file mode 100644 index 00000000..7f867d73 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/meta/main.yaml @@ -0,0 +1,2 @@ +--- +dependencies: diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/_base_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/_base_config.yaml new file mode 100644 index 00000000..c1acaf7a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/_base_config.yaml @@ -0,0 +1,25 @@ +--- +- ansible.builtin.debug: + msg: + Start junos_static_routes base config ansible_connection={{ ansible_connection + }} + +- name: Configure base static_routes + junipernetworks.junos.junos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.0.0/24 + next_hop: + - forward_router_address: 192.168.0.1 + - afi: ipv6 + routes: + - dest: 2001:db8::5/128 + next_hop: + - forward_router_address: 2001:db8:0:1:2a0:a502:0:19da + +- ansible.builtin.debug: + msg: + End junos_static_routes base config ansible_connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/_remove_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/_remove_config.yaml new file mode 100644 index 00000000..f8e90759 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/_remove_config.yaml @@ -0,0 +1,18 @@ +--- +- ansible.builtin.debug: + msg: + Start junos_static_routes teardown ansible_connection={{ ansible_connection + }} + +- name: Remove static route config + junipernetworks.junos.junos_static_routes: + config: + - address_families: + - afi: ipv4 + - afi: ipv6 + state: deleted + +- ansible.builtin.debug: + msg: + End junos_static_routes teardown ansible_connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/deleted.yaml new file mode 100644 index 00000000..3c701d9c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/deleted.yaml @@ -0,0 +1,43 @@ +--- +- ansible.builtin.debug: + msg: + START junos_static_routes deleted integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- block: + - name: Delete the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_static_routes: &id001 + config: + - address_families: + - afi: ipv4 + - afi: ipv6 + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - not result.after + debugger: on_failed + + - name: + Delete the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_static_routes: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_static_routes deleted integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/merged.yaml new file mode 100644 index 00000000..aeaa6d05 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/merged.yaml @@ -0,0 +1,78 @@ +--- +- ansible.builtin.debug: + msg: + START junos_static_routes merged integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.set_fact: + expected_merged_output: + - address_families: + - afi: ipv6 + routes: + - dest: 2001:db8::5/128 + next_hop: + - forward_router_address: 2001:db8:0:1:2a0:a502:0:19da + - dest: ::/0 + next_hop: + - forward_router_address: 2001:db8:0:1:2a0:a502:0:19da + - afi: ipv4 + routes: + - dest: 192.168.0.0/24 + next_hop: + - forward_router_address: 192.168.0.1 + - dest: 192.168.1.0/24 + metric: 2 + next_hop: + - forward_router_address: 192.168.1.1 + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_static_routes: &id001 + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.0.0/24 + next_hop: + - forward_router_address: 192.168.0.1 + - dest: 192.168.1.0/24 + next_hop: + - forward_router_address: 192.168.1.1 + metric: 2 + - afi: ipv6 + routes: + - dest: 2001:db8::5/128 + next_hop: + - forward_router_address: 2001:db8:0:1:2a0:a502:0:19da + - dest: ::/0 + next_hop: + - forward_router_address: 2001:db8:0:1:2a0:a502:0:19da + state: merged + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_merged_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + debugger: on_failed + + - name: + Merge the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_static_routes: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_static_routes merged integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/overridden.yaml new file mode 100644 index 00000000..a24b890a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/overridden.yaml @@ -0,0 +1,57 @@ +--- +- ansible.builtin.debug: + msg: START junos_static_routes overridden integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_overridden_output: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.20.0/24 + next_hop: + - forward_router_address: 192.168.20.1 + metric: 10 + +- block: + - name: Override the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_static_routes: &id001 + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.20.0/24 + next_hop: + - forward_router_address: 192.168.20.1 + metric: 10 + state: overridden + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_overridden_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + debugger: on_failed + + - name: + Override the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_static_routes: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_static_routes overridden integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/replaced.yaml new file mode 100644 index 00000000..b0aa7b8c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_static_routes/tests/netconf/replaced.yaml @@ -0,0 +1,60 @@ +--- +- ansible.builtin.debug: + msg: START junos_static_routes overridden integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_overridden_output: + - address_families: + - afi: ipv6 + routes: + - dest: 2001:db8::5/128 + next_hop: + - forward_router_address: 2001:db8:0:1:2a0:a502:0:19da + - afi: ipv4 + routes: + - dest: 192.168.0.0/24 + next_hop: + - forward_router_address: 192.168.20.1 + +- block: + - name: Replace the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_static_routes: &id001 + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.168.0.0/24 + next_hop: + - forward_router_address: 192.168.20.1 + state: replaced + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_overridden_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + debugger: on_failed + + - name: + Override the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_static_routes: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_static_routes overridden integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/aliases b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/aliases new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/defaults/main.yaml new file mode 100644 index 00000000..9ef5ba51 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/tasks/main.yaml new file mode 100644 index 00000000..ac951c8f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/tasks/main.yaml @@ -0,0 +1,3 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/tasks/netconf.yaml new file mode 100644 index 00000000..6071adcf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/tasks/netconf.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + register: test_cases + connection: local + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/tests/netconf/basic.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/tests/netconf/basic.yaml new file mode 100644 index 00000000..ef24717f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_system/tests/netconf/basic.yaml @@ -0,0 +1,370 @@ +--- +- ansible.builtin.debug: + msg="START junos_system netconf/basic.yaml on connection={{ ansible_connection + }}" + +- name: setup - remove hostname + junipernetworks.junos.junos_system: + hostname: vsrx01 + state: absent + +- name: Set hostname + register: result + junipernetworks.junos.junos_system: + hostname: vsrx01 + state: present + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'vsrx01' in config.xml" + +- name: Set hostname (idempotent) + register: result + junipernetworks.junos.junos_system: + hostname: vsrx01 + state: present + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Deactivate hostname configuration + register: result + junipernetworks.junos.junos_system: + hostname: vsrx01 + state: present + active: false + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - ''''' in config.xml' + +- name: Activate hostname configuration + register: result + junipernetworks.junos.junos_system: + hostname: vsrx01 + state: present + active: true + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'vsrx01' in config.xml" + +- name: Delete hostname configuration + register: result + junipernetworks.junos.junos_system: + hostname: vsrx01 + state: absent + +- ansible.builtin.assert: + that: + - result.changed == true + - "'vsrx01' in config.xml" + +- name: Teardown - set hostname + junipernetworks.junos.junos_system: + hostname: vsrx01 + state: present + +- name: setup - remove domain name + junipernetworks.junos.junos_system: + domain_name: ansible.com + state: absent + +- name: Set domain name + register: result + junipernetworks.junos.junos_system: + domain_name: ansible.com + state: present + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ansible.com' in config.xml" + +- name: Set domain name (idempotent) + register: result + junipernetworks.junos.junos_system: + domain_name: ansible.com + state: present + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Deactivate domain name + register: result + junipernetworks.junos.junos_system: + domain_name: ansible.com + state: present + active: false + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - ''''' in config.xml' + +- name: Activate domain name + register: result + junipernetworks.junos.junos_system: + domain_name: ansible.com + state: present + active: true + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ansible.com' in config.xml" + +- name: Delete domain name + register: result + junipernetworks.junos.junos_system: + domain_name: ansible.com + state: absent + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ansible.com' not in config.xml" + +- name: Teardown - set domain name + junipernetworks.junos.junos_system: + domain_name: ansible.com + state: present + +- name: Setup - delete domain search + register: result + junipernetworks.junos.junos_system: + domain_search: + - test.com + - sample.com + state: absent + +- name: Set domain search + register: result + junipernetworks.junos.junos_system: + domain_search: + - test.com + - sample.com + state: present + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'test.com' in config.xml" + - "'sample.com' in config.xml" + +- name: Set domain search (idempotency) + register: result + junipernetworks.junos.junos_system: + domain_search: + - test.com + - sample.com + state: present + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Deactivate domain search + register: result + junipernetworks.junos.junos_system: + domain_search: + - test.com + - sample.com + state: present + active: false + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - '''test.com'' in config.xml' + - '''sample.com'' in config.xml' + +- name: Activate domain search + register: result + junipernetworks.junos.junos_system: + domain_search: + - test.com + - sample.com + state: present + active: true + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'test.com' in config.xml" + - "'sample.com' in config.xml" + +- name: Delete domain search + register: result + junipernetworks.junos.junos_system: + domain_search: + - test.com + - sample.com + state: absent + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'test.com' not in config.xml" + - "'sample.com' not in config.xml" + +- name: Setup - delete name servers + register: result + junipernetworks.junos.junos_system: + name_servers: + - 8.8.8.8 + - 8.8.4.4 + state: absent + +- name: Set name servers + register: result + junipernetworks.junos.junos_system: + name_servers: + - 8.8.8.8 + - 8.8.4.4 + state: present + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'8.8.8.8' in config.xml" + - "'8.8.4.4' in config.xml" + +- name: Set name servers (idempotent) + register: result + junipernetworks.junos.junos_system: + name_servers: + - 8.8.8.8 + - 8.8.4.4 + state: present + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Deactivate name servers + register: result + junipernetworks.junos.junos_system: + name_servers: + - 8.8.8.8 + - 8.8.4.4 + state: present + active: false + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - ''''' in config.xml' + +- name: Activate name servers + register: result + junipernetworks.junos.junos_system: + name_servers: + - 8.8.8.8 + - 8.8.4.4 + state: present + active: true + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'8.8.8.8' in config.xml" + - "'8.8.4.4' in config.xml" + +- name: Delete name servers + register: result + junipernetworks.junos.junos_system: + name_servers: + - 8.8.8.8 + - 8.8.4.4 + state: absent + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'8.8.8.8' not in config.xml" + - "'8.8.4.4' not in config.xml" + +- ansible.builtin.debug: + msg="END junos_system netconf/basic.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/defaults/main.yaml new file mode 100644 index 00000000..822f2213 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_cases: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/tasks/main.yaml new file mode 100644 index 00000000..ac951c8f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/tasks/main.yaml @@ -0,0 +1,3 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/tasks/netconf.yaml new file mode 100644 index 00000000..3fa0553b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/tasks/netconf.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + register: test_cases + connection: local + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/tests/netconf/basic.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/tests/netconf/basic.yaml new file mode 100644 index 00000000..119519a6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_user/tests/netconf/basic.yaml @@ -0,0 +1,204 @@ +--- +- ansible.builtin.debug: + msg="START junos_user netconf/basic.yaml on connection={{ ansible_connection + }}" + +- name: setup - remove user + junipernetworks.junos.junos_user: + name: test_user + state: absent + +- name: Create user + register: result + junipernetworks.junos.junos_user: + name: test_user + state: present + full_name: test_user + role: operator + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'test_user' in config.xml" + - "'test_user' in config.xml" + - "'operator' in config.xml" + +- name: Create user again (idempotent) + register: result + junipernetworks.junos.junos_user: + name: test_user + state: present + full_name: test_user + role: operator + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Deactivate user + register: result + junipernetworks.junos.junos_user: + name: test_user + state: present + full_name: test_user + role: operator + active: false + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - ''''' in config.xml' + - "'test_user' in config.xml" + +- name: Activate user + register: result + junipernetworks.junos.junos_user: + name: test_user + state: present + full_name: test_user + role: operator + active: true + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'test_user' in config.xml" + - "'test_user' in config.xml" + - "'operator' in config.xml" + +- name: Delete user + register: result + junipernetworks.junos.junos_user: + name: test_user + state: absent + full_name: test_user + role: operator + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'test_user' not in config.xml" + - "'test_user' not in config.xml" + +- name: Delete user again (idempotent check) + register: result + junipernetworks.junos.junos_user: + name: test_user + state: absent + full_name: test_user + role: operator + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown list of users + register: result + junipernetworks.junos.junos_user: + aggregate: + - name: test_user1 + state: absent + + - name: test_user2 + state: absent + +- name: Create list of users + register: result + junipernetworks.junos.junos_user: + aggregate: + - name: test_user1 + full_name: test_user2 + role: operator + state: present + + - name: test_user2 + full_name: test_user2 + role: read-only + state: present + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'test_user1' in config.xml" + - "'test_user2' in config.xml" + +- name: Delete list of users + register: result + junipernetworks.junos.junos_user: + aggregate: + - name: test_user1 + full_name: test_user2 + role: operator + state: absent + + - name: test_user2 + full_name: test_user2 + role: read-only + state: absent + +- name: Get running configuration + register: config + junipernetworks.junos.junos_rpc: + rpc: get-configuration + +- ansible.builtin.assert: + that: + - result.changed == true + - "'test_user1' not in config.xml" + - "'test_user2' not in config.xml" + +- name: Create list of users + register: result + junipernetworks.junos.junos_user: + aggregate: + - name: "{{ ansible_user|default('ansible') }}" + + - name: test_user1 + full_name: test_user2 + role: operator + + - name: test_user2 + full_name: test_user2 + role: read-only + +- name: Purge users except the users in aggregate + register: result + junipernetworks.junos.junos_user: + aggregate: + - name: "{{ ansible_user|default('ansible') }}" + purge: true + +- ansible.builtin.assert: + that: + - result.changed == true + - result.diff.prepared is search("\- *user test_user1") + - result.diff.prepared is search("\- *user test_user2") + +- ansible.builtin.debug: + msg="END junos_user netconf/basic.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/meta/main.yaml new file mode 100644 index 00000000..7f867d73 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/meta/main.yaml @@ -0,0 +1,2 @@ +--- +dependencies: diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tasks/main.yaml new file mode 100644 index 00000000..ee273606 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tasks/netconf.yaml new file mode 100644 index 00000000..3db81d09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tasks/netconf.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect all netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/_base_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/_base_config.yaml new file mode 100644 index 00000000..99fc71c5 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/_base_config.yaml @@ -0,0 +1,13 @@ +--- +- ansible.builtin.debug: + msg: Start junos_vlans base config ansible_connection={{ ansible_connection + }} + +- name: Configure base vlans + junipernetworks.junos.junos_config: + lines: + - set vlans vlan1 vlan-id 1 + - set vlans vlan2 vlan-id 2 + +- ansible.builtin.debug: + msg: End junos_vlans base config ansible_connection={{ ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/_initial_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/_initial_config.yaml new file mode 100644 index 00000000..0ef2c234 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/_initial_config.yaml @@ -0,0 +1,12 @@ +--- +- ansible.builtin.debug: + msg: "START junos_routing_instances reset config on connection={{ ansible_connection }}" + +- name: Configure policy options w.r.t routing-instances + junipernetworks.junos.junos_config: + lines: + - set vlans vlan1 vlan-id 1 + - set vlans vlan2 vlan-id 2 + - set vlans vlan2 vlan-id 2 l3-interface irb.12 +- ansible.builtin.debug: + msg: "END junos_routing_instances reset config on connection={{ ansible_connection }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/_remove_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/_remove_config.yaml new file mode 100644 index 00000000..11176a31 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/_remove_config.yaml @@ -0,0 +1,12 @@ +--- +- ansible.builtin.debug: + msg: Start junos_vlans teardown ansible_connection={{ ansible_connection }} + +- name: Remove interface config + junipernetworks.junos.junos_config: + lines: + - delete vlans vlan1 + - delete vlans vlan2 + +- ansible.builtin.debug: + msg: End junos_vlans teardown ansible_connection={{ ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/deleted.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/deleted.yaml new file mode 100644 index 00000000..25e75c37 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/deleted.yaml @@ -0,0 +1,39 @@ +--- +- ansible.builtin.debug: + msg: + START junos_vlans deleted integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- block: + - name: Delete the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_vlans: &id001 + config: + state: deleted + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - not result.after + + - name: + Delete the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_vlans: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_vlans deleted integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/empty_config.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/empty_config.yaml new file mode 100644 index 00000000..61e29a1e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/empty_config.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: START junos_vlans empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_vlans: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_vlans: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Override with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_vlans: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_vlans: + running_config: + state: parsed + +- ansible.builtin.debug: + msg: result +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + junipernetworks.junos.junos_vlans: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- ansible.builtin.debug: + msg: END junos_vlans empty_config integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/fixtures/parsed.cfg b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/fixtures/parsed.cfg new file mode 100644 index 00000000..ae9fbe0f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/fixtures/parsed.cfg @@ -0,0 +1,17 @@ + + + + 18.4R1-S2.4 + + + vlan1 + 1 + + + vlan2 + 2 + irb.12 + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/gathered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/gathered.yaml new file mode 100644 index 00000000..bd5c270b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/gathered.yaml @@ -0,0 +1,35 @@ +--- +- ansible.builtin.debug: + msg: START junos_vlans gathered integration tests on connection={{ ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.include_tasks: _initial_config.yaml + + - ansible.builtin.set_fact: + expected_gathered_output: + - name: vlan1 + vlan_id: 1 + - name: vlan2 + vlan_id: 2 + l3_interface: "irb.12" + + - name: Gather bgp address family facts using gathered state + register: result + junipernetworks.junos.junos_vlans: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + - "{{ expected_gathered_output | symmetric_difference(result['gathered']) |length\ + \ == 0 }}" + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_vlans gathered integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/merged.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/merged.yaml new file mode 100644 index 00000000..6456a2d2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/merged.yaml @@ -0,0 +1,53 @@ +--- +- ansible.builtin.debug: + msg: + START junos_vlans merged integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.set_fact: + expected_merged_output: + - name: vlan1 + vlan_id: 1 + + - name: vlan2 + vlan_id: 2 + l3_interface: "irb.12" + +- block: + - name: Merge the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_vlans: &id001 + config: + - name: vlan1 + vlan_id: 1 + + - name: vlan2 + vlan_id: 2 + l3_interface: "irb.12" + state: merged + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_merged_output | symmetric_difference(result['after']) |length\ + \ == 0 }}" + + - name: + Merge the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_vlans: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_vlans merged integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/overridden.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/overridden.yaml new file mode 100644 index 00000000..3341f8f2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/overridden.yaml @@ -0,0 +1,47 @@ +--- +- ansible.builtin.debug: + msg: + START junos_vlans overridden integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_overridden_output: + - name: vlan1 + vlan_id: 100 + +- block: + - name: Override the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_vlans: &id001 + config: + - name: vlan1 + vlan_id: 100 + state: overridden + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_overridden_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Override the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_vlans: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_vlans overridden integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/parsed.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/parsed.yaml new file mode 100644 index 00000000..4fa120c2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/parsed.yaml @@ -0,0 +1,29 @@ +--- +- ansible.builtin.debug: + msg: + START junos_vlans parsed integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.set_fact: + expected_parsed_output: + - name: vlan1 + vlan_id: 1 + - name: vlan2 + vlan_id: 2 + l3_interface: "irb.12" + +- name: Parse externally provided vlans config to agnostic model + register: result + junipernetworks.junos.junos_vlans: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that config was correctly parsed + ansible.builtin.assert: + that: + - "{{ expected_parsed_output == result['parsed'] }}" + - result['changed'] == false +- ansible.builtin.debug: + msg: + END junos_vlans parsed integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/rendered.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/rendered.yaml new file mode 100644 index 00000000..95e7af25 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/rendered.yaml @@ -0,0 +1,28 @@ +--- +- ansible.builtin.debug: + msg: START junos_vlans rendered integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.set_fact: + expected_rendered_output: 'vlan11vlan22irb.12' +- name: Render platform specific commands from task input using rendered state + register: result + junipernetworks.junos.junos_vlans: + config: + - name: vlan1 + vlan_id: 1 + + - name: vlan2 + vlan_id: 2 + l3_interface: "irb.12" + state: rendered + +- name: Assert that correct set of commands were rendered and task changed is false. + ansible.builtin.assert: + that: + - "{{ expected_rendered_output == result['rendered'] }}" + - result['changed'] == false + +- ansible.builtin.debug: + msg: END junos_vlans rendered integration tests on connection={{ + ansible_connection }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/replaced.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/replaced.yaml new file mode 100644 index 00000000..d9f102c6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/replaced.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: + START junos_vlans replaced integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _base_config.yaml + +- ansible.builtin.set_fact: + expected_replaced_output: + - name: vlan1 + vlan_id: 10 + + - name: vlan2 + vlan_id: 2 + +- block: + - name: Replace the provided configuration with the exisiting running configuration + register: result + junipernetworks.junos.junos_vlans: &id001 + config: + - name: vlan1 + vlan_id: 10 + state: replaced + + - name: Assert the configuration is reflected on host + ansible.builtin.assert: + that: + - "{{ expected_replaced_output | symmetric_difference(result['after'])\ + \ |length == 0 }}" + + - name: + Replace the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + junipernetworks.junos.junos_vlans: *id001 + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_vlans replaced integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/rtt.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/rtt.yml new file mode 100644 index 00000000..dbd77cd8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vlans/tests/netconf/rtt.yml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: START junos_vlans round trip integration tests on connection={{ + ansible_connection }} + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + - ansible.builtin.include_tasks: _initial_config.yaml + + - name: Apply the provided configuration (base config) + register: base_config + junipernetworks.junos.junos_vlans: + config: + - name: vlan1 + vlan_id: 1 + - name: vlan2 + vlan_id: 2 + l3_interface: "irb.12" + state: merged + + - name: Gather interfaces facts + junipernetworks.junos.junos_facts: + gather_subset: + - default + gather_network_resources: + - vlans + + - name: Apply the provided configuration (config to be reverted) + register: result + junipernetworks.junos.junos_vlans: + config: + - name: vlan1 + vlan_id: 10 + state: replaced + + - name: Assert that changes were applied + ansible.builtin.assert: + that: result['changed'] == true + + - name: Revert back to base config using facts round trip + register: revert + junipernetworks.junos.junos_vlans: + config: "{{ ansible_facts['network_resources']['vlans'] }}" + state: replaced + + - name: Assert that before dicts are correct + ansible.builtin.assert: + that: + - result.changed == True + - "{{ result['after'] | symmetric_difference( revert['before'])\ + \ |length == 0 }}" + + - name: Assert that config was reverted + ansible.builtin.assert: + that: + - result.changed == True + - "{{ base_config['after'] | symmetric_difference( revert['after'])\ + \ |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: + END junos_vlans round trip integration tests on connection={{ ansible_connection + }} diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/defaults/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/defaults/main.yaml new file mode 100644 index 00000000..9ef5ba51 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/meta/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/meta/main.yml new file mode 100644 index 00000000..d80f5fbf --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_junos_tests diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/tasks/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/tasks/main.yaml new file mode 100644 index 00000000..ac951c8f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/tasks/main.yaml @@ -0,0 +1,3 @@ +--- +- name: Invoke netconf tasks + ansible.builtin.include_tasks: netconf.yaml diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/tasks/netconf.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/tasks/netconf.yaml new file mode 100644 index 00000000..3fa0553b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/tasks/netconf.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect netconf test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/netconf" + patterns: "{{ testcase }}.yaml" + register: test_cases + connection: local + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.netconf) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.netconf + tags: + - netconf diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/tests/netconf/basic.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/tests/netconf/basic.yaml new file mode 100644 index 00000000..160500f9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/junos_vrf/tests/netconf/basic.yaml @@ -0,0 +1,320 @@ +--- +- ansible.builtin.debug: + msg="START junos_vrf netconf/basic.yaml on connection={{ ansible_connection + }}" + +- name: setup - remove vrf + junipernetworks.junos.junos_vrf: + name: test-1 + state: absent + +- name: Configure vrf and its parameter + register: result + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/6 + - ge-0/0/5 + rd: 192.0.2.3:10 + target: target:65513:111 + state: present + +- ansible.builtin.assert: + that: + - result.changed == true + - result.diff.prepared is search("\+ *test-1") + - result.diff.prepared is search("\+ *description test-vrf-1") + - result.diff.prepared is search("\+ *instance-type vrf") + - result.diff.prepared is search("\+ *interface ge-0/0/5.0") + - result.diff.prepared is search("\+ *interface ge-0/0/6.0") + - result.diff.prepared is search("\+ *route-distinguisher 192.0.2.3:10") + - result.diff.prepared is search("\+ *vrf-target target:65513:111") + +- name: Configure vrf and its parameter (idempotent) + register: result + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/6 + - ge-0/0/5 + rd: 192.0.2.3:10 + target: target:65513:111 + state: present + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Change vrf parameter + register: result + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + state: present + +- ansible.builtin.assert: + that: + - result.changed == true + - "'[edit routing-instances test-1]' in result.diff.prepared" + - result.diff.prepared is search("\+ *interface ge-0/0/2.0") + - result.diff.prepared is search("\+ *interface ge-0/0/3.0") + - "'[edit routing-instances test-1]' in result.diff.prepared" + - result.diff.prepared is search("\+ *route-distinguisher 192.0.2.1:10") + - result.diff.prepared is search("\+ *vrf-target target:65514:113") + +- name: Deactivate vrf + register: result + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + state: present + active: false + +- ansible.builtin.assert: + that: + - result.changed == true + - "'[edit routing-instances]' in result.diff.prepared" + - result.diff.prepared is search("! *inactive[:] test-1") + - "'[edit routing-instances test-1]' in result.diff.prepared" + - result.diff.prepared is search("! *inactive[:] interface ge-0/0/2.0") + - result.diff.prepared is search("! *inactive[:] interface ge-0/0/3.0") + - "'[edit routing-instances test-1]' in result.diff.prepared" + - result.diff.prepared is search("! *inactive[:] route-distinguisher") + - result.diff.prepared is search("! *inactive[:] vrf-target") + +- name: Activate vrf + register: result + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + state: present + active: true + +- ansible.builtin.assert: + that: + - result.changed == true + - "'[edit routing-instances]' in result.diff.prepared" + - result.diff.prepared is search("! *active[:] test-1") + - "'[edit routing-instances test-1]' in result.diff.prepared" + - result.diff.prepared is search("! *active[:] interface ge-0/0/2.0") + - result.diff.prepared is search("! *active[:] interface ge-0/0/3.0") + - "'[edit routing-instances test-1]' in result.diff.prepared" + - result.diff.prepared is search("! *active[:] route-distinguisher") + - result.diff.prepared is search("! *active[:] vrf-target") + +- name: Delete vrf + register: result + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + state: absent + +- ansible.builtin.assert: + that: + - result.changed == true + - result.diff.prepared is search("\- *test-1") + - result.diff.prepared is search("\- *description test-vrf-1") + - result.diff.prepared is search("\- *instance-type vrf") + - result.diff.prepared is search("\- *interface ge-0/0/2.0") + - result.diff.prepared is search("\- *interface ge-0/0/3.0") + - result.diff.prepared is search("\- *route-distinguisher 192.0.2.1:10") + - result.diff.prepared is search("\- *vrf-target target:65514:113") + +- name: Delete vrf (idempotent) + register: result + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + state: absent + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Setup vrf using aggregate + register: result + junipernetworks.junos.junos_vrf: + aggregate: + - name: test-1 + + - name: test-2 + state: absent + +- name: Create vrf using aggregate + register: result + junipernetworks.junos.junos_vrf: + aggregate: + - name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + + - name: test-2 + description: test-vrf-2 + interfaces: + - ge-0/0/4 + - ge-0/0/5 + rd: 192.0.2.2:10 + target: target:65515:114 + +- ansible.builtin.assert: + that: + - result.changed == true + - result.diff.prepared is search("\+ *test-1") + - result.diff.prepared is search("\+ *description test-vrf-1") + - result.diff.prepared is search("\+ *instance-type vrf") + - result.diff.prepared is search("\+ *interface ge-0/0/2.0") + - result.diff.prepared is search("\+ *interface ge-0/0/3.0") + - result.diff.prepared is search("\+ *route-distinguisher 192.0.2.1:10") + - result.diff.prepared is search("\+ *vrf-target target:65514:113") + - result.diff.prepared is search("\+ *test-2") + - result.diff.prepared is search("\+ *description test-vrf-2") + - result.diff.prepared is search("\+ *instance-type vrf") + - result.diff.prepared is search("\+ *interface ge-0/0/4.0") + - result.diff.prepared is search("\+ *interface ge-0/0/5.0") + - result.diff.prepared is search("\+ *route-distinguisher 192.0.2.2:10") + - result.diff.prepared is search("\+ *vrf-target target:65515:114") + +- name: Deactivate vrf configuration using aggregate + register: result + junipernetworks.junos.junos_vrf: + aggregate: + - name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + + - name: test-2 + description: test-vrf-2 + interfaces: + - ge-0/0/4 + - ge-0/0/5 + rd: 192.0.2.2:10 + target: target:65515:114 + active: false + +- ansible.builtin.assert: + that: + - result.changed == true + - "'edit routing-instances test-1' in result.diff.prepared" + - result.diff.prepared is search("! *inactive[:] interface ge-0/0/2.0") + - result.diff.prepared is search("! *inactive[:] interface ge-0/0/3.0") + - result.diff.prepared is search("! *inactive[:] route-distinguisher") + - result.diff.prepared is search("! *inactive[:] vrf-target") + - "'edit routing-instances test-2' in result.diff.prepared" + - result.diff.prepared is search("! *inactive[:] interface ge-0/0/4.0") + - result.diff.prepared is search("! *inactive[:] interface ge-0/0/5.0") + - result.diff.prepared is search("! *inactive[:] route-distinguisher") + - result.diff.prepared is search("! *inactive[:] vrf-target") + +- name: Deactivate vrf configuration using aggregate + register: result + junipernetworks.junos.junos_vrf: + aggregate: + - name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3 + - ge-0/0/2 + rd: 192.0.2.1:10 + target: target:65514:113 + + - name: test-2 + description: test-vrf-2 + interfaces: + - ge-0/0/4 + - ge-0/0/5 + rd: 192.0.2.2:10 + target: target:65515:114 + active: true + +- ansible.builtin.assert: + that: + - result.changed == true + - "'edit routing-instances test-1' in result.diff.prepared" + - result.diff.prepared is search("! *active[:] interface ge-0/0/2.0") + - result.diff.prepared is search("! *active[:] interface ge-0/0/3.0") + - result.diff.prepared is search("! *active[:] route-distinguisher") + - result.diff.prepared is search("! *active[:] vrf-target") + - "'edit routing-instances test-2' in result.diff.prepared" + - result.diff.prepared is search("! *active[:] interface ge-0/0/4.0") + - result.diff.prepared is search("! *active[:] interface ge-0/0/5.0") + - result.diff.prepared is search("! *active[:] route-distinguisher") + - result.diff.prepared is search("! *active[:] vrf-target") + +- name: Delete vrf configuration using aggregate + register: result + junipernetworks.junos.junos_vrf: + aggregate: + - name: test-1 + + - name: test-2 + state: absent + +- ansible.builtin.assert: + that: + - result.changed == true + - result.diff.prepared is search("\- *test-1") + - result.diff.prepared is search("\- *description test-vrf-1") + - result.diff.prepared is search("\- *instance-type vrf") + - result.diff.prepared is search("\- *interface ge-0/0/2.0") + - result.diff.prepared is search("\- *interface ge-0/0/3.0") + - result.diff.prepared is search("\- *route-distinguisher 192.0.2.1:10") + - result.diff.prepared is search("\- *vrf-target target:65514:113") + - result.diff.prepared is search("\- *test-2") + - result.diff.prepared is search("\- *description test-vrf-2") + - result.diff.prepared is search("\- *instance-type vrf") + - result.diff.prepared is search("\- *interface ge-0/0/4.0") + - result.diff.prepared is search("\- *interface ge-0/0/5.0") + - result.diff.prepared is search("\- *route-distinguisher 192.0.2.2:10") + - result.diff.prepared is search("\- *vrf-target target:65515:114") + +- name: Delete vrf configuration using aggregate (idempotent) + register: result + junipernetworks.junos.junos_vrf: + aggregate: + - name: test-1 + + - name: test-2 + state: absent + +- ansible.builtin.assert: + that: + - result.changed == false + +- ansible.builtin.debug: + msg="END junos_vrf netconf/basic.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/prepare_junos_tests/meta/main.yaml b/ansible_collections/junipernetworks/junos/tests/integration/targets/prepare_junos_tests/meta/main.yaml new file mode 100644 index 00000000..61d3ffe4 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/prepare_junos_tests/meta/main.yaml @@ -0,0 +1,2 @@ +--- +allow_duplicates: true diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/prepare_junos_tests/tasks/main.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/prepare_junos_tests/tasks/main.yml new file mode 100644 index 00000000..68bf6e30 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/prepare_junos_tests/tasks/main.yml @@ -0,0 +1,4 @@ +--- +- name: Run the prepare steps if requested + ansible.builtin.include_tasks: prepare.yml + when: prepare_junos_tests_task | default(True) | bool diff --git a/ansible_collections/junipernetworks/junos/tests/integration/targets/prepare_junos_tests/tasks/prepare.yml b/ansible_collections/junipernetworks/junos/tests/integration/targets/prepare_junos_tests/tasks/prepare.yml new file mode 100644 index 00000000..179fb0d9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/integration/targets/prepare_junos_tests/tasks/prepare.yml @@ -0,0 +1,18 @@ +--- +- name: Debug task + ansible.builtin.debug: + msg: "START prepare_junos_tests/main.yaml" + +- name: Ensure netconf is enabled + connection: ansible.netcommon.network_cli + tags: netconf + junipernetworks.junos.junos_netconf: + state: present + +- name: Wait for netconf server to come up + delegate_to: localhost + tags: netconf + ansible.builtin.wait_for: + host: "{{ hostvars[item].ansible_host }}" + port: 830 + with_inventory_hostnames: junos diff --git a/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.14.txt b/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.14.txt new file mode 100644 index 00000000..ed6d78df --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.14.txt @@ -0,0 +1 @@ +plugins/action/junos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` diff --git a/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.15.txt b/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.15.txt new file mode 100644 index 00000000..ed6d78df --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.15.txt @@ -0,0 +1 @@ +plugins/action/junos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` diff --git a/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.16.txt b/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.16.txt new file mode 100644 index 00000000..ed6d78df --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.16.txt @@ -0,0 +1 @@ +plugins/action/junos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` diff --git a/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.17.txt b/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.17.txt new file mode 100644 index 00000000..ed6d78df --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.17.txt @@ -0,0 +1 @@ +plugins/action/junos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` diff --git a/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.18.txt b/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.18.txt new file mode 100644 index 00000000..ed6d78df --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.18.txt @@ -0,0 +1 @@ +plugins/action/junos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` diff --git a/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.19.txt b/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.19.txt new file mode 100644 index 00000000..ed6d78df --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/sanity/ignore-2.19.txt @@ -0,0 +1 @@ +plugins/action/junos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` diff --git a/ansible_collections/junipernetworks/junos/tests/unit/__init__.py b/ansible_collections/junipernetworks/junos/tests/unit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/junipernetworks/junos/tests/unit/mock/__init__.py b/ansible_collections/junipernetworks/junos/tests/unit/mock/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/junipernetworks/junos/tests/unit/mock/loader.py b/ansible_collections/junipernetworks/junos/tests/unit/mock/loader.py new file mode 100644 index 00000000..0fc53edc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/mock/loader.py @@ -0,0 +1,117 @@ +# (c) 2012-2014, Michael DeHaan +# +# 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 + +from ansible.errors import AnsibleParserError +from ansible.module_utils._text import to_bytes, to_text +from ansible.parsing.dataloader import DataLoader + + +class DictDataLoader(DataLoader): + def __init__(self, file_mapping=None): + file_mapping = {} if file_mapping is None else file_mapping + assert isinstance(file_mapping, dict) + + super(DictDataLoader, self).__init__() + + self._file_mapping = file_mapping + self._build_known_directories() + self._vault_secrets = None + + def load_from_file(self, path, cache=True, unsafe=False): + path = to_text(path) + if path in self._file_mapping: + return self.load(self._file_mapping[path], path) + return None + + # TODO: the real _get_file_contents returns a bytestring, so we actually convert the + # unicode/text it's created with to utf-8 + def _get_file_contents(self, file_name): + file_name = to_text(file_name) + if file_name in self._file_mapping: + return (to_bytes(self._file_mapping[file_name]), False) + else: + raise AnsibleParserError("file not found: %s" % file_name) + + def path_exists(self, path): + path = to_text(path) + return path in self._file_mapping or path in self._known_directories + + def is_file(self, path): + path = to_text(path) + return path in self._file_mapping + + def is_directory(self, path): + path = to_text(path) + return path in self._known_directories + + def list_directory(self, path): + ret = [] + path = to_text(path) + for x in list(self._file_mapping.keys()) + self._known_directories: + if x.startswith(path): + if os.path.dirname(x) == path: + ret.append(os.path.basename(x)) + return ret + + def is_executable(self, path): + # FIXME: figure out a way to make paths return true for this + return False + + def _add_known_directory(self, directory): + if directory not in self._known_directories: + self._known_directories.append(directory) + + def _build_known_directories(self): + self._known_directories = [] + for path in self._file_mapping: + dirname = os.path.dirname(path) + while dirname not in ("/", ""): + self._add_known_directory(dirname) + dirname = os.path.dirname(dirname) + + def push(self, path, content): + rebuild_dirs = False + if path not in self._file_mapping: + rebuild_dirs = True + + self._file_mapping[path] = content + + if rebuild_dirs: + self._build_known_directories() + + def pop(self, path): + if path in self._file_mapping: + del self._file_mapping[path] + self._build_known_directories() + + def clear(self): + self._file_mapping = dict() + self._known_directories = [] + + def get_basedir(self): + return os.getcwd() + + def set_vault_secrets(self, vault_secrets): + self._vault_secrets = vault_secrets diff --git a/ansible_collections/junipernetworks/junos/tests/unit/mock/path.py b/ansible_collections/junipernetworks/junos/tests/unit/mock/path.py new file mode 100644 index 00000000..7d287a5f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/mock/path.py @@ -0,0 +1,13 @@ +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type +from unittest.mock import MagicMock + +from ansible.utils.path import unfrackpath + + +mock_unfrackpath_noop = MagicMock( + spec_set=unfrackpath, + side_effect=lambda x, *args, **kwargs: x, +) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/mock/procenv.py b/ansible_collections/junipernetworks/junos/tests/unit/mock/procenv.py new file mode 100644 index 00000000..e6e09464 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/mock/procenv.py @@ -0,0 +1,96 @@ +# (c) 2016, Matt Davis +# (c) 2016, Toshio Kuratomi +# +# 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 +import sys + +from contextlib import contextmanager +from io import BytesIO, StringIO +from unittest import TestCase + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.six import PY3 + + +@contextmanager +def swap_stdin_and_argv(stdin_data="", argv_data=tuple()): + """ + context manager that temporarily masks the test runner's values for stdin and argv + """ + real_stdin = sys.stdin + real_argv = sys.argv + + if PY3: + fake_stream = StringIO(stdin_data) + fake_stream.buffer = BytesIO(to_bytes(stdin_data)) + else: + fake_stream = BytesIO(to_bytes(stdin_data)) + + try: + sys.stdin = fake_stream + sys.argv = argv_data + + yield + finally: + sys.stdin = real_stdin + sys.argv = real_argv + + +@contextmanager +def swap_stdout(): + """ + context manager that temporarily replaces stdout for tests that need to verify output + """ + old_stdout = sys.stdout + + if PY3: + fake_stream = StringIO() + else: + fake_stream = BytesIO() + + try: + sys.stdout = fake_stream + + yield fake_stream + finally: + sys.stdout = old_stdout + + +class ModuleTestCase(TestCase): + def setUp(self, module_args=None): + if module_args is None: + module_args = { + "_ansible_remote_tmp": "/tmp", + "_ansible_keep_remote_files": False, + } + + args = json.dumps(dict(ANSIBLE_MODULE_ARGS=module_args)) + + # unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually + self.stdin_swap = swap_stdin_and_argv(stdin_data=args) + self.stdin_swap.__enter__() + + def tearDown(self): + # unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually + self.stdin_swap.__exit__(None, None, None) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/mock/vault_helper.py b/ansible_collections/junipernetworks/junos/tests/unit/mock/vault_helper.py new file mode 100644 index 00000000..82d01f5c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/mock/vault_helper.py @@ -0,0 +1,44 @@ +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible.module_utils._text import to_bytes +from ansible.parsing.vault import VaultSecret + + +class TextVaultSecret(VaultSecret): + """A secret piece of text. ie, a password. Tracks text encoding. + + The text encoding of the text may not be the default text encoding so + we keep track of the encoding so we encode it to the same bytes.""" + + def __init__(self, text, encoding=None, errors=None, _bytes=None): + super(TextVaultSecret, self).__init__() + self.text = text + self.encoding = encoding or "utf-8" + self._bytes = _bytes + self.errors = errors or "strict" + + @property + def bytes(self): + """The text encoded with encoding, unless we specifically set _bytes.""" + return self._bytes or to_bytes( + self.text, + encoding=self.encoding, + errors=self.errors, + ) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/mock/yaml_helper.py b/ansible_collections/junipernetworks/junos/tests/unit/mock/yaml_helper.py new file mode 100644 index 00000000..e46d3180 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/mock/yaml_helper.py @@ -0,0 +1,177 @@ +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type +import io + +import yaml + +from ansible.module_utils.six import PY3 +from ansible.parsing.yaml.dumper import AnsibleDumper +from ansible.parsing.yaml.loader import AnsibleLoader + + +class YamlTestUtils(object): + """Mixin class to combine with a unittest.TestCase subclass.""" + + def _loader(self, stream): + """Vault related tests will want to override this. + + Vault cases should setup a AnsibleLoader that has the vault password.""" + return AnsibleLoader(stream) + + def _dump_stream(self, obj, stream, dumper=None): + """Dump to a py2-unicode or py3-string stream.""" + if PY3: + return yaml.dump(obj, stream, Dumper=dumper) + else: + return yaml.dump(obj, stream, Dumper=dumper, encoding=None) + + def _dump_string(self, obj, dumper=None): + """Dump to a py2-unicode or py3-string""" + if PY3: + return yaml.dump(obj, Dumper=dumper) + else: + return yaml.dump(obj, Dumper=dumper, encoding=None) + + def _dump_load_cycle(self, obj): + # Each pass though a dump or load revs the 'generation' + # obj to yaml string + string_from_object_dump = self._dump_string(obj, dumper=AnsibleDumper) + + # wrap a stream/file like StringIO around that yaml + stream_from_object_dump = io.StringIO(string_from_object_dump) + loader = self._loader(stream_from_object_dump) + # load the yaml stream to create a new instance of the object (gen 2) + obj_2 = loader.get_data() + + # dump the gen 2 objects directory to strings + string_from_object_dump_2 = self._dump_string( + obj_2, + dumper=AnsibleDumper, + ) + + # The gen 1 and gen 2 yaml strings + self.assertEqual(string_from_object_dump, string_from_object_dump_2) + # the gen 1 (orig) and gen 2 py object + self.assertEqual(obj, obj_2) + + # again! gen 3... load strings into py objects + stream_3 = io.StringIO(string_from_object_dump_2) + loader_3 = self._loader(stream_3) + obj_3 = loader_3.get_data() + + string_from_object_dump_3 = self._dump_string( + obj_3, + dumper=AnsibleDumper, + ) + + self.assertEqual(obj, obj_3) + # should be transitive, but... + self.assertEqual(obj_2, obj_3) + self.assertEqual(string_from_object_dump, string_from_object_dump_3) + + def _old_dump_load_cycle(self, obj): + """Dump the passed in object to yaml, load it back up, dump again, compare.""" + stream = io.StringIO() + + yaml_string = self._dump_string(obj, dumper=AnsibleDumper) + self._dump_stream(obj, stream, dumper=AnsibleDumper) + + yaml_string_from_stream = stream.getvalue() + + # reset stream + stream.seek(0) + + loader = self._loader(stream) + # loader = AnsibleLoader(stream, vault_password=self.vault_password) + obj_from_stream = loader.get_data() + + stream_from_string = io.StringIO(yaml_string) + loader2 = self._loader(stream_from_string) + # loader2 = AnsibleLoader(stream_from_string, vault_password=self.vault_password) + obj_from_string = loader2.get_data() + + stream_obj_from_stream = io.StringIO() + stream_obj_from_string = io.StringIO() + + if PY3: + yaml.dump( + obj_from_stream, + stream_obj_from_stream, + Dumper=AnsibleDumper, + ) + yaml.dump( + obj_from_stream, + stream_obj_from_string, + Dumper=AnsibleDumper, + ) + else: + yaml.dump( + obj_from_stream, + stream_obj_from_stream, + Dumper=AnsibleDumper, + encoding=None, + ) + yaml.dump( + obj_from_stream, + stream_obj_from_string, + Dumper=AnsibleDumper, + encoding=None, + ) + + yaml_string_stream_obj_from_stream = stream_obj_from_stream.getvalue() + yaml_string_stream_obj_from_string = stream_obj_from_string.getvalue() + + stream_obj_from_stream.seek(0) + stream_obj_from_string.seek(0) + + if PY3: + yaml_string_obj_from_stream = yaml.dump( + obj_from_stream, + Dumper=AnsibleDumper, + ) + yaml_string_obj_from_string = yaml.dump( + obj_from_string, + Dumper=AnsibleDumper, + ) + else: + yaml_string_obj_from_stream = yaml.dump( + obj_from_stream, + Dumper=AnsibleDumper, + encoding=None, + ) + yaml_string_obj_from_string = yaml.dump( + obj_from_string, + Dumper=AnsibleDumper, + encoding=None, + ) + + assert yaml_string == yaml_string_obj_from_stream + assert yaml_string == yaml_string_obj_from_stream == yaml_string_obj_from_string + assert ( + yaml_string + == yaml_string_obj_from_stream + == yaml_string_obj_from_string + == yaml_string_stream_obj_from_stream + == yaml_string_stream_obj_from_string + ) + assert obj == obj_from_stream + assert obj == obj_from_string + assert obj == yaml_string_obj_from_stream + assert obj == yaml_string_obj_from_string + assert ( + obj + == obj_from_stream + == obj_from_string + == yaml_string_obj_from_stream + == yaml_string_obj_from_string + ) + return { + "obj": obj, + "yaml_string": yaml_string, + "yaml_string_from_stream": yaml_string_from_stream, + "obj_from_stream": obj_from_stream, + "obj_from_string": obj_from_string, + "yaml_string_obj_from_string": yaml_string_obj_from_string, + } diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/__init__.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/conftest.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/conftest.py new file mode 100644 index 00000000..349e71ad --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/conftest.py @@ -0,0 +1,34 @@ +# Copyright (c) 2017 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json + +import pytest + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.common._collections_compat import MutableMapping +from ansible.module_utils.six import string_types + + +@pytest.fixture +def patch_ansible_module(request, mocker): + if isinstance(request.param, string_types): + args = request.param + elif isinstance(request.param, MutableMapping): + if "ANSIBLE_MODULE_ARGS" not in request.param: + request.param = {"ANSIBLE_MODULE_ARGS": request.param} + if "_ansible_remote_tmp" not in request.param["ANSIBLE_MODULE_ARGS"]: + request.param["ANSIBLE_MODULE_ARGS"]["_ansible_remote_tmp"] = "/tmp" + if "_ansible_keep_remote_files" not in request.param["ANSIBLE_MODULE_ARGS"]: + request.param["ANSIBLE_MODULE_ARGS"]["_ansible_keep_remote_files"] = False + args = json.dumps(request.param) + else: + raise Exception( + "Malformed data to the patch_ansible_module pytest fixture", + ) + + mocker.patch("ansible.module_utils.basic._ANSIBLE_ARGS", to_bytes(args)) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/__init__.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/__init__.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/__init__.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply.txt new file mode 100644 index 00000000..4bb5afa0 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply.txt @@ -0,0 +1,7 @@ + + + set version 15.1X49-D15.4 + set system host-name vsrx01 + set system domain-name ansible.com + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_diff.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_diff.txt new file mode 100644 index 00000000..c2b803f8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_diff.txt @@ -0,0 +1,12 @@ + + + +[edit interfaces] ++ ae11 { ++ unit 0 { ++ description Test; ++ } ++ } + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_json.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_json.txt new file mode 100644 index 00000000..a1d7345a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_json.txt @@ -0,0 +1,190 @@ + +{ + "configuration" : [ + { + "system" : [ + { + "host-name" : [ + { + "data" : "vsrx01" + } + ], + "domain-name" : [ + { + "data" : "junos.com" + } + ], + "name-server" : [ + { + "name" : + { + "data" : "172.26.1.1" + } + }, + { + "name" : + { + "data" : "8.8.8.8" + } + } + ], + "services" : [ + { + "ssh" : [ + { + } + ], + "telnet" : [ + { + } + ], + "netconf" : [ + { + "ssh" : [ + { + "port" : [ + { + "data" : "830" + } + ] + } + ], + "traceoptions" : [ + { + "file" : [ + { + "filename" : [ + { + "data" : "netconf-ops.log" + } + ] + } + ], + "flag" : [ + { + "name" : + { + "data" : "all" + } + } + ] + } + ] + } + ], + "web-management" : [ + { + "http" : [ + { + "interface" : [ + { + "data" : "fxp0.0" + } + ] + } + ] + } + ] + } + ], + "syslog" : [ + { + "user" : [ + { + "name" : + { + "data" : "*" + }, + "contents" : [ + { + "name" : + { + "data" : "any" + }, + "emergency" : [ + { + "data" : null + } + ] + } + ] + } + ], + "file" : [ + { + "name" : + { + "data" : "messages" + }, + "contents" : [ + { + "name" : + { + "data" : "any" + }, + "any" : [ + { + "data" : null + } + ] + }, + { + "name" : + { + "data" : "authorization" + }, + "info" : [ + { + "data" : null + } + ] + } + ] + }, + { + "name" : + { + "data" : "interactive-commands" + }, + "contents" : [ + { + "name" : + { + "data" : "interactive-commands" + }, + "any" : [ + { + "data" : null + } + ] + } + ] + }, + { + "name" : + { + "data" : "test1" + }, + "contents" : [ + { + "name" : + { + "data" : "any" + }, + "any" : [ + { + "data" : null + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] +} + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_set.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_set.txt new file mode 100644 index 00000000..c5ec7fb0 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_set.txt @@ -0,0 +1,7 @@ + + + set version 15.1X49-D15.4 + set system host-name vsrx01 + set system domain-name ansible.com + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_text.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_text.txt new file mode 100644 index 00000000..c1ba1ad9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_text.txt @@ -0,0 +1,9 @@ + + + version 20.3R2.9; + system { + host-name vsrx01; + domain-name ansible.com; + } + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_xml.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_xml.txt new file mode 100644 index 00000000..87cd765d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/get_configuration_rpc_reply_xml.txt @@ -0,0 +1,9 @@ + + + 20.3R2.9 + + vsrx01 + ansible.com + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_address_family.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_address_family.cfg new file mode 100644 index 00000000..c1d2042f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_address_family.cfg @@ -0,0 +1,22 @@ +description "This is configured with Junos_bgp resource module replace"; +preference 2; +hold-time 5; +advertise-inactive; +out-delay 10; +bgp-error-tolerance { + malformed-route-limit 40000000; +} +authentication-algorithm md5; +advertise-bgp-static { + policy static-to-bgp; +} +bfd-liveness-detection { + version automatic; + minimum-receive-interval 8; + multiplier 30; + no-adaptation; + transmit-interval { + minimum-interval 4; + } +} +egress-te-sid-stats; diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_address_family_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_address_family_config.cfg new file mode 100644 index 00000000..18712c32 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_address_family_config.cfg @@ -0,0 +1,137 @@ + + + + 18.4R1-S2.4 + + + + + + This is configured with Junos_bgp resource module + + 2 + 5 + + + + 10 + + + + 20000000 + + + + + 11.11.11.11 + + set + + + + + 3 + + + + 15 + + + + + + + + + + 4294967290 + + 22 + + 2200 + + + + + + + + + + + + + + + + + + + + + + + + + 8000 + 8000 + + + 12000 + 12000 + + + + 1200 + + + 15 + + + + + + + + + md5 + + + + enable + + + + + internal + 12 + + + ebgp + + + + + voice + target:40:40 + + + + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_global.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_global.cfg new file mode 100644 index 00000000..c1d2042f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_global.cfg @@ -0,0 +1,22 @@ +description "This is configured with Junos_bgp resource module replace"; +preference 2; +hold-time 5; +advertise-inactive; +out-delay 10; +bgp-error-tolerance { + malformed-route-limit 40000000; +} +authentication-algorithm md5; +advertise-bgp-static { + policy static-to-bgp; +} +bfd-liveness-detection { + version automatic; + minimum-receive-interval 8; + multiplier 30; + no-adaptation; + transmit-interval { + minimum-interval 4; + } +} +egress-te-sid-stats; diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_global_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_global_config.cfg new file mode 100644 index 00000000..a8c11bc0 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_bgp_global_config.cfg @@ -0,0 +1,37 @@ + + + 18.4R1-S2.4 + + + + + This is configured with Junos_bgp resource module + + 2 + 5 + + + + 10 + + + + 30000000 + + md5 + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.json b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.json new file mode 100644 index 00000000..8a295996 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.json @@ -0,0 +1,25 @@ +{ + "interfaces": [ + { + "interface": [ + { + "name": { + "data": "ae11" + }, + "unit": [ + { + "name": { + "data": "0" + }, + "description": [ + { + "data": "Test" + } + ] + } + ] + } + ] + } + ] +} diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.set b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.set new file mode 100644 index 00000000..f67ea05d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.set @@ -0,0 +1,2 @@ +delete interfaces ae11 +set interfaces ae11 unit 0 description Test diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.text b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.text new file mode 100644 index 00000000..2f89ac2b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.text @@ -0,0 +1,8 @@ + +interfaces { + ae11 { + unit 0 { + description Test + } + } + } diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.xml b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.xml new file mode 100644 index 00000000..a0e8fe1b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_config.xml @@ -0,0 +1,9 @@ + + + ae11 + + 0 + Test + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_hostname_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_hostname_config.cfg new file mode 100644 index 00000000..1e6830e0 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_hostname_config.cfg @@ -0,0 +1,8 @@ + + + 18.4R1-S2.4 + + vsrx12 + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_interfaces.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_interfaces.cfg new file mode 100644 index 00000000..8a707327 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_interfaces.cfg @@ -0,0 +1,10 @@ +ge-0/0/0 { + description "Configured by Ansi-Team"; +} +fxp0 { + unit 0 { + family inet { + dhcp; + } + } +} diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_interfaces_config.xml b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_interfaces_config.xml new file mode 100644 index 00000000..26d323fc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_interfaces_config.xml @@ -0,0 +1,53 @@ + + + + + + ge-0/0/1 + Configured by Ansible + + 100m + 1024 + + 2000 + 2200 + + full-duplex + + 0 + + + access + + vlan100 + + + + + + + ge-0/0/2 + Configured by Ansible + 400 + 10m + 2048 + + 3000 + 3200 + + + 0 + + + trunk + + vlan200 + vlan300 + + + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_l2_interfaces.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_l2_interfaces.cfg new file mode 100644 index 00000000..3f39ed78 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_l2_interfaces.cfg @@ -0,0 +1,31 @@ +ge-0/0/0 { + description "Configured by Ansi-Team"; +} +ge-0/0/1 { + unit 0 { + family ethernet-switching { + interface-mode access; + vlan { + members vlan100; + } + } + } +} +ge-0/0/2 { + native-vlan-id 400; + unit 0 { + family ethernet-switching { + interface-mode trunk; + vlan { + members [ vlan200 vlan300 ]; + } + } + } +} +fxp0 { + unit 0 { + family inet { + dhcp; + } + } +} diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_l2_interfaces_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_l2_interfaces_config.cfg new file mode 100644 index 00000000..26d323fc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_l2_interfaces_config.cfg @@ -0,0 +1,53 @@ + + + + + + ge-0/0/1 + Configured by Ansible + + 100m + 1024 + + 2000 + 2200 + + full-duplex + + 0 + + + access + + vlan100 + + + + + + + ge-0/0/2 + Configured by Ansible + 400 + 10m + 2048 + + 3000 + 3200 + + + 0 + + + trunk + + vlan200 + vlan300 + + + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_l3_interfaces.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_l3_interfaces.cfg new file mode 100644 index 00000000..fe81e715 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_l3_interfaces.cfg @@ -0,0 +1,39 @@ +ge-0/0/0 { + description "Configured by Ansi-Team"; +} +ge-0/0/1 { + unit 0 { + family ethernet-switching { + interface-mode access; + vlan { + members vlan100; + } + } + } +} +ge-0/0/2 { + native-vlan-id 400; + unit 0 { + family ethernet-switching { + interface-mode trunk; + vlan { + members [ vlan200 vlan300 ]; + } + } + } +} +ge-1/0/0 { + unit 0 { + family inet { + address 100.64.0.1/10; + address 100.64.0.2/10; + } + } +} +fxp0 { + unit 0 { + family inet { + dhcp; + } + } +} diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_logging_global_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_logging_global_config.cfg new file mode 100644 index 00000000..e554b73a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_logging_global_config.cfg @@ -0,0 +1,66 @@ + + + 18.4R1-S2.4 + + + + vagrant + 2000 + super-user + + $6$QiBkxU5N$QY11GzNuFs1sfY0OAacyJ/0WFmP9ciovUAmM425yYAo9OjccxvjWlEZNo8SeqCQxYeM86cfd9V.N1RiiHW2zN0 + + ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key + + + + + + $1$nq.N1UsY$JxA/ESAj3KuXseXE597gg0 + + ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key + + + + + + + + 830 + + + + + vsrx + + + host111 + + any + + + ^set* + + 1231 + ftp + field + 11.1.1.11 + inst11 + + ^delete + ^prompt + + + + + + + + + https://ae1.juniper.net/junos/key_retrieval + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ntp_global_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ntp_global_config.cfg new file mode 100644 index 00000000..f99d998e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ntp_global_config.cfg @@ -0,0 +1,20 @@ + + + 18.4R1-S2.4 + + + + 3 + md5 + $9$GxDjqfT3CA0UjfzF6u0RhS + + + 4 + sha1 + $9$ZsUDk.mT3/toJGiHqQz + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospf_interfaces.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospf_interfaces.cfg new file mode 100644 index 00000000..0ec7941f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospf_interfaces.cfg @@ -0,0 +1,6 @@ +area 0.0.0.2 { + interface ge-0/0/2.0 { + metric 5; + priority 3; + } +} diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospf_interfaces_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospf_interfaces_config.cfg new file mode 100644 index 00000000..a3448104 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospf_interfaces_config.cfg @@ -0,0 +1,34 @@ + + + + + + + 0.0.0.10 + + 200 + + + so-0/0/0.0 + + 5 + 3 + + + + + 0.0.0.20 + + ge-1/1/0.0 + + + ge-2/2/0.0 + + + + + + 10.200.16.77 + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv2.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv2.cfg new file mode 100644 index 00000000..7df43d60 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv2.cfg @@ -0,0 +1,6 @@ +Sun Jun 14 12:10:47.455 UTC +router ospf 30 + area 100 + default-metric 10 + ! +! diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv2_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv2_config.cfg new file mode 100644 index 00000000..94784b87 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv2_config.cfg @@ -0,0 +1,214 @@ + + + + + + + 3000 + 4000 + 9 + + + 20000 + + 1200 + + + + + 10g + + + 0.0.0.100 + + 100 + + + 10.200.17.0/24 + + + 2000 + + + 10.200.15.0/24 + + + 2000 + + + so-0/0/0.0 + + + + + 1g + 5 + + + 10g + 40 + + + 5 + 3 + 2 + 2 + 4 + 2 + + + + 0.0.0.200 + + 100 + + + 10.400.17.0/24 + + + 2000 + + + so-0/0/1.0 + + + + + 1g + 5 + + + + + 20 + $9$.fz6pu1crvEc-w2gDjz36 + 2023-7-12.03:00:00 +0000 + + + 10 + $9$m5F/u0ISlMhSdsg4jiFn/ + 2023-7-12.03:00:00 +0000 + + + + + so-0/0/2.0 + + + 20 + $9$.fz6pu1crvEc-w2gDjz36 + 2023-7-12.03:00:00 +0000 + + + + + so-0/0/3.0 + + + 20 + $9$.fz6pu1crvEc-w2gDjz36 + 2023-7-12.03:00:00 +0000 + + + + + + + + + + 9.9.9.9 + + + + + + 4 + + + + + + + + + + + + + + 20 + + 99 + + 2000 + + + + + + + 23000 + 32000 + + + 20 + 32000 + + + + 2 + + + from-fib + + + + + 20 + + 99 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv3.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv3.cfg new file mode 100644 index 00000000..13241363 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv3.cfg @@ -0,0 +1,6 @@ +Sun Jun 14 12:10:47.455 UTC +router ospfv3 30 + area 100 + default-metric 10 + ! +! diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv3_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv3_config.cfg new file mode 100644 index 00000000..a3448104 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ospfv3_config.cfg @@ -0,0 +1,34 @@ + + + + + + + 0.0.0.10 + + 200 + + + so-0/0/0.0 + + 5 + 3 + + + + + 0.0.0.20 + + ge-1/1/0.0 + + + ge-2/2/0.0 + + + + + + 10.200.16.77 + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.10_count_2 b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.10_count_2 new file mode 100644 index 00000000..9fcc94a6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.10_count_2 @@ -0,0 +1,7 @@ +PING 10.10.10.10 (10.10.10.10): 56 data bytes +64 bytes from 10.10.10.10: icmp_seq=0 ttl=64 time=18.041 ms +64 bytes from 10.10.10.10: icmp_seq=1 ttl=64 time=15.710 ms + +--- 10.10.10.10 ping statistics --- +2 packets transmitted, 2 packets received, 0% packet loss +round-trip min/avg/max/stddev = 15.710/16.876/18.041/1.165 ms diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.11_count_5_size_512_interval_2 b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.11_count_5_size_512_interval_2 new file mode 100644 index 00000000..68d44d7f --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.11_count_5_size_512_interval_2 @@ -0,0 +1,11 @@ +PING 10.10.10.11 (10.10.10.11): 56 data bytes +64 bytes from 10.10.10.11: icmp_seq=0 ttl=64 time=18.041 ms +64 bytes from 10.10.10.11: icmp_seq=1 ttl=64 time=15.710 ms +64 bytes from 10.10.10.11: icmp_seq=0 ttl=64 time=16.051 ms +64 bytes from 10.10.10.11: icmp_seq=0 ttl=64 time=17.024 ms +64 bytes from 10.10.10.11: icmp_seq=0 ttl=64 time=20.090 ms + + +--- 10.10.10.11 ping statistics --- +5 packets transmitted, 5 packets received, 0% packet loss +round-trip min/avg/max/stddev = 18.710/17.876/20.041/2.165 ms diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.12_count_5_do-not-fragment_rapid b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.12_count_5_do-not-fragment_rapid new file mode 100644 index 00000000..26d6e8ee --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.12_count_5_do-not-fragment_rapid @@ -0,0 +1,5 @@ +PING 8.8.8.8 (8.8.8.8): 56 data bytes +!!!!! +--- 8.8.8.8 ping statistics --- +5 packets transmitted, 5 packets received, 0% packet loss +round-trip min/avg/max/stddev = 2.587/2.631/2.740/0.058 ms diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.20_count_4 b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.20_count_4 new file mode 100644 index 00000000..70cff3bc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_ping_ping_10.10.10.20_count_4 @@ -0,0 +1,4 @@ +PING 10.10.10.20 (10.10.10.20): 56 data bytes + +--- 10.10.10.20 ping statistics --- +4 packets transmitted, 0 packets received, 100% packet loss diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_prefix_lists_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_prefix_lists_config.cfg new file mode 100644 index 00000000..2a171419 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_prefix_lists_config.cfg @@ -0,0 +1,21 @@ + + + + 18.4R1-S2.4 + + + customer_64510 + + + customer_64500 + + + 172.16.1.16/28 + + + 172.16.1.32/28 + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_routing_instances_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_routing_instances_config.cfg new file mode 100644 index 00000000..afd7b91d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_routing_instances_config.cfg @@ -0,0 +1,32 @@ + + + 18.4R1-S2.4 + + + test-policy + + t1 + + + + + + + test-policy-1 + + t1 + + + + + + + + + forwardinst + Configured by Ansible Content Team + forwarding + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_routing_options_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_routing_options_config.cfg new file mode 100644 index 00000000..f852d95a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_routing_options_config.cfg @@ -0,0 +1,13 @@ + + + 18.4R1-S2.4 + + 12.12.12.12 + + 2 + 4 + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_security_policies_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_security_policies_config.cfg new file mode 100644 index 00000000..c61ab77a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_security_policies_config.cfg @@ -0,0 +1,172 @@ + + + + + + one + two + + test_policy_1 + + a1 + a3 + a2 + a4 + + + junos-dhcp-relay + junos-finger + authenticated-user + unknown-user + any + unauthenticated-user + test + + test_end_user_profile + + any + none + test + Enhanced_Web_Chat + any + none + Enhanced_Web_Collaboration + + + + + + + + + + + test_policy_2 + + a1 + a2 + junos-dhcp-relay + + + + test_dyn_app + + SECURITY-SSL-PROXY + + + + + + + one + three + + test_policy_3 + + any + any-ipv6 + any-ipv4 + any + any-ipv4 + any-ipv6 + any + + + + + + FWClient1 + FWClient2 + + + WEBAUTH + + Opera1 + test-client + test_ssl_term + + + + + WEBAUTH + + Opera1 + test-client + test_ssl_term + + test + + + + + + + + + gtp1 + sctp1 + test_idp + + SECURITY-SSL-PROXY + + + test + + + test_utm + test_icap + + test_traffic_control + + + + test + test_anti_malware + + + 64 + 64 + + + + + + test + test + + + + + + + + test_glob_1 + + a1 + a2 + junos-dhcp-relay + + + + + + + + + + test_glob_2 + + a1 + a2 + junos-dhcp-relay + + + + + + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_security_policies_global_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_security_policies_global_config.cfg new file mode 100644 index 00000000..d0b370f8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_security_policies_global_config.cfg @@ -0,0 +1,41 @@ + + + 18.4R1-S2.4 + + + + + + 10k + 3 + + /[A-Z]*/gm + + + lookup + + + + + + + + + + enable + + + + + + + + 10 + 10 + + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_security_zones_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_security_zones_config.cfg new file mode 100644 index 00000000..4c346a09 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_security_zones_config.cfg @@ -0,0 +1,137 @@ + + + + 18.4R1-S2.4 + + + + + test description + + + all + + + bgp + + + + all + + + dhcp + + + + + ge-0/0/1.0 + + + ge-0/0/2.0 + + test_screen + + + + test_sec_zone1 + +
+ test_adr1 + 10.0.0.0/24 + test desc +
+
+ test_adr2 + + 1.1.1.1 + + +
+
+ test_adr3 + + 10.2.0.1 + + 10.2.0.2 + + +
+
+ test_adr4 + + 10.3.0.1/24 + +
+
+ test_adr5 + 10.1.0.0/24 + test desc +
+ + test_adrset1 +
+ test_adr1 +
+
+ test_adr2 +
+
+ + test_adrset2 +
+ test_adr3 +
+
+ test_adr4 +
+
+ + test_adrset3 +
+ test_adr5 +
+ + test_adrset1 + + + test_adrset2 + + test description +
+
+ + test_profile + + + test description + + + + all + + + bgp + + + + all + + + dhcp + + + + + ge-0/0/3.0 + + + ge-0/0/4.0 + + test_screen + + +
+
+
+
+
diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_snmp_server_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_snmp_server_config.cfg new file mode 100644 index 00000000..01f821ea --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_snmp_server_config.cfg @@ -0,0 +1,38 @@ + + + 18.4R1-S2.4 + + + cl1 + + 192.16.1.0/24 + + + 192.16.2.0/24 + + + 11.11.11.11/32 + + + + + cl2 + + 192.16.4.0/24 + + + + + clv1 + + + clv2 + + + + + + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_vlans_config.cfg b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_vlans_config.cfg new file mode 100644 index 00000000..ff54e6e7 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/junos_vlans_config.cfg @@ -0,0 +1,11 @@ + + + 18.4R1-S2.4 + + + vlan1 + 1 + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/load_configuration_xml.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/load_configuration_xml.txt new file mode 100644 index 00000000..72ba03fc --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/load_configuration_xml.txt @@ -0,0 +1,6 @@ + + + + 0 + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_chassis_hardware_xml.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_chassis_hardware_xml.txt new file mode 100644 index 00000000..a0853b8c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_chassis_hardware_xml.txt @@ -0,0 +1,26 @@ + + + + Chassis + adc382ed18b0 + VSRX + + Midplane + + + System IO + + + Routing Engine + VSRX RE + + + FPC 0 + Virtual FPC + + + Power Supply 0 + + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_chassis_routing-engine_xml.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_chassis_routing-engine_xml.txt new file mode 100644 index 00000000..ccdcaca2 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_chassis_routing-engine_xml.txt @@ -0,0 +1,52 @@ + + + + 0 + master + master (default) + OK + 30 degrees C / 86 degrees F + 27 degrees C / 80 degrees F + 16349 MB + (16384 MB installed) + 16 + 3 + 0 + 5 + 1 + 92 + RE-S-EX9200-1800X4 + 0123456789 + 2017-04-27 12:25:03 PDT + 139 days, 3 hours, 12 minutes, 35 seconds + Router rebooted after a normal shutdown. + 0.03 + 0.06 + 0.02 + + + 1 + backup + backup (default) + OK + 30 degrees C / 86 degrees F + 27 degrees C / 80 degrees F + 16349 MB + (16384 MB installed) + 10 + 0 + 0 + 0 + 0 + 100 + RE-S-EX9200-1800X4 + 0123456789 + 2017-09-13 10:24:59 PDT + 5 hours, 12 minutes, 36 seconds + Router rebooted after a normal shutdown. + 0.00 + 0.00 + 0.00 + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_interfaces_details_xml.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_interfaces_details_xml.txt new file mode 100644 index 00000000..800cec05 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_interfaces_details_xml.txt @@ -0,0 +1,25 @@ + + + + em0 + up + up + 8 + 17 + 1 + Ethernet + Ethernet + 1514 + 1000mbps + Unspecified + Unspecified + 0 + 0 + 52:54:00:8a:af:30 + 52:54:00:8a:af:30 + Unspecified + Never + Never + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_system_memory_xml.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_system_memory_xml.txt new file mode 100644 index 00000000..1b4202ea --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_system_memory_xml.txt @@ -0,0 +1,20 @@ + + + + 983500 + 100% + 17844 + 1% + 67284 + 6% + 148268 + 15% + 288908 + 29% + 260500 + 26% + 200684 + 20% + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_system_storage_xml.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_system_storage_xml.txt new file mode 100644 index 00000000..abe6a033 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_system_storage_xml.txt @@ -0,0 +1,20 @@ + + + + /dev/vtbd0s1a + 1025132 + 583460 + 359664 + 62 + / + + + devfs + 2 + 2 + 0 + 100 + /dev + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_version_json.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_version_json.txt new file mode 100644 index 00000000..8209fc21 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_version_json.txt @@ -0,0 +1,42 @@ + +{ + "software-information" : [ + { + "host-name" : [ + { + "data" : "vsrx01" + } + ], + "product-model" : [ + { + "data" : "vSRX" + } + ], + "product-name" : [ + { + "data" : "vsrx" + } + ], + "junos-version" : [ + { + "data" : "15.1X49-D15.4" + } + ], + "package-information" : [ + { + "name" : [ + { + "data" : "junos" + } + ], + "comment" : [ + { + "data" : "JUNOS Software Release [15.1X49-D15.4]" + } + ] + } + ] + } + ] + } + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_version_text.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_version_text.txt new file mode 100644 index 00000000..ce2ded13 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_version_text.txt @@ -0,0 +1,8 @@ + + + Hostname: vsrx01 + Model: vSRX + Junos: 15.1X49-D15.4 + JUNOS Software Release [15.1X49-D15.4] + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_version_xml.txt b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_version_xml.txt new file mode 100644 index 00000000..b5656293 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/fixtures/show_version_xml.txt @@ -0,0 +1,12 @@ + + + vsrx01 + vSRX + vsrx + 15.1X49-D15.4 + + junos + JUNOS Software Release [15.1X49-D15.4] + + + diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/junos_module.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/junos_module.py new file mode 100644 index 00000000..b847e3ee --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/junos_module.py @@ -0,0 +1,104 @@ +# (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 . + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json +import os + + +try: + from lxml.etree import parse +except ImportError: + from xml.etree.ElementTree import parse + +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import ( + AnsibleExitJson, + AnsibleFailJson, + ModuleTestCase, +) + + +fixture_path = os.path.join(os.path.dirname(__file__), "fixtures") +fixture_data = {} + + +def load_fixture(name, content="xml"): + path = os.path.join(fixture_path, name) + if path in fixture_data: + return fixture_data[path] + + if content == "str": + with open(path) as f: + data = f.read() + try: + data = json.load(path) + except Exception: + pass + else: + try: + data = parse(path).getroot() + except Exception: + pass + + fixture_data[path] = data + return data + + +class TestJunosModule(ModuleTestCase): + def execute_module( + self, + failed=False, + changed=False, + commands=None, + sort=True, + defaults=False, + format="text", + ): + self.load_fixtures(commands, format, changed=changed) + + if failed: + result = self.failed() + self.assertTrue(result["failed"], result) + else: + result = self.changed(changed) + self.assertEqual(result["changed"], changed, result) + + 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, format=None, changed=None): + pass diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_bgp_address_family.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_bgp_address_family.py new file mode 100644 index 00000000..5a743bee --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_bgp_address_family.py @@ -0,0 +1,3090 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_bgp_address_family +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosBgp_address_familyModule(TestJunosModule): + module = junos_bgp_address_family + + def setUp(self): + super(TestJunosBgp_address_familyModule, self).setUp() + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.bgp_address_family.bgp_address_family.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.bgp_address_family.bgp_address_family.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.bgp_address_family.bgp_address_family." + "Bgp_address_familyFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosBgp_address_familyModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + if filename: + output = load_fixture(filename) + else: + output = load_fixture("junos_bgp_address_family_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def test_junos_bgp_address_family_parsed(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + 2 + 5 + + 10 + + + + 9.9.9.9 + + + + + + 4 + + + + + + + + + + + + + + 20 + + 99 + + 2000 + + + + + + + 23000 + 32000 + + + 20 + 32000 + + + + 2 + + + from-fib + + + + + 20 + + 99 + + + + + + + 3 + + + + + + + + + + + + + + + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2000, + "limit_threshold": 99, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "delay_route_advertisements": { + "max_delay_route_age": 20, + "max_delay_routing_uptime": 32000, + "min_delay_inbound_convergence": 32000, + "min_delay_routing_uptime": 23000, + }, + "graceful_restart_forwarding_state_bit": "from-fib", + "type": "any", + }, + { + "legacy_redirect_ip_action": { + "receive": True, + "send": True, + }, + "loops": 4, + "no_install": True, + "output_queue_priority_expedited": True, + "secondary_independent_resolution": True, + "type": "flow", + }, + { + "entropy_label": {"no_next_hop_validation": True}, + "explicit_null": {"connected_only": True}, + "per_group_label": True, + "per_prefix_label": True, + "prefix_limit": { + "forever": True, + "limit_threshold": 99, + "maximum": 20, + }, + "resolve_vpn": True, + "rib": "inet.3", + "route_refresh_priority_priority": 3, + "type": "labeled-unicast", + }, + { + "extended_nexthop": True, + "extended_nexthop_color": True, + "local_ipv4_address": "9.9.9.9", + "type": "unicast", + }, + ], + "afi": "inet", + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_bgp_address_family_groups_single_entry_parsed(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + internal + 12 + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "groups": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "name": "internal", + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_bgp_address_family_groups_multiple_entry_parsed(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + internal + 12 + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + + + external + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + 65438 + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "groups": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "name": "internal", + }, + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "name": "external", + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_bgp_address_family_groups_neighbors_single_entry_parsed( + self, + ): + parsed_str = """ + + + 18.4R1-S2.4 + + + + internal + 12 + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + + + external + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + 65438 + + 10.10.10.1 + + + + + 20 + + 98 + + + + + + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "groups": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "name": "internal", + }, + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "name": "external", + "neighbors": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "limit_threshold": 98, + "maximum": 20, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "neighbor_address": "10.10.10.1", + }, + ], + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_bgp_address_family_groups_neighbors_multiple_entry_parsed( + self, + ): + parsed_str = """ + + + 18.4R1-S2.4 + + + + internal + 12 + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + + + external + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + 65438 + + 10.10.10.1 + + + + + 20 + + 98 + + + + + + + + 10.10.10.10 + + + + + 20 + + 98 + + + + + + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "groups": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "name": "internal", + }, + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "name": "external", + "neighbors": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "limit_threshold": 98, + "maximum": 20, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "neighbor_address": "10.10.10.1", + }, + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "limit_threshold": 98, + "maximum": 20, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "neighbor_address": "10.10.10.10", + }, + ], + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_bgp_address_family_single_groups_neighbors_multiple_entry_parsed( + self, + ): + parsed_str = """ + + + 18.4R1-S2.4 + + + + external + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + 65438 + + 10.10.10.1 + + + + + 20 + + 98 + + + + + + + + 10.10.10.10 + + + + + 20 + + 98 + + + + + + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "groups": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "name": "external", + "neighbors": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "limit_threshold": 98, + "maximum": 20, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "neighbor_address": "10.10.10.1", + }, + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "limit_threshold": 98, + "maximum": 20, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "neighbor_address": "10.10.10.10", + }, + ], + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_bgp_address_family_single_groups_neighbors_single_entry_parsed( + self, + ): + parsed_str = """ + + + 18.4R1-S2.4 + + + + external + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + + + + + + + + 65438 + + 10.10.10.1 + + + + + 20 + + 98 + + + + + + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "groups": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + { + "af_type": [ + { + "type": "any", + "withdraw_priority_expedited": True, + }, + ], + "afi": "inet", + }, + ], + "name": "external", + "neighbors": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "limit_threshold": 98, + "maximum": 20, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "neighbor_address": "10.10.10.1", + }, + ], + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_bgp_address_family_single_groups_withdrow_priority_parser( + self, + ): + parsed_str = """ + + + 18.4R1-S2.4 + + + + external + + + + + 13 + + + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + 65438 + + 10.10.10.1 + + + + + 20 + + 98 + + + + + + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "groups": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + { + "af_type": [ + { + "type": "any", + "withdraw_priority_priority": 13, + }, + ], + "afi": "inet", + }, + ], + "name": "external", + "neighbors": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "limit_threshold": 98, + "maximum": 20, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "neighbor_address": "10.10.10.1", + }, + ], + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_bgp_address_family_single_groups_add_path_parser(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + external + + + + + 13 + + + + + + + + + + + 12 + cm123 + + + 12 + cm1123 + + + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + + 1 + 10 + customer65443 + + + + + + + + + + 65438 + + 10.10.10.1 + + + + + 20 + + 98 + + + + + + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "groups": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "add_path": { + "receive": True, + "send": { + "multipath": True, + "include_backup_path": 1, + "path_count": 10, + "prefix_policy": "customer65443", + "path_selection_mode": { + "all_paths": True, + "equal_cost_paths": True, + }, + }, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + { + "af_type": [ + { + "type": "any", + "withdraw_priority_priority": 13, + }, + { + "traffic_statistics": {"set": True}, + "type": "labeled-unicast", + }, + ], + "afi": "inet", + }, + { + "af_type": [ + { + "topology": [ + { + "community": ["cm123", "cm1123"], + "name": "12", + }, + ], + "type": "unicast", + }, + ], + "afi": "inet6", + }, + ], + "name": "external", + "neighbors": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "limit_threshold": 98, + "maximum": 20, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "neighbor_address": "10.10.10.1", + }, + ], + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_bgp_address_family_single_groups_add_path_nested_parser( + self, + ): + parsed_str = """ + + + 18.4R1-S2.4 + + + + external + + + + + 13 + + + + + 10 + + + 2 + + 12 + + + + + + + + + 12 + cm123 + + + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + + 1 + 10 + customer65443 + + + + + + + + + + 65438 + + 10.10.10.1 + + + + + 20 + + 98 + + + + + + + + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "groups": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "idle_timeout_value": 2001, + "limit_threshold": 98, + "maximum": 20, + }, + "damping": True, + "defer_initial_multipath_build": { + "maximum_delay": 2, + }, + "add_path": { + "receive": True, + "send": { + "multipath": True, + "include_backup_path": 1, + "path_count": 10, + "prefix_policy": "customer65443", + "path_selection_mode": { + "all_paths": True, + "equal_cost_paths": True, + }, + }, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + { + "af_type": [ + { + "type": "any", + "withdraw_priority_priority": 13, + }, + { + "traffic_statistics": { + "interval": 10, + "file": { + "files": 2, + "size": 12, + "world_readable": True, + "no_world_readable": True, + }, + }, + "type": "labeled-unicast", + }, + ], + "afi": "inet", + }, + { + "af_type": [ + { + "topology": [ + {"community": ["cm123"], "name": "12"}, + ], + "type": "unicast", + }, + ], + "afi": "inet6", + }, + ], + "name": "external", + "neighbors": [ + { + "address_family": [ + { + "af_type": [ + { + "accepted_prefix_limit": { + "limit_threshold": 98, + "maximum": 20, + }, + "type": "signaling", + }, + ], + "afi": "evpn", + }, + ], + "neighbor_address": "10.10.10.1", + }, + ], + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_bgp_address_family_config_001(self): + """ + This function generate the commands to configure attributes: + - af_type + - afi + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="evpn", + af_type=[dict(type="signaling", set=True)], + ), + ], + ), + state="merged", + ), + ) + + commands = [ + '' + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_002(self): + """ + This function generate the commands to configure attributes: + - accepted_prefix_limit + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="evpn", + af_type=[ + dict( + type="signaling", + accepted_prefix_limit=dict( + limit_threshold=98, + idle_timeout_value=2001, + maximum=20, + ), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "2098" + "2001" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_002_001(self): + """ + This function generate the commands to configure attributes: + - accepted_prefix_limit + forever: true + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="evpn", + af_type=[ + dict( + type="signaling", + accepted_prefix_limit=dict( + maximum=20, + limit_threshold=98, + forever=True, + ), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "2098" + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_003(self): + """ + This function generate the commands to configure attributes: + - add_path + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="evpn", + af_type=[ + dict( + type="signaling", + add_path=dict( + receive=True, + send=dict( + multipath=True, + include_backup_path=1, + path_count=10, + prefix_policy="customer65443", + path_selection_mode=dict( + all_paths=True, + equal_cost_paths=True, + ), + ), + ), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "10" + "1" + "" + "customer65443" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_004(self): + """ + This function generate the commands to configure attributes: + - aggregate_label + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="evpn", + af_type=[ + dict( + type="signaling", + aggregate_label=dict( + set=True, + community="cuastomerapn1", + ), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "cuastomerapn1" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_005(self): + """ + This function generate the commands to configure attributes: + - aigp + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet6", + af_type=[ + dict( + type="labeled-unicast", + aigp=dict(set=True), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_005_001(self): + """ + This function generate the commands to configure attributes: + - aigp + disable: true + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet6", + af_type=[ + dict( + type="labeled-unicast", + aigp=dict(disable=True), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_006(self): + """ + This function generate the commands to configure attributes: + - aigp + damping: true + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet6", + af_type=[ + dict(type="labeled-unicast", damping=True), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_007(self): + """ + This function generate the commands to configure attributes: + - aigp + defer_initial_multipath_build + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet6", + af_type=[ + dict( + type="labeled-unicast", + defer_initial_multipath_build=dict( + set=True, + ), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_007_001(self): + """ + This function generate the commands to configure attributes: + defer_initial_multipath_build + maximum_delay + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet6", + af_type=[ + dict( + type="labeled-unicast", + defer_initial_multipath_build=dict( + maximum_delay=1200, + ), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "1200" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_008(self): + """ + This function generate the commands to configure attributes: + - delay_route_advertisements + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet6", + af_type=[ + dict( + type="labeled-unicast", + delay_route_advertisements=dict( + set=True, + max_delay_route_age=12000, + max_delay_routing_uptime=12000, + min_delay_inbound_convergence=8000, + min_delay_routing_uptime=8000, + ), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "1200012000" + "8000" + "8000" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_009(self): + """ + This function generate the commands to configure attributes: + - entropy_label + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="labeled-unicast", + entropy_label=dict( + set=True, + no_next_hop_validation=True, + ), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_010(self): + """ + This function generate the commands to configure attributes: + - explicit_null + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="labeled-unicast", + explicit_null=dict( + set=True, + connected_only=True, + ), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_011(self): + """ + This function generate the commands to configure attributes: + - extended_nexthop + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict(type="unicast", extended_nexthop=True), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_012(self): + """ + This function generate the commands to configure attributes: + - extended_nexthop_color + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet6", + af_type=[ + dict( + type="unicast", + extended_nexthop_color=True, + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_013(self): + """ + This function generate the commands to configure attributes: + - graceful_restart_forwarding_state_bit: from-fib + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="unicast", + graceful_restart_forwarding_state_bit="from-fib", + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "from-fib" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_013_001(self): + """ + This function generate the commands to configure attributes: + - graceful_restart_forwarding_state_bit: set + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="unicast", + graceful_restart_forwarding_state_bit="set", + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "set" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_014(self): + """ + This function generate the commands to configure attributes: + - local_ipv4_address + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="unicast", + local_ipv4_address="11.11.11.11", + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "11.11.11.11" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_015(self): + """ + This function generate the commands to configure attributes: + - legacy_redirect_ip_action + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="flow", + legacy_redirect_ip_action=dict( + set=True, + send=True, + receive=True, + ), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_016(self): + """ + This function generate the commands to configure attributes: + - loops + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict(afi="inet", af_type=[dict(type="flow", loops=3)]), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "3" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_017(self): + """ + This function generate the commands to configure attributes: + - no_install + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[dict(type="flow", no_install=True)], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_018(self): + """ + This function generate the commands to configure attributes: + - no_validate + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[dict(type="flow", no_validate="sample")], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "sample" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_019(self): + """ + This function generate the commands to configure attributes: + - output_queue_priority_expedited + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="flow", + output_queue_priority_expedited=True, + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_020(self): + """ + This function generate the commands to configure attributes: + - output_queue_priority_priority + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="flow", + output_queue_priority_priority=15, + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "15" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_021(self): + """ + This function generate the commands to configure attributes: + - per_group_label + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet6", + af_type=[ + dict( + type="labeled-unicast", + per_group_label=True, + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_022(self): + """ + This function generate the commands to configure attributes: + - per_prefix_label + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="labeled-unicast", + per_prefix_label=True, + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_023(self): + """ + This function generate the commands to configure attributes: + - prefix_limit + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="labeled-unicast", + prefix_limit=dict( + maximum=4294967290, + teardown=True, + limit_threshold=22, + idle_timeout=True, + idle_timeout_value=2200, + ), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "4294967290222200" + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_023_001(self): + """ + This function generate the commands to configure attributes: + - prefix_limit + forever: true + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="labeled-unicast", + prefix_limit=dict( + teardown=True, + forever=True, + ), + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_024(self): + """ + This function generate the commands to configure attributes: + - resolve_vpn + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict(type="labeled-unicast", resolve_vpn=True), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_025(self): + """ + This function generate the commands to configure attributes: + - rib + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet6", + af_type=[ + dict(type="labeled-unicast", rib="inet.3"), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_026(self): + """ + This function generate the commands to configure attributes: + - ribgroup_name + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet6", + af_type=[ + dict( + type="labeled-unicast", + ribgroup_name="inet3", + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "inet3" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_027(self): + """ + This function generate the commands to configure attributes: + - route_refresh_priority_expedited + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet6", + af_type=[ + dict( + type="labeled-unicast", + route_refresh_priority_expedited=True, + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_028(self): + """ + This function generate the commands to configure attributes: + - route_refresh_priority_priority + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet6", + af_type=[ + dict( + type="labeled-unicast", + route_refresh_priority_priority=15, + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "15" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_029(self): + """ + This function generate the commands to configure attributes: + - secondary_independent_resolution + """ + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="flow", + secondary_independent_resolution=True, + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_030(self): + """ + This function generate the commands to configure attributes: + - groups: + address_family: + topology + """ + set_module_args( + dict( + config=dict( + groups=[ + dict( + name="ebgp", + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="unicast", + topology=[ + dict( + name="voice", + community=["target:40:40"], + ), + ], + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "ebgp" + "voice" + "target:40:40" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_deleted_031(self): + """ + This function generate the commands to to delete bgp_address family completely: + """ + set_module_args(dict(config=dict(), state="deleted")) + commands = [ + '' + "internal" + "ebgp" + '' + '' + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_deleted_032(self): + """ + This function generate the commands to to delete bgp_address family completely: + """ + set_module_args( + dict( + config=dict( + groups=[ + dict( + name="ebgp", + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="unicast", + topology=[ + dict( + name="voice", + community=["target:40:40"], + ), + ], + ), + ], + ), + ], + ), + ], + ), + state="overridden", + ), + ) + commands = [ + '' + "internal" + '' + "ebgp" + '' + '' + "ebgp" + "voice" + "target:40:40" + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_address_family_config_033(self): + """ + This function generate the commands to configure attributes: + - groups: + address_family: + topology + """ + set_module_args( + dict( + config=dict( + groups=[ + dict( + name="ebgp", + neighbors=[ + dict( + neighbor_address="14.14.14.14", + address_family=[ + dict( + afi="inet", + af_type=[ + dict( + type="unicast", + no_install=True, + ), + ], + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "ebgp" + "14.14.14.14" + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + """ + def test_junos_bgp_address_family_merged_idempotent(self): + self.get_connection.return_value = load_fixture( + "junos_bgp_address_family_config.cfg" + ) + src = load_fixture("junos_bgp_address_family.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=dict( + address_family=[ + dict( + afi="evpn", + af_type=[dict(type="flow", damping=True)], + ) + ] + ), + state="merged", + ) + ) + self.execute_module(changed=False, commands=[]) + + def test_junos_bgp_group_address_family_add(self): + set_module_args( + dict( + config=dict( + groups=[ + dict( + name="external", + address_family=[ + dict( + afi="evpn", + af_type=[dict(type="flow", damping=True)], + ) + ], + ) + ], + address_family=[ + dict( + afi="evpn", + af_type=[dict(type="flow", damping=True)], + ) + ], + ), + state="merged", + ) + ) + commands = [ + '' + "external" + "" + "" + "" + "", + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_bgp_group_address_family_rep(self): + set_module_args( + dict( + config=dict( + groups=[ + dict( + name="external", + address_family=[ + dict( + afi="evpn", + af_type=[dict(type="flow", damping=True)], + ) + ], + ) + ], + address_family=[ + dict( + afi="evpn", + af_type=[dict(type="flow", damping=True)], + ) + ], + ), + state="replaced", + ) + ) + commands = [ + '' + "external" + "" + "" + "" + "", + '', + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_bgp_address_family_rep_idempotent(self): + self.get_connection.return_value = load_fixture( + "junos_bgp_address_family_config.cfg" + ) + src = load_fixture("junos_bgp_address_family.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=dict( + groups=[ + dict( + name="external", + address_family=[ + dict( + afi="evpn", + af_type=[dict(type="flow", damping=True)], + ) + ], + ) + ], + address_family=[ + dict( + afi="evpn", + af_type=[dict(type="flow", damping=True)], + ) + ], + ), + state="replaced", + ) + ) + + self.execute_module(changed=False, commands=[]) + """ diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_bgp_global.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_bgp_global.py new file mode 100644 index 00000000..f5d8dfcd --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_bgp_global.py @@ -0,0 +1,1190 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_bgp_global +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosBgp_globalModule(TestJunosModule): + module = junos_bgp_global + + def setUp(self): + super(TestJunosBgp_globalModule, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.bgp_global.bgp_global.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.bgp_global.bgp_global.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.bgp_global.bgp_global." + "Bgp_globalFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosBgp_globalModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + if filename: + output = load_fixture(filename) + else: + output = load_fixture("junos_bgp_global_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def test_junos_bgp_global_merged(self): + set_module_args( + dict( + config=dict( + damping=True, + description="This is configured with Junos_bgp resource module", + preference="2", + bfd_liveness_detection=dict( + minimum_receive_interval=4, + multiplier=10, + no_adaptation=True, + version="automatic", + ), + ), + state="merged", + ), + ) + commands = [ + '' + "This is configured with Junos_bgp resource module" + "2" + "4" + "10" + "automatic", + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merged_idempotent(self): + set_module_args( + dict( + config=dict( + accept_remote_nexthop=True, + advertise_from_main_vpn_tables=True, + advertise_inactive=True, + as_number="65432", + authentication_algorithm="md5", + bgp_error_tolerance=dict(malformed_route_limit=30000000), + damping=True, + description="This is configured with Junos_bgp resource module", + hold_time=5, + holddown_all_stale_labels=True, + log_updown=True, + no_advertise_peer_as=True, + no_aggregator_id=True, + out_delay=10, + preference="2", + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_bgp_global_replaced(self): + """ + :return: + """ + set_module_args( + dict( + config=dict( + accept_remote_nexthop=True, + advertise_from_main_vpn_tables=True, + advertise_inactive=True, + as_number="65432", + authentication_algorithm="md5", + bgp_error_tolerance=dict(malformed_route_limit=20000000), + damping=True, + description="This is configured with Junos_bgp resource module", + groups=[ + dict(name="internal", out_delay=22), + dict(name="external", out_delay=20), + ], + hold_time=4, + holddown_all_stale_labels=True, + log_updown=True, + keep="all", + mtu_discovery=True, + no_precision_timers=True, + no_advertise_peer_as=True, + no_aggregator_id=True, + out_delay=10, + preference="2", + ), + state="replaced", + ), + ) + + commands = [ + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + "" + "" + "" + "" + "md5" + "This is configured with Junos_bgp resource module" + "4all2" + "10" + "20000000" + "internal" + "22external" + "20", + '' + '' + "65432", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_replaced_idempotent(self): + set_module_args( + dict( + config=dict( + accept_remote_nexthop=True, + advertise_from_main_vpn_tables=True, + advertise_inactive=True, + as_number="65432", + authentication_algorithm="md5", + bgp_error_tolerance=dict(malformed_route_limit=30000000), + damping=True, + description="This is configured with Junos_bgp resource module", + hold_time=5, + holddown_all_stale_labels=True, + log_updown=True, + no_advertise_peer_as=True, + no_aggregator_id=True, + out_delay=10, + preference="2", + ), + state="replaced", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_bgp_global_rendered(self): + """ + :return: + """ + set_module_args( + dict( + config=dict( + description="This is configured with Junos_bgp resource module", + groups=[dict(name="internal", out_delay=22)], + hold_time=4, + holddown_all_stale_labels=True, + include_mp_next_hop=True, + log_updown=True, + loops=5, + keep="all", + mtu_discovery=True, + out_delay=10, + preference="2", + ), + state="rendered", + ), + ) + + rendered = ( + '' + "" + "" + "This is configured with Junos_bgp resource module" + "4all2" + "10" + "internal22" + "" + ) + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) + + def test_junos_bgp_global_rendered_empty(self): + """ + :return: + """ + set_module_args(dict(config=dict(description=""), state="rendered")) + rendered = "" + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) + + def test_junos_bgp_global_gathered(self): + """ + :return: + """ + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + gather_dict = { + "accept_remote_nexthop": True, + "advertise_from_main_vpn_tables": True, + "advertise_inactive": True, + "as_number": "65432", + "authentication_algorithm": "md5", + "bgp_error_tolerance": {"malformed_route_limit": "30000000"}, + "damping": True, + "description": "This is configured with Junos_bgp resource module", + "hold_time": "5", + "holddown_all_stale_labels": True, + "log_updown": True, + "no_advertise_peer_as": True, + "no_aggregator_id": True, + "out_delay": "10", + "preference": "2", + } + self.assertEqual(sorted(gather_dict), sorted(result["gathered"])) + + def test_junos_bgp_global_parsed(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + + This is configured with Junos_bgp resource module + + 2 + 5 + + + + 10 + + + + 30000000 + + md5 + + + + + + 172.16.17.0/24 + + + + 10.200.16.75 + + 65432 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "accept_remote_nexthop": "True", + "advertise_from_main_vpn_tables": "True", + "advertise_inactive": "True", + "as_number": "65534", + "authentication_algorithm": "md5", + "bgp_error_tolerance": {"malformed_route_limit": "30000000"}, + "damping": "True", + "description": "This is configured with Junos_bgp resource module", + "hold_time": "5", + "holddown_all_stale_labels": "True", + "log_updown": "true", + "no_advertise_peer_as": "true", + "no_aggregator_id": "true", + "out_delay": "10", + "preference": "2", + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_bgp_global_parsed_empty_running_config(self): + set_module_args(dict(running_config="", state="parsed")) + try: + self.execute_module(changed=False) + except Exception: + pass + + def test_junos_bgp_global_delete(self): + set_module_args(dict(config=dict(), state="deleted")) + + commands = [ + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + "", + '' + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_delete_purged(self): + set_module_args(dict(config=dict(), state="purged")) + + commands = [ + '', + '', + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merged_routing_options(self): + """ + configure routing-options attributes: + - loops + - as_number + - asdot_notation + """ + set_module_args( + dict( + config=dict(as_number="65432", loops=5, asdot_notation=True), + state="merged", + ), + ) + commands = [ + '' + "", + '' + "654325" + "", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merge_groups(self): + """ + description: configure groups attributes: + """ + set_module_args( + dict( + config=dict( + groups=[ + dict( + name="internal", + neighbors=[ + dict( + neighbor_address="11.11.11.11", + peer_as="65534", + out_delay=11, + accept_remote_nexthop=True, + ), + dict( + neighbor_address="11.11.11.12", + peer_as="65534", + out_delay=12, + accept_remote_nexthop=True, + ), + ], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "internal" + "11.11.11.11" + "65534" + "11" + "11.11.11.12" + "6553412" + "", + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merged_advertise_bgp_static(self): + """ + configure advertise_bgp_static attributes: + """ + set_module_args( + dict( + config=dict(advertise_bgp_static=dict(policy="static-to-bgp")), + state="merged", + ), + ) + commands = [ + '' + "static-to-bgp" + "" + "", + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merged_advertise_external(self): + """ + configure advertise_external attributes: + """ + set_module_args( + dict( + config=dict( + advertise_external=dict(set=True, conditional=True), + ), + state="merged", + ), + ) + commands = [ + '' + "" + "", + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merged_bfd_liveness_detection(self): + """ + configure bfd_liveness_detection attributes: + """ + set_module_args( + dict( + config=dict( + bfd_liveness_detection=dict( + minimum_receive_interval=8, + no_adaptation=True, + authentication=dict( + algorithm="keyed-md5", + key_chain="junos", + loose_check=True, + ), + detection_time=dict(threshold=1000000), + transmit_interval=dict( + minimum_interval=20, + threshold=100000, + ), + holddown_interval=20, + multiplier=20, + session_mode="multihop", + version="1", + ), + ), + state="merged", + ), + ) + commands = [ + '' + "" + "keyed-md5junos" + "" + "1000000" + "20" + "208" + "20" + "multihop" + "1" + "", + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merged_bgp_error_tolerance(self): + """ + configure bgp_error_tolerance attributes: + """ + set_module_args( + dict( + config=dict( + bgp_error_tolerance=dict( + set=True, + malformed_route_limit=10, + malformed_update_log_interval=15, + no_malformed_route_limit=True, + ), + ), + state="merged", + ), + ) + commands = [ + '' + "10" + "15" + "" + "", + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merged_bmp(self): + """ + configure bmp attributes: + """ + set_module_args( + dict( + config=dict( + bmp=dict( + monitor=True, + route_monitoring=dict( + none=True, + post_policy=True, + post_policy_exclude_non_eligible=True, + pre_policy=True, + post_policy_exclude_non_feasible=True, + ), + ), + ), + state="merged", + ), + ) + commands = [ + '' + "enable" + "" + "", + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merged_bmp_2(self): + """ + configure bmp attributes: + """ + set_module_args( + dict( + config=dict( + bmp=dict( + monitor=False, + route_monitoring=dict( + none=False, + post_policy=False, + post_policy_exclude_non_eligible=False, + pre_policy=False, + post_policy_exclude_non_feasible=False, + ), + ), + ), + state="merged", + ), + ) + commands = [ + '' + "disable" + "", + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merged_egress_te(self): + """ + configure egress_te attributes: + """ + set_module_args( + dict( + config=dict(egress_te=dict(set=True, backup_path="sample")), + state="merged", + ), + ) + commands = [ + '' + "sample" + "", + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merged_egress_te_backup_paths(self): + """ + configure egress_te_backup_paths attributes: + """ + set_module_args( + dict( + config=dict( + egress_te_backup_paths=dict( + templates=[ + dict( + path_name="temp", + ip_forward=dict(set=True, rti_name="sample"), + peers=["10.10.10.10", "11.11.11.11"], + remote_nexthop="11.1.1.1", + ), + ], + ), + ), + state="merged", + ), + ) + commands = [ + '' + "temp" + "10.10.10.1011.11.11.11" + "11.1.1.1" + "" + "", + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merged_groups_allow(self): + """ + configure allow attributes: + """ + set_module_args( + dict( + config=dict( + groups=[dict(name="internal", allow=["all", "1.1.1.0/24"])], + ), + state="merged", + ), + ) + commands = [ + '' + "internalall" + "1.1.1.0/24" + "", + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_merged_optimal_route_reflection(self): + """ + configure optimal_route_reflection attributes: + """ + set_module_args( + dict( + config=dict( + groups=[ + dict( + name="internal", + optimal_route_reflection=dict( + igp_backup="test_igp", + igp_primary="test_primary", + ), + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "internal" + "test_igptest_primary" + "" + "", + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_bgp_global_parsed_bgp_global(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + 10000 + + + + + + + + + + Config is updated with merged operation + + 3 + 15 + + + all + + + 20 + + + md5 + + + + enable + + + + + + + + + > + + + + est1 + + + + + + + est2 + + + + + + + + internal + 22 + + 11.11.11.1 + 65432 + + + + + + + 4294967291 + + + + + + + + + + 65534 + 5 + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + self.execute_module(changed=False) + + def test_junos_bgp_global_parsed_bgp_group_neighbors_list(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + + est2 + + + + 1000 + 1000 + 100 + 400 + + multihop + 1 + + + 10000 + 4294967285 + + + enable + + + + + $9$6HxBAtOrlMXNbp0MX + + 0.0.4.198 + + + + + + + + internal + 22 + + 11.11.11.1 + 65432 + + + 11.11.11.2 + 65432 + + + + 4294967291 + + + + art1 + + + + + + + + + + + + + + + 65534 + 5 + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + self.execute_module(changed=False) + + def test_junos_bgp_global_parsed_bgp_group_neighbors_list_2(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + from-fib + 1700 + 1500 + + + + + + + + + + + + art1 + art12 + + 65432 + + + + + ge-0/0/1.0 + 12 + + + 100 + + + + + temp_trace + 4294967100 + 3 + + + + 4byte-as + + + + + all + + + + state + + + + task + + + + update + + prefix + pol1 + + + + + 200 + + + + + traffic_temp + 20000 + 10 + + + + + + + + 500 + + + + + + + + + + + + + + + + 10 + + + 13 + 20 + + + + 14 + + + 15 + + + + + + + + + + + + + + + + internal + 22 + + 11.11.11.1 + 65432 + + + + 1000 + + 220000 + 2000 + + + 10000 + + + cisco + + keyed-md5 + + + + + + + 65534 + 5 + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + self.execute_module(changed=False) + + def test_junos_bgp_global_parsed_only_routing_options(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + 65534 + 5 + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + self.execute_module(changed=False) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_command.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_command.py new file mode 100644 index 00000000..5e066957 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_command.py @@ -0,0 +1,182 @@ +# (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 . + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +try: + from lxml.etree import fromstring +except ImportError: + from xml.etree.ElementTree import fromstring + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_command +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +RPC_CLI_MAP = {"get-software-information": "show version"} + + +class TestJunosCommandModule(TestJunosModule): + module = junos_command + + def setUp(self): + super(TestJunosCommandModule, self).setUp() + + self.mock_conn = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.Connection", + ) + self.conn = self.mock_conn.start() + + self.mock_netconf = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.NetconfConnection", + ) + self.netconf_conn = self.mock_netconf.start() + + self.mock_exec_rpc = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_command.exec_rpc", + ) + self.exec_rpc = self.mock_exec_rpc.start() + + self.mock_netconf_rpc = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf.NetconfConnection", + ) + self.netconf_rpc = self.mock_netconf_rpc.start() + + self.mock_get_connection = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_command.get_connection", + ) + self.get_connection = self.mock_get_connection.start() + + self.mock_get_capabilities = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_command.get_capabilities", + ) + self.get_capabilities = self.mock_get_capabilities.start() + self.get_capabilities.return_value = {"network_api": "netconf"} + + def tearDown(self): + super(TestJunosCommandModule, self).tearDown() + self.mock_conn.stop() + self.mock_netconf.stop() + self.mock_get_capabilities.stop() + self.mock_netconf_rpc.stop() + self.mock_exec_rpc.stop() + self.mock_get_connection.stop() + + def load_fixtures(self, commands=None, format="text", changed=False): + def load_from_file(*args, **kwargs): + element = fromstring(args[1]) + if element.text: + path = str(element.text) + else: + path = RPC_CLI_MAP[str(element.tag)] + + filename = path.replace(" ", "_") + filename = "%s_%s.txt" % (filename, format) + return load_fixture(filename) + + self.exec_rpc.side_effect = load_from_file + + def test_junos_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("Hostname:")) + + def test_junos_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("Hostname:")) + + def test_junos_command_wait_for(self): + wait_for = 'result[0] contains "Junos:"' + set_module_args(dict(commands=["show version"], wait_for=wait_for)) + self.execute_module() + + def test_junos_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.exec_rpc.call_count, 10) + + def test_junos_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.exec_rpc.call_count, 2) + + def test_junos_command_match_any(self): + wait_for = [ + 'result[0] contains "Junos:"', + 'result[0] contains "test string"', + ] + set_module_args( + dict(commands=["show version"], wait_for=wait_for, match="any"), + ) + self.execute_module() + + def test_junos_command_match_all(self): + wait_for = [ + 'result[0] contains "Junos:"', + 'result[0] contains "JUNOS Software Release"', + ] + set_module_args( + dict(commands=["show version"], wait_for=wait_for, match="all"), + ) + self.execute_module() + + def test_junos_command_match_all_failure(self): + wait_for = [ + 'result[0] contains "Junos:"', + '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_junos_command_simple_json(self): + set_module_args(dict(commands=["show version"], display="json")) + result = self.execute_module(format="json") + self.assertEqual(len(result["stdout"]), 1) + self.assertTrue("software-information" in result["stdout"][0]) + + def test_junos_command_simple_rpc_text(self): + set_module_args( + dict(rpcs=["get-software-information"], display="text"), + ) + result = self.execute_module(format="text") + self.assertEqual(len(result["stdout"]), 1) + self.assertTrue(result["stdout"][0].startswith("Hostname:")) + + def test_junos_command_simple_rpc_json(self): + set_module_args( + dict(rpcs=["get-software-information"], display="json"), + ) + result = self.execute_module(format="json") + self.assertEqual(len(result["stdout"]), 1) + self.assertTrue("software-information" in result["stdout"][0]) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_config.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_config.py new file mode 100644 index 00000000..e24a56c4 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_config.py @@ -0,0 +1,237 @@ +# +# (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 . + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible.module_utils._text import to_text + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_config +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosConfigModule(TestJunosModule): + module = junos_config + + def setUp(self): + super(TestJunosConfigModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_config.get_configuration", + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_config.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_load_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_config.load_configuration", + ) + self.load_configuration = self.mock_load_configuration.start() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_config.commit_configuration", + ) + self.commit_configuration = self.mock_commit_configuration.start() + + self.mock_get_diff = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_config.get_diff", + ) + self.get_diff = self.mock_get_diff.start() + + self.mock_conn = patch("ansible.module_utils.connection.Connection") + self.conn = self.mock_conn.start() + + self.mock_netconf = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.NetconfConnection", + ) + self.netconf_conn = self.mock_netconf.start() + + self.mock_exec_rpc = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_config.exec_rpc", + ) + self.exec_rpc = self.mock_exec_rpc.start() + + self.mock_netconf_rpc = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf.NetconfConnection", + ) + self.netconf_rpc = self.mock_netconf_rpc.start() + + def tearDown(self): + super(TestJunosConfigModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_get_diff.stop() + self.load_configuration.stop() + self.mock_conn.stop() + self.mock_netconf.stop() + self.mock_exec_rpc.stop() + self.mock_netconf_rpc.stop() + + def load_fixtures(self, commands=None, format="text", changed=False): + self.get_config.return_value = load_fixture( + "get_configuration_rpc_reply.txt", + ) + if changed: + self.load_config.return_value = load_fixture( + "get_configuration_rpc_reply_diff.txt", + ) + else: + self.load_config.return_value = None + + def test_junos_config_unchanged(self): + src = load_fixture("junos_config.set", content="str") + set_module_args(dict(src=src)) + self.execute_module() + + def test_junos_config_src_set(self): + src = load_fixture("junos_config.set", content="str") + set_module_args(dict(src=src)) + self.execute_module(changed=True) + args, kwargs = self.load_config.call_args + self.assertEqual(kwargs["action"], "set") + self.assertEqual(kwargs["format"], "text") + + def test_junos_config_backup(self): + set_module_args(dict(backup=True)) + result = self.execute_module() + self.assertIn("__backup__", result) + + def test_junos_config_lines(self): + set_module_args( + dict( + lines=[ + "delete interfaces ae11", + "set interfaces ae11 unit 0 description Test", + ], + ), + ) + self.execute_module(changed=True) + args, kwargs = self.load_config.call_args + self.assertEqual( + args[1][0], + "set interfaces ae11 unit 0 description Test", + ) + self.assertEqual(kwargs["action"], "set") + self.assertEqual(kwargs["format"], "text") + + def test_junos_config_confirm(self): + src = load_fixture("junos_config.set", content="str") + set_module_args(dict(src=src, confirm=40)) + self.execute_module(changed=True) + args, kwargs = self.commit_configuration.call_args + self.assertEqual(kwargs["confirm_timeout"], to_text(40)) + + def test_junos_config_rollback(self): + rollback = 10 + set_module_args(dict(rollback=rollback)) + self.execute_module(changed=True) + self.assertEqual(self.get_diff.call_count, 1) + self.assertEqual(self.load_configuration.call_count, 1) + self.assertEqual(self.commit_configuration.call_count, 1) + load_configuration_args = self.load_configuration.call_args + self.assertEqual(rollback, load_configuration_args[1].get("rollback")) + + def test_junos_config_rollback_0(self): + rollback = 0 + set_module_args(dict(rollback=rollback)) + self.execute_module(changed=True) + self.assertEqual(self.get_diff.call_count, 1) + self.assertEqual(self.load_configuration.call_count, 1) + self.assertEqual(self.commit_configuration.call_count, 1) + load_configuration_args = self.load_configuration.call_args + self.assertEqual(rollback, load_configuration_args[1].get("rollback")) + + def test_junos_config_src_text(self): + src = load_fixture("junos_config.text", content="str") + set_module_args(dict(src=src)) + self.execute_module(changed=True) + args, kwargs = self.load_config.call_args + self.assertEqual(kwargs["action"], "merge") + self.assertEqual(kwargs["format"], "text") + + def test_junos_config_src_xml(self): + src = load_fixture("junos_config.xml", content="str") + set_module_args(dict(src=src)) + self.execute_module(changed=True) + args, kwargs = self.load_config.call_args + self.assertEqual(kwargs["action"], "merge") + self.assertEqual(kwargs["format"], "xml") + + def test_junos_config_src_json(self): + src = load_fixture("junos_config.json", content="str") + set_module_args(dict(src=src)) + self.execute_module(changed=True) + args, kwargs = self.load_config.call_args + self.assertEqual(kwargs["action"], "merge") + self.assertEqual(kwargs["format"], "json") + + def test_junos_config_update_override(self): + src = load_fixture("junos_config.xml", content="str") + set_module_args(dict(src=src, update="override")) + self.execute_module() + args, kwargs = self.load_config.call_args + self.assertEqual(kwargs["action"], "override") + self.assertEqual(kwargs["format"], "xml") + + def test_junos_config_update_replace(self): + src = load_fixture("junos_config.json", content="str") + set_module_args(dict(src=src, update="replace")) + self.execute_module() + args, kwargs = self.load_config.call_args + self.assertEqual(kwargs["action"], "replace") + self.assertEqual(kwargs["format"], "json") + + def test_junos_config_zeroize(self): + set_module_args(dict(zeroize="yes")) + self.execute_module(changed=True) + self.assertEqual(self.exec_rpc.call_count, 1) + + def test_junos_config_src_format_xml(self): + src = load_fixture("junos_config.json", content="str") + set_module_args(dict(src=src, src_format="xml")) + self.execute_module() + args, kwargs = self.load_config.call_args + self.assertEqual(kwargs["format"], "xml") + + def test_junos_config_confirm_commit(self): + set_module_args(dict(confirm_commit=True)) + self.execute_module(changed=True) + self.assertEqual(self.commit_configuration.call_count, 1) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_facts.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_facts.py new file mode 100644 index 00000000..154ea4f5 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_facts.py @@ -0,0 +1,171 @@ +# (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 . + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +try: + from lxml.etree import fromstring +except ImportError: + from xml.etree.ElementTree import fromstring + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_facts +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +RPC_CLI_MAP = { + "get-software-information": "show version", + "get-interface-information": "show interfaces details", + "get-system-memory-information": "show system memory", + "get-chassis-inventory": "show chassis hardware", + "get-route-engine-information": "show chassis routing-engine", + "get-system-storage": "show system storage", +} + + +class TestJunosCommandModule(TestJunosModule): + module = junos_facts + + def setUp(self): + super(TestJunosCommandModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.legacy.base.get_configuration", + ) + self.get_config = self.mock_get_config.start() + + self.mock_netconf = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.NetconfConnection", + ) + self.netconf_conn = self.mock_netconf.start() + + self.mock_exec_rpc = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.legacy.base.exec_rpc", + ) + self.exec_rpc = self.mock_exec_rpc.start() + + self.mock_netconf_rpc = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf.NetconfConnection", + ) + self.netconf_rpc = self.mock_netconf_rpc.start() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_capabilities = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.legacy.base.get_capabilities", + ) + self.get_capabilities = self.mock_get_capabilities.start() + + self.get_capabilities.return_value = { + "device_info": { + "network_os": "junos", + "network_os_hostname": "vsrx01", + "network_os_model": "vsrx", + "network_os_version": "17.3R1.10", + }, + "network_api": "netconf", + } + + def tearDown(self): + super(TestJunosCommandModule, self).tearDown() + self.mock_netconf.stop() + self.mock_exec_rpc.stop() + self.mock_netconf_rpc.stop() + self.mock_get_capabilities.stop() + self.mock_get_resource_connection.stop() + + def load_fixtures(self, commands=None, format="text", changed=False): + def load_from_file(*args, **kwargs): + element = fromstring(args[1]) + + if element.text: + path = str(element.text) + else: + path = RPC_CLI_MAP[str(element.tag)] + + filename = path.replace(" ", "_") + filename = "%s_%s.txt" % (filename, format) + return load_fixture(filename) + + self.exec_rpc.side_effect = load_from_file + + def test_junos_get_facts(self): + set_module_args(dict()) + result = self.execute_module(format="xml") + facts = result["ansible_facts"] + + self.assertEqual(facts["ansible_net_hostname"], "vsrx01") + self.assertEqual(facts["ansible_network_resources"], {}) + self.assertEqual(facts["ansible_net_system"], "junos") + self.assertTrue("ansible_net_model" in facts) + self.assertTrue("ansible_net_version" in facts) + self.assertTrue("ansible_network_resources" in facts) + self.assertTrue("ansible_net_serialnum" in facts) + + def test_junos_get_facts_subset_config_set(self): + self.get_config.return_value = load_fixture( + "get_configuration_rpc_reply.txt", + ) + set_module_args(dict(gather_subset="config", config_format="set")) + result = self.execute_module(format="xml") + facts = result["ansible_facts"] + + self.assertTrue("ansible_net_config" in facts) + self.assertTrue(facts["ansible_net_config"].startswith("set")) + self.assertEqual(facts["ansible_net_hostname"], "vsrx01") + self.assertTrue("ansible_net_interfaces" not in facts) + + def test_junos_get_facts_subset_config_json(self): + self.get_config.return_value = load_fixture( + "get_configuration_rpc_reply_json.txt", + ) + set_module_args(dict(gather_subset="config", config_format="json")) + result = self.execute_module(format="xml") + facts = result["ansible_facts"] + + self.assertTrue("ansible_net_config" in facts) + self.assertTrue("configuration" in facts["ansible_net_config"]) + self.assertEqual(facts["ansible_net_hostname"], "vsrx01") + self.assertTrue("ansible_net_interfaces" not in facts) + + def test_junos_get_facts_subset_list(self): + set_module_args(dict(gather_subset=["hardware", "interfaces"])) + result = self.execute_module(format="xml") + facts = result["ansible_facts"] + + self.assertTrue("ansible_net_config" not in facts) + self.assertEqual( + facts["ansible_net_interfaces"]["em0"]["oper-status"], + "up", + ) + self.assertEqual(facts["ansible_net_memfree_mb"], 200684) + + def test_junos_get_facts_wrong_subset(self): + set_module_args(dict(gather_subset=["hardware", "interfaces", "test"])) + result = self.execute_module(format="xml", failed=True) + + self.assertTrue(result["msg"].startswith("Subset must be one")) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_hostname.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_hostname.py new file mode 100644 index 00000000..8fe1931d --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_hostname.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_hostname +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosHostnameModule(TestJunosModule): + module = junos_hostname + + def setUp(self): + super(TestJunosHostnameModule, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.hostname.hostname.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.hostname.hostname.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.hostname.hostname." + "HostnameFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosHostnameModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + output = load_fixture("junos_hostname_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def test_junos_hostname_merged_01(self): + set_module_args(dict(config=dict(hostname="vsrx"), state="merged")) + result = self.execute_module(changed=True) + self.assertIn( + "vsrx", + str(result["commands"]), + ) + + def test_junos_hostname_parsed_01(self): + parsed_str = """ + + + 18.4R1-S2.4 + + vsrx + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = {"hostname": "vsrx"} + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_hostname_overridden_01(self): + set_module_args( + dict(config=dict(hostname="vsrx12"), state="overridden"), + ) + result = self.execute_module(changed=True) + self.assertIn( + "vsrx12", + str(result["commands"]), + ) + + def test_junos_hostname_gathered(self): + """ + :return: + """ + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + gathered_hostname = {"hostname": "vsrx10"} + self.assertEqual(sorted(gathered_hostname), sorted(result["gathered"])) + + def test_junos_hostname_rendered(self): + set_module_args(dict(config=dict(hostname="vsrx10"), state="rendered")) + rendered = ( + '' + "vsrx10" + ) + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) + + def test_junos_hostname_replaced(self): + set_module_args(dict(config=dict(hostname="vsrx12"), state="replaced")) + result = self.execute_module(changed=True) + self.assertIn( + "vsrx12", + str(result["commands"]), + ) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_interfaces.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_interfaces.py new file mode 100644 index 00000000..d2f41bf6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_interfaces.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_interfaces +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosInterfacesModule(TestJunosModule): + module = junos_interfaces + + def setUp(self): + super(TestJunosInterfacesModule, self).setUp() + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.interfaces.interfaces.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_validate_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils.validate_config", + ) + self.validate_config = self.mock_validate_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.interfaces.interfaces.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_get_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.interfaces.interfaces." + "InterfacesFacts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestJunosInterfacesModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_validate_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + + def load_fixtures(self, commands=None, format="text", changed=False): + self.get_config.return_value = load_fixture( + "junos_interfaces_config.xml", + ) + if changed: + self.load_config.return_value = load_fixture( + "get_configuration_rpc_reply_diff.txt", + ) + else: + self.load_config.return_value = None + + def test_junos_interfaces_merged(self): + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/1", + description="This is configured with ansible resource module", + mtu=1024, + speed="100m", + ), + ], + state="merged", + ), + ) + commands = [ + '' + "ge-0/0/1This is configured with ansible resource module" + "100m1024", + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_interfaces_merged_idempotent(self): + self.get_config.return_value = load_fixture( + "junos_interfaces_config.xml", + ) + src = load_fixture("junos_interfaces.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/0", + description="Configured by Ansi-Team", + ), + ], + state="merged", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_junos_interfaces_replaced(self): + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/2", + description="This is configured with ansible", + mtu=1024, + speed="100m", + ), + ], + state="replaced", + ), + ) + result = self.execute_module(changed=True) + commands = [ + '' + "ge-0/0/2" + "This is configured with ansible" + "100m1024", + ] + + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_interfaces_replaced_idempotent(self): + self.get_config.return_value = load_fixture( + "junos_interfaces_config.xml", + ) + src = load_fixture("junos_interfaces.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/0", + description="Configured by Ansi-Team", + ), + ], + state="replaced", + ), + ) + + self.execute_module(changed=False, commands=[]) + + def test_junos_interfaces_overridden(self): + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/2", + description="This is configured with ansible", + mtu=1024, + speed="100m", + ), + ], + state="overridden", + ), + ) + commands = [ + '' + "ge-0/0/2" + "This is configured with ansible" + "100m1024", + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_interfaces_overridden_idempotent(self): + self.get_config.return_value = load_fixture( + "junos_interfaces_config.xml", + ) + src = load_fixture("junos_interfaces.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/0", + description="Configured by Ansi-Team", + ), + ], + state="overridden", + ), + ) + + self.execute_module(changed=False, commands=[]) + + def test_junos_interfaces_delete(self): + set_module_args(dict(config=[dict(name="ge-0/0/2")], state="deleted")) + + commands = [ + '', + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_interfaces_delete_idempotent(self): + set_module_args(dict(config=[dict(name="ge-0/0/4")], state="deleted")) + self.execute_module(changed=False, commands=[]) + + def test_junos_interfaces_rendered(self): + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/1", + description="This is configured with ansible resource module", + mtu=1024, + speed="100m", + ), + ], + state="rendered", + ), + ) + commands = [ + '' + "ge-0/0/1" + "This is configured with ansible resource module" + "100m" + "1024" + "", + ] + self.execute_module(changed=False, commands=commands) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_l2_interfaces.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_l2_interfaces.py new file mode 100644 index 00000000..06d61143 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_l2_interfaces.py @@ -0,0 +1,316 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_l2_interfaces +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosL2InterfacesModule(TestJunosModule): + module = junos_l2_interfaces + + def setUp(self): + super(TestJunosL2InterfacesModule, self).setUp() + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.l2_interfaces.l2_interfaces.load_config", + ) + self.load_config = self.mock_load_config.start() + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.l2_interfaces.l2_interfaces.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.l2_interfaces.l2_interfaces." + "L2_interfacesFacts.get_device_data", + ) + self.mock_get_res_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.l2_interfaces.l2_interfaces." + "L2_interfaces.get_res_config", + ) + self.get_res_config = self.mock_get_res_config.start() + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosL2InterfacesModule, self).tearDown() + self.mock_load_config.stop() + self.mock_get_res_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + if filename: + output = load_fixture(filename) + else: + output = load_fixture("junos_l2_interfaces_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def test_junos_l2_interfaces_merged(self): + set_module_args( + dict( + config=[dict(name="ge-0/0/1", access=dict(vlan="vlan100"))], + state="merged", + ), + ) + commands = [ + '' + "ge-0/0/10" + "access" + "vlan100" + "" + "", + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_l2_interfaces_gathered(self): + """ + :return: + """ + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + with open("gathered_outout.py", "w") as file: + file.write(str(result["gathered"])) + gather_list = [ + {"access": {"vlan": "vlan100"}, "name": "ge-0/0/1", "unit": 0, "enhanced_layer": True}, + { + "name": "ge-0/0/2", + "trunk": {"allowed_vlans": ["vlan200", "vlan300"], "native_vlan": "400"}, + "unit": 0, + "enhanced_layer": True, + }, + ] + self.assertEqual(gather_list, result["gathered"]) + + def test_junos_l2_interfaces_merged_idempotent(self): + set_module_args( + dict( + config=[ + dict(name="ge-0/0/1", access=dict(vlan="vlan100"), unit=0, enhanced_layer=True), + dict( + name="ge-0/0/2", + trunk=dict(allowed_vlans=["vlan200", "vlan300"], native_vlan="400"), + unit=0, + enhanced_layer=True, + ), + ], + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_l2_interfaces_replaced(self): + set_module_args( + dict( + config=[dict(name="ge-0/0/1", access=dict(vlan="vlan100"), enhanced_layer=False)], + state="replaced", + ), + ) + commands = [ + '' + "ge-0/0/10" + "access" + "vlan100" + "", + ] + result = self.execute_module(changed=True) + + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_l2_interfaces_replaced_idempotent(self): + set_module_args( + dict( + config=[ + dict(name="ge-0/0/1", access=dict(vlan="vlan100"), unit=0, enhanced_layer=True), + dict( + name="ge-0/0/2", + trunk=dict(allowed_vlans=["vlan200", "vlan300"], native_vlan="400"), + unit=0, + enhanced_layer=True, + ), + ], + state="replaced", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_l2_interfaces_overridden(self): + set_module_args( + dict( + config=[dict(name="ge-0/0/1", access=dict(vlan="vlan100"), enhanced_layer=False)], + state="overridden", + ), + ) + commands = [ + '' + "ge-0/0/10" + "access" + "vlan100" + "", + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_l2_interfaces_overridden_idempotent(self): + set_module_args( + dict( + config=[ + dict(name="ge-0/0/1", access=dict(vlan="vlan100"), unit=0, enhanced_layer=True), + dict( + name="ge-0/0/2", + trunk=dict(allowed_vlans=["vlan200", "vlan300"], native_vlan="400"), + unit=0, + enhanced_layer=True, + ), + ], + state="overridden", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_l2_interfaces_delete(self): + self.get_res_config.return_value = load_fixture( + "junos_interfaces_config.xml", + ) + src = load_fixture("junos_l2_interfaces.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args(dict(config=[dict(name="ge-0/0/1")], state="deleted")) + commands = [ + '' + "ge-0/0/10" + '' + '' + '', + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_l2_interfaces_delete_idempotent(self): + set_module_args(dict(config=[dict(name="ge-0/0/3")], state="deleted")) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_l2_interfaces_parsed(self): + parsed_str = """ + + + + + ge-0/0/6 + + 0 + + + trunk + + vlan02 + + + + + + + + ge-0/0/37 + + 0 + + + + vlan31 + + + + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_list = [ + { + "name": "ge-0/0/6", + "trunk": { + "allowed_vlans": ["vlan02"], + }, + "unit": 0, + "enhanced_layer": True, + }, + { + "access": { + "vlan": "vlan31", + }, + "name": "ge-0/0/37", + "unit": 0, + "enhanced_layer": False, + }, + ] + self.assertEqual(result["parsed"], parsed_list) + + def test_junos_l2_interfaces_rendered(self): + set_module_args( + dict( + config=[dict(name="ge-0/0/4", access=dict(vlan="vlan100"))], + state="rendered", + ), + ) + rendered = ( + '' + "ge-0/0/40" + "access" + "vlan100" + "" + ) + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_l3_interfaces.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_l3_interfaces.py new file mode 100644 index 00000000..600861a6 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_l3_interfaces.py @@ -0,0 +1,256 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_l3_interfaces +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosL3InterfacesModule(TestJunosModule): + module = junos_l3_interfaces + + def setUp(self): + super(TestJunosL3InterfacesModule, self).setUp() + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.l3_interfaces.l3_interfaces.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_validate_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils.validate_config", + ) + self.validate_config = self.mock_validate_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.l3_interfaces.l3_interfaces.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_get_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.l3_interfaces.l3_interfaces." + "L3_interfacesFacts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestJunosL3InterfacesModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_validate_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + + def load_fixtures(self, commands=None, format="text", changed=False): + self.get_config.return_value = load_fixture( + "junos_interfaces_config.xml", + ) + if changed: + self.load_config.return_value = load_fixture( + "get_configuration_rpc_reply_diff.txt", + ) + else: + self.load_config.return_value = None + + def test_junos_l3_interfaces_merged(self): + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/1", + ipv4=[ + dict(address="100.64.0.1/10"), + dict(address="100.64.0.2/10"), + ], + ), + ], + state="merged", + ), + ) + commands = [ + '' + "ge-0/0/10" + "100.64.0.1/10" + "100.64.0.2/10" + "", + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_l3_interfaces_merged_idempotent(self): + self.get_config.return_value = load_fixture( + "junos_interfaces_config.xml", + ) + src = load_fixture("junos_l3_interfaces.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/1", + ipv4=[ + dict(address="100.64.0.1/10"), + dict(address="100.64.0.2/10"), + ], + ), + ], + state="merged", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_junos_l3_interfaces_replaced(self): + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/2", + ipv4=[ + dict(address="100.64.0.1/10"), + dict(address="100.64.0.2/10"), + ], + ), + ], + state="replaced", + ), + ) + commands = [ + '' + "ge-0/0/20" + "100.64.0.1/10" + "100.64.0.2/10" + "", + ] + result = self.execute_module(changed=True) + + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_l3_interfaces_replaced_idempotent(self): + self.get_config.return_value = load_fixture( + "junos_interfaces_config.xml", + ) + src = load_fixture("junos_l3_interfaces.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/1", + ipv4=[ + dict(address="100.64.0.1/10"), + dict(address="100.64.0.2/10"), + ], + ), + ], + state="merged", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_junos_l3_interfaces_overridden(self): + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/1", + ipv4=[ + dict(address="100.64.0.1/10"), + dict(address="100.64.0.2/10"), + ], + ), + ], + state="overridden", + ), + ) + commands = [ + '' + "ge-0/0/10" + "100.64.0.1/10" + "100.64.0.2/10" + "", + ] + result = self.execute_module(changed=True) + + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_l3_interfaces_overridden_idempotent(self): + self.get_config.return_value = load_fixture( + "junos_interfaces_config.xml", + ) + src = load_fixture("junos_l3_interfaces.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/1", + ipv4=[ + dict(address="100.64.0.1/10"), + dict(address="100.64.0.2/10"), + ], + ), + ], + state="overridden", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_junos_l3_interfaces_rendered(self): + set_module_args( + dict( + config=[ + dict( + name="ge-0/0/1", + ipv4=[ + dict(address="100.64.0.1/10"), + dict(address="100.64.0.2/10"), + ], + ), + ], + state="rendered", + ), + ) + commands = [ + '' + "ge-0/0/10" + "100.64.0.1/10" + "100.64.0.2/10" + "", + ] + self.execute_module(changed=False, commands=commands) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_logging_global.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_logging_global.py new file mode 100644 index 00000000..55ac5170 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_logging_global.py @@ -0,0 +1,1029 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_logging_global +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosLogging_globalModule(TestJunosModule): + module = junos_logging_global + + def setUp(self): + super(TestJunosLogging_globalModule, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.logging_global.logging_global.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.logging_global.logging_global.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.logging_global.logging_global." + "Logging_globalFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosLogging_globalModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + output = load_fixture("junos_logging_global_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def test_junos_logging_global_merged_archive_01(self): + set_module_args( + dict( + config=dict( + archive=dict( + set=True, + files=10, + file_size=65578, + no_binary_data=True, + no_world_readable=True, + ), + ), + state="merged", + ), + ) + commands = [ + '' + "10" + "65578" + "", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_logging_global_merged_console_02(self): + set_module_args( + dict( + config=dict( + console=dict( + any=dict(level="info"), + authorization=dict(level="any"), + change_log=dict(level="critical"), + ftp=dict(level="none"), + ), + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + "any", + str(result["commands"]), + ) + self.assertIn( + "authorization", + str(result["commands"]), + ) + self.assertIn( + "change-log", + str(result["commands"]), + ) + self.assertIn( + "ftp", + str(result["commands"]), + ) + + def test_junos_logging_global_merged_files_03(self): + set_module_args( + dict( + config=dict( + files=[dict(name="file101", allow_duplicates=True)], + ), + state="merged", + ), + ) + commands = [ + '' + "file101" + "", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_logging_global_merged_files_04(self): + set_module_args( + dict( + config=dict( + files=[ + dict( + name="file102", + allow_duplicates=True, + any=dict(level="any"), + structured_data=dict(set=True), + ), + dict( + name="file103", + archive=dict( + set=True, + no_binary_data=True, + files=10, + file_size=65578, + no_world_readable=True, + ), + explicit_priority=True, + match="^set*", + match_strings=["^delete", "^prompt"], + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "file102" + "any" + "file103" + "10" + "65578" + "^set*" + "^delete" + "^prompt", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_logging_global_merged_hosts_05(self): + set_module_args( + dict( + config=dict( + hosts=[ + dict( + name="host222", + exclude_hostname=True, + allow_duplicates=True, + ), + ], + ), + state="merged", + ), + ) + commands = [ + '' + "host222" + "", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_logging_global_merged_hosts_idempotent_06(self): + set_module_args( + dict( + config=dict( + hosts=[ + dict( + name="host111", + exclude_hostname=True, + allow_duplicates=True, + any=dict(level="any"), + structured_data=dict(set=True, brief=True), + facility_override="ftp", + log_prefix="field", + match="^set*", + match_strings=["^delete", "^prompt"], + port=1231, + routing_instance="inst11", + source_address="11.11.11.11", + ), + ], + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_logging_global_merged_07(self): + set_module_args( + dict( + config=dict( + allow_duplicates=True, + routing_instance="inst11", + log_rotate_frequency=45, + source_address="33.33.33.33", + time_format=dict(millisecond=True, year=True), + ), + state="merged", + ), + ) + commands = [ + '' + "45" + "inst1133.33.33.33" + "", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_logging_global_merged_user_08(self): + set_module_args( + dict( + config=dict( + users=[ + dict(name="user1", allow_duplicates=True), + dict( + name="user2", + allow_duplicates=True, + any=dict(level="any"), + user=dict(level="info"), + ), + ], + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + "user1", + str(result["commands"]), + ) + self.assertIn( + "user2", + str(result["commands"]), + ) + self.assertIn( + "any", + str(result["commands"]), + ) + + def test_junos_logging_global_replaced_user_09(self): + set_module_args( + dict( + config=dict( + users=[ + dict(name="user1", allow_duplicates=True), + dict( + name="user2", + allow_duplicates=True, + any=dict(level="any"), + user=dict(level="info"), + ), + ], + ), + state="replaced", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + '', + str(result["commands"]), + ) + self.assertIn( + 'user1', + str(result["commands"]), + ) + self.assertIn( + "user2", + str(result["commands"]), + ) + self.assertIn( + "", + str(result["commands"]), + ) + + def test_junos_logging_global_overridden_user_10(self): + set_module_args( + dict( + config=dict( + users=[ + dict(name="user1", allow_duplicates=True), + dict( + name="user2", + allow_duplicates=True, + any=dict(level="any"), + user=dict(level="info"), + ), + ], + ), + state="overridden", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + '', + str(result["commands"]), + ) + self.assertIn( + 'user1', + str(result["commands"]), + ) + self.assertIn( + "user2", + str(result["commands"]), + ) + + def test_junos_logging_global_deleted_user_11(self): + set_module_args(dict(config=dict(), state="deleted")) + commands = [ + '' + '', + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_logging_global_rendered_12(self): + set_module_args( + dict( + config=dict( + archive=dict( + set=True, + files=10, + file_size=65578, + no_binary_data=True, + no_world_readable=True, + ), + ), + state="rendered", + ), + ) + rendered = ( + '' + "10" + "65578" + ) + result = self.execute_module(changed=False) + + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) + + def test_junos_logging_global_parsed_13(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + 65578 + 10 + + + + + user1 + + + + user2 + + any + + + + user + + + + + + host111 + + any + + + ^set* + + 1231 + ftp + field + 11.1.1.11 + inst11 + + ^delete + ^prompt + + + + + + + file101 + + + + file102 + + any + + + + + + + + file103 + ^set* + + 65578 + 10 + + + + + ^delete + ^prompt + + + any + + + + authorization + + + + ftp + + + + change-log + + + + + + + 33.33.33.33 + inst11 + 45 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "allow_duplicates": True, + "archive": { + "file_size": 65578, + "files": 10, + "no_binary_data": True, + "no_world_readable": True, + }, + "console": { + "any": {"level": "info"}, + "authorization": {"level": "any"}, + "change_log": {"level": "critical"}, + "ftp": {"level": "none"}, + }, + "files": [ + {"allow_duplicates": True, "name": "file101"}, + { + "allow_duplicates": True, + "any": {"level": "any"}, + "name": "file102", + "structured_data": {"set": True}, + }, + { + "archive": { + "file_size": 65578, + "files": 10, + "no_binary_data": True, + "no_world_readable": True, + }, + "explicit_priority": True, + "match": "^set*", + "match_strings": ["^delete", "^prompt"], + "name": "file103", + }, + ], + "hosts": [ + { + "allow_duplicates": True, + "any": {"level": "any"}, + "exclude_hostname": True, + "facility_override": "ftp", + "log_prefix": "field", + "match": "^set*", + "match_strings": ["^delete", "^prompt"], + "name": "host111", + "port": 1231, + "routing_instance": "inst11", + "source_address": "11.1.1.11", + "structured_data": {"brief": True}, + }, + ], + "log_rotate_frequency": 45, + "routing_instance": "inst11", + "source_address": "33.33.33.33", + "time_format": {"millisecond": True, "year": True}, + "users": [ + {"allow_duplicates": True, "name": "user1"}, + { + "allow_duplicates": True, + "any": {"level": "any"}, + "name": "user2", + "user": {"level": "info"}, + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_logging_global_gathered_14(self): + """ + :return: + """ + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + gather_list = { + "hosts": [ + { + "name": "host111", + "allow_duplicates": True, + "any": {"level": "any"}, + "exclude_hostname": True, + "facility_override": "ftp", + "log_prefix": "field", + "match": "^set*", + "match_strings": ["^delete", "^prompt"], + "port": 1231, + "routing_instance": "inst11", + "source_address": "11.1.1.11", + "structured_data": {"brief": True}, + }, + ], + } + self.assertEqual(sorted(gather_list), sorted(result["gathered"])) + + def test_junos_logging_global_parsed_15(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + 65578 + 10 + + + + + user1 + + + + user2 + + any + + + + user + + + + + + host111 + + any + + + ^set* + + 1231 + ftp + field + 11.1.1.11 + inst11 + + ^delete + ^prompt + + + + + + + file101 + + + www.antsiblr.com + + + + file102 + + any + + + + + + + + file103 + ^set* + + 65578 + 10 + + + + + ^delete + ^prompt + + + any + + + + authorization + + + + ftp + + + + change-log + + + + + 33.33.33.33 + inst11 + 45 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "allow_duplicates": True, + "archive": { + "file_size": 65578, + "files": 10, + "no_binary_data": True, + "no_world_readable": True, + }, + "console": { + "any": {"level": "info"}, + "authorization": {"level": "any"}, + "change_log": {"level": "critical"}, + "ftp": {"level": "none"}, + }, + "files": [ + { + "allow_duplicates": True, + "name": "file101", + "archive_sites": ["www.antsiblr.com"], + }, + { + "allow_duplicates": True, + "any": {"level": "any"}, + "name": "file102", + "structured_data": {"set": True}, + }, + { + "archive": { + "file_size": 65578, + "files": 10, + "binary_data": True, + "world_readable": True, + }, + "explicit_priority": True, + "match": "^set*", + "match_strings": ["^delete", "^prompt"], + "name": "file103", + }, + ], + "hosts": [ + { + "allow_duplicates": True, + "any": {"level": "any"}, + "exclude_hostname": True, + "facility_override": "ftp", + "log_prefix": "field", + "match": "^set*", + "match_strings": ["^delete", "^prompt"], + "name": "host111", + "port": 1231, + "routing_instance": "inst11", + "source_address": "11.1.1.11", + "structured_data": {"brief": True}, + }, + ], + "log_rotate_frequency": 45, + "routing_instance": "inst11", + "source_address": "33.33.33.33", + "time_format": {"set": True}, + "users": [ + {"allow_duplicates": True, "name": "user1"}, + { + "allow_duplicates": True, + "any": {"level": "any"}, + "name": "user2", + "user": {"level": "info"}, + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_logging_global_parsed_16(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + 65578 + 10 + + + + + user1 + + ^delete + ^prompt + + + user2 + + any + + + + user + + + + + + host111 + + any + + + ^set* + + 1231 + ftp + field + 11.1.1.11 + inst11 + + ^delete + ^prompt + + + + + + + file101 + + + www.antsiblr.com + www.antsiblr2.com + + + any + + + + authorization + + + + + + + + any + + + + authorization + + + + ftp + + + + change-log + + + + + 33.33.33.33 + inst11 + 45 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "allow_duplicates": True, + "archive": { + "file_size": 65578, + "files": 10, + "no_binary_data": True, + "no_world_readable": True, + }, + "console": { + "any": {"level": "info"}, + "authorization": {"level": "any"}, + "change_log": {"level": "critical"}, + "ftp": {"level": "none"}, + }, + "files": [ + { + "allow_duplicates": True, + "name": "file101", + "archive_sites": ["www.antsiblr.com", "www.antsiblr2.com"], + "any": {"level": "any"}, + "authorization": {"level": "any"}, + "structured_data": {"brief": True}, + }, + ], + "hosts": [ + { + "allow_duplicates": True, + "any": {"level": "any"}, + "exclude_hostname": True, + "facility_override": "ftp", + "log_prefix": "field", + "match": "^set*", + "match_strings": ["^delete", "^prompt"], + "name": "host111", + "port": 1231, + "routing_instance": "inst11", + "source_address": "11.1.1.11", + "structured_data": {"brief": True}, + }, + ], + "log_rotate_frequency": 45, + "routing_instance": "inst11", + "source_address": "33.33.33.33", + "time_format": {"set": True}, + "users": [ + { + "allow_duplicates": True, + "name": "user1", + "match_strings": ["^delete", "^prompt"], + }, + { + "allow_duplicates": True, + "any": {"level": "any"}, + "name": "user2", + "user": {"level": "info"}, + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_logging_global_parsed_17(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + user1 + ^set* + ^delete + + user + + + + + host111 + + any + + + + authorization + + + ^delete + + + + + file101 + ^delete + + + www.antsiblr.com + + + www.antsiblr2.com + + + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "files": [ + { + "allow_duplicates": True, + "name": "file101", + "archive": { + "archive_sites": [ + "www.antsiblr.com", + "www.antsiblr2.com", + ], + }, + "any": {"level": "any"}, + "authorization": {"level": "any"}, + "structured_data": {"brief": True}, + }, + ], + "hosts": [ + { + "any": {"level": "any"}, + "authorization": {"level": "any"}, + "match_strings": ["^delete"], + "name": "host111", + "structured_data": {"set": True}, + }, + ], + "users": [ + { + "name": "user1", + "user": {"level": "info"}, + "match": "^set*", + "match_strings": ["^delete"], + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_netconf.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_netconf.py new file mode 100644 index 00000000..70e4fe0b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_netconf.py @@ -0,0 +1,131 @@ +# (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 . + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_netconf +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule + + +class TestJunosCommandModule(TestJunosModule): + module = junos_netconf + + def setUp(self): + super(TestJunosCommandModule, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_conn = patch("ansible.module_utils.connection.Connection") + self.conn = self.mock_conn.start() + + self.mock_netconf = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.NetconfConnection", + ) + self.netconf_conn = self.mock_netconf.start() + + self.mock_netconf_rpc = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf.NetconfConnection", + ) + self.netconf_rpc = self.mock_netconf_rpc.start() + + self.mock_get_capabilities = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.get_capabilities", + ) + self.get_capabilities = self.mock_get_capabilities.start() + self.get_capabilities.return_value = {"network_api": "netconf"} + + def tearDown(self): + super(TestJunosCommandModule, self).tearDown() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_conn.stop() + self.mock_netconf.stop() + self.mock_netconf_rpc.stop() + self.mock_get_capabilities.stop() + + def test_junos_netconf_enable(self): + self.netconf_conn().get.return_value = "" + set_module_args(dict(state="present")) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["set system services netconf ssh port 830"], + ) + + def test_junos_netconf_disable(self): + out = """ + ssh { + port 830; + } + """ + self.netconf_conn().get.return_value = out + set_module_args(dict(state="absent")) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["delete system services netconf"], + ) + + def test_junos_netconf_port_change(self): + out = """ + ssh { + port 830; + } + """ + self.netconf_conn().get.return_value = out + set_module_args(dict(state="present", netconf_port=22)) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["set system services netconf ssh port 22"], + ) + + def test_junos_netconf_port_error(self): + out = """ + ssh { + port 22; + } + """ + self.netconf_conn().get.return_value = out + set_module_args(dict(state="present", netconf_port=0)) + result = self.execute_module(changed=True, failed=True) + self.assertEqual( + result["msg"], + "netconf_port must be between 1 and 65535", + ) + + def test_junos_netconf_config_error(self): + self.netconf_conn().get.return_value = None + set_module_args(dict(state="present")) + result = self.execute_module(failed=True) + self.assertEqual(result["msg"], "unable to retrieve current config") diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ntp_global.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ntp_global.py new file mode 100644 index 00000000..26836a7c --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ntp_global.py @@ -0,0 +1,718 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_ntp_global +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosNtp_globalModule(TestJunosModule): + module = junos_ntp_global + + def setUp(self): + super(TestJunosNtp_globalModule, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.ntp_global.ntp_global.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.ntp_global.ntp_global.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.ntp_global.ntp_global." + "Ntp_globalFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosNtp_globalModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + output = load_fixture("junos_ntp_global_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def test_junos_ntp_global_merged_01(self): + set_module_args( + dict( + config=dict( + boot_server="78.46.194.186", + broadcasts=[ + dict( + address="172.16.255.255", + key="50", + ttl=200, + version=3, + routing_instance_name="rt1", + ), + dict( + address="192.16.255.255", + key="50", + ttl=200, + version=3, + routing_instance_name="rt1", + ), + ], + broadcast_client=True, + interval_range=2, + multicast_client="224.0.0.1", + peers=[ + dict(peer="78.44.194.186"), + dict( + peer="172.44.194.186", + key_id="10000", + prefer=True, + version=3, + ), + ], + servers=[ + dict( + server="48.46.194.186", + key_id=34, + prefer=True, + version=2, + routing_instance="rt1", + ), + dict( + server="48.45.194.186", + key_id=34, + prefer=True, + version=2, + ), + ], + source_addresses=[ + dict( + source_address="172.45.194.186", + routing_instance="rt1", + ), + dict( + source_address="171.45.194.186", + routing_instance="rt2", + ), + ], + threshold=dict(action="accept", value=300), + trusted_keys=[dict(key_id=3000), dict(key_id=2000)], + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + "78.46.194.186", + str(result["commands"]), + ) + self.assertIn( + "172.16.255.25550", + str(result["commands"]), + ) + self.assertIn( + "rt1200", + str(result["commands"]), + ) + self.assertIn( + "3", + str(result["commands"]), + ) + self.assertIn( + "192.16.255.25550", + str(result["commands"]), + ) + + def test_junos_ntp_global_merged_02(self): + set_module_args( + dict( + config=dict( + boot_server="78.46.194.186", + authentication_keys=[ + dict(id="2", algorithm="md5", key="asdfghd"), + dict(id="5", algorithm="sha1", key="aasdad"), + ], + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + "2md5asdfghd", + str(result["commands"]), + ) + self.assertIn( + "5sha1aasdad", + str(result["commands"]), + ) + + def test_junos_ntp_global_parsed_01(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + 78.46.194.186 + + 2 + + + 78.44.194.186 + + + 172.44.194.186 + 10000 + 3 + + + + 48.46.194.186 + 34 + 2 + + rt1 + + + 48.45.194.186 + 34 + 2 + + + + 172.16.255.255 + rt1 + 50 + 3 + 200 + + + 192.16.255.255 + rt2 + 50 + 3 + 200 + + + +
224.0.0.1
+
+ 3000 + 2000 + + 300 + accept + + + 172.45.194.186 + rt1 + + + 171.45.194.186 + rt2 + +
+
+ + + fxp0 + + 0 + + + + + + + + + + + + rt1 + rt1 + + + rt2 + rt2 + + +
+
+ """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "boot_server": "78.46.194.186", + "broadcast_client": True, + "broadcasts": [ + { + "address": "172.16.255.255", + "key": "50", + "routing_instance_name": "rt1", + "ttl": 200, + "version": 3, + }, + { + "address": "192.16.255.255", + "key": "50", + "routing_instance_name": "rt2", + "ttl": 200, + "version": 3, + }, + ], + "interval_range": 2, + "multicast_client": "224.0.0.1", + "peers": [ + {"peer": "78.44.194.186"}, + { + "key_id": 10000, + "peer": "172.44.194.186", + "prefer": True, + "version": 3, + }, + ], + "servers": [ + { + "key_id": 34, + "prefer": True, + "routing_instance": "rt1", + "server": "48.46.194.186", + "version": 2, + }, + { + "key_id": 34, + "prefer": True, + "server": "48.45.194.186", + "version": 2, + }, + ], + "source_addresses": [ + { + "routing_instance": "rt1", + "source_address": "172.45.194.186", + }, + { + "routing_instance": "rt2", + "source_address": "171.45.194.186", + }, + ], + "threshold": {"action": "accept", "value": 300}, + "trusted_keys": [{"key_id": 2000}, {"key_id": 3000}], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_ntp_global_parsed_02(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + 78.46.194.186 + + 2 + + + 172.44.194.186 + 10000 + 3 + + + + 48.45.194.186 + 34 + 2 + + + + 192.16.255.255 + rt2 + 50 + 3 + 200 + + + +
224.0.0.1
+
+ 2000 + + 300 + accept + + + 171.45.194.186 + rt2 + +
+
+ + + rt1 + rt1 + + + rt2 + rt2 + + +
+
+ """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "boot_server": "78.46.194.186", + "broadcast_client": True, + "broadcasts": [ + { + "address": "192.16.255.255", + "key": "50", + "routing_instance_name": "rt2", + "ttl": 200, + "version": 3, + }, + ], + "interval_range": 2, + "multicast_client": "224.0.0.1", + "peers": [ + { + "key_id": 10000, + "peer": "172.44.194.186", + "prefer": True, + "version": 3, + }, + ], + "servers": [ + { + "key_id": 34, + "prefer": True, + "server": "48.45.194.186", + "version": 2, + }, + ], + "source_addresses": [ + {"routing_instance": "rt2", "source_address": "171.45.194.186"}, + ], + "threshold": {"action": "accept", "value": 300}, + "trusted_keys": [{"key_id": 2000}], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_ntp_global_parsed_03(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + 2 + md5 + $9$GxDjqfT3CA0UjfzF6u0RhS + + + 5 + sha1 + $9$ZsUDk.mT3/toJGiHqQz + + + + + + rt1 + rt1 + + + rt2 + rt2 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "authentication_keys": [ + { + "algorithm": "md5", + "id": 2, + "key": "$9$GxDjqfT3CA0UjfzF6u0RhS", + }, + { + "algorithm": "sha1", + "id": 5, + "key": "$9$ZsUDk.mT3/toJGiHqQz", + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_ntp_global_overridden_01(self): + set_module_args( + dict( + config=dict( + boot_server="78.46.194.186", + broadcasts=[ + dict( + address="172.16.255.255", + key="50", + ttl=200, + version=3, + routing_instance_name="rt1", + ), + dict( + address="192.16.255.255", + key="50", + ttl=200, + version=3, + routing_instance_name="rt1", + ), + ], + broadcast_client=True, + interval_range=2, + multicast_client="224.0.0.1", + peers=[ + dict(peer="78.44.194.186"), + dict( + peer="172.44.194.186", + key_id="10000", + prefer=True, + version=3, + ), + ], + servers=[ + dict( + server="48.46.194.186", + key_id=34, + prefer=True, + version=2, + routing_instance="rt1", + ), + dict( + server="48.45.194.186", + key_id=34, + prefer=True, + version=2, + ), + ], + source_addresses=[ + dict( + source_address="172.45.194.186", + routing_instance="rt1", + ), + dict( + source_address="171.45.194.186", + routing_instance="rt2", + ), + ], + threshold=dict(action="accept", value=300), + trusted_keys=[dict(key_id=3000), dict(key_id=2000)], + ), + state="overridden", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + "78.46.194.186", + str(result["commands"]), + ) + self.assertIn( + "172.16.255.25550", + str(result["commands"]), + ) + self.assertIn( + "rt1200", + str(result["commands"]), + ) + self.assertIn( + "3", + str(result["commands"]), + ) + self.assertIn( + "192.16.255.25550", + str(result["commands"]), + ) + + def test_junos_ntp_global_gathered(self): + """ + :return: + """ + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + gather_list = { + "authentication_keys": [ + { + "algorithm": "md5", + "id": 3, + "key": "$9$GxDjqfT3CA0UjfzF6u0RhS", + }, + { + "algorithm": "sha1", + "id": 4, + "key": "$9$ZsUDk.mT3/toJGiHqQz", + }, + ], + } + self.assertEqual(sorted(gather_list), sorted(result["gathered"])) + + def test_junos_ntp_global_rendered(self): + set_module_args( + dict( + config=dict( + boot_server="78.46.194.186", + authentication_keys=[ + dict(id="2", algorithm="md5", key="asdfghd"), + dict(id="5", algorithm="sha1", key="aasdad"), + ], + ), + state="rendered", + ), + ) + rendered = ( + '' + "2md5" + "asdfghd" + "5sha1aasdad" + "78.46.194.186" + ) + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) + + def test_junos_ntp_global_replaced_01(self): + set_module_args( + dict( + config=dict( + boot_server="78.46.194.186", + broadcasts=[ + dict( + address="172.16.255.255", + key="50", + ttl=200, + version=3, + routing_instance_name="rt1", + ), + dict( + address="192.16.255.255", + key="50", + ttl=200, + version=3, + routing_instance_name="rt1", + ), + ], + broadcast_client=True, + interval_range=2, + multicast_client="224.0.0.1", + peers=[ + dict(peer="78.44.194.186"), + dict( + peer="172.44.194.186", + key_id="10000", + prefer=True, + version=3, + ), + ], + servers=[ + dict( + server="48.46.194.186", + key_id=34, + prefer=True, + version=2, + routing_instance="rt1", + ), + dict( + server="48.45.194.186", + key_id=34, + prefer=True, + version=2, + ), + ], + source_addresses=[ + dict( + source_address="172.45.194.186", + routing_instance="rt1", + ), + dict( + source_address="171.45.194.186", + routing_instance="rt2", + ), + ], + threshold=dict(action="accept", value=300), + trusted_keys=[dict(key_id=3000), dict(key_id=2000)], + ), + state="replaced", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + "78.46.194.186", + str(result["commands"]), + ) + self.assertIn( + "172.16.255.25550", + str(result["commands"]), + ) + self.assertIn( + "rt1200", + str(result["commands"]), + ) + self.assertIn( + "3", + str(result["commands"]), + ) + self.assertIn( + "192.16.255.25550", + str(result["commands"]), + ) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ospf_interfaces.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ospf_interfaces.py new file mode 100644 index 00000000..39ea2b77 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ospf_interfaces.py @@ -0,0 +1,344 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import MagicMock, patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_ospf_interfaces +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosOspfv3Module(TestJunosModule): + module = junos_ospf_interfaces + + def setUp(self): + super(TestJunosOspfv3Module, self).setUp() + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.ospf_interfaces.ospf_interfaces.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_validate_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils.validate_config", + ) + self.validate_config = self.mock_validate_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.ospf_interfaces.ospf_interfaces.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_get_connection = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.ospf_interfaces.ospf_interfaces." + "Ospf_interfacesFacts.get_connection", + ) + self.get_connection = self.mock_get_connection.start() + + self.conn = self.get_connection() + self.conn.get = MagicMock() + + self.mock_get_xml_dict = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts." + "ospf_interfaces.ospf_interfaces.Ospf_interfacesFacts._get_xml_dict", + ) + self._get_xml_dict = self.mock_get_xml_dict.start() + + def tearDown(self): + super(TestJunosOspfv3Module, self).tearDown() + self.mock_get_connection.stop() + self.mock_load_config.stop() + self.mock_validate_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + + def load_fixtures(self, commands=None, format="text", changed=False): + self.get_connection.return_value = load_fixture( + "junos_ospf_interfaces_config.cfg", + ) + if changed: + self.load_config.return_value = load_fixture( + "get_configuration_rpc_reply_diff.txt", + ) + else: + self.load_config.return_value = None + + def test_junos_ospf_interfaces_merged(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + name="ge-0/0/2.0", + address_family=[ + dict( + afi="ipv4", + processes=dict( + area=dict(area_id="0.0.0.2"), + priority=3, + metric=5, + ), + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + '' + "0.0.0.2ge-0/0/2.0" + "35", + '' + "10.200.16.75", + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_ospf_interfaces_merged_idempotent(self): + self.get_connection.return_value = load_fixture( + "junos_ospf_interfaces_config.cfg", + ) + src = load_fixture("junos_ospf_interfaces.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.77", + name="so-0/0/0.0", + address_family=[ + dict( + afi="ipv4", + processes=dict( + area=dict(area_id="0.0.0.10"), + priority=3, + metric=5, + ), + ), + ], + ), + ], + state="merged", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_junos_ospf_interfaces_replaced(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + name="ge-0/0/2.0", + address_family=[ + dict( + afi="ipv4", + processes=dict( + area=dict(area_id="0.0.0.1"), + priority=6, + metric=7, + ), + ), + ], + ), + ], + state="replaced", + ), + ) + result = self.execute_module(changed=True) + commands = [ + '' + "0.0.0.1ge-0/0/2.0" + "67", + '' + "10.200.16.75", + ] + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_ospf_interfaces_replaced_idempotent(self): + self.get_connection.return_value = load_fixture( + "junos_ospf_interfaces_config.cfg", + ) + src = load_fixture("junos_ospf_interfaces.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + name="ge-0/0/2.0", + address_family=[ + dict( + afi="ipv4", + processes=dict( + area=dict(area_id="0.0.0.1"), + priority=6, + metric=7, + ), + ), + ], + ), + ], + state="replaced", + ), + ) + + self.execute_module(changed=False, commands=[]) + + def test_junos_ospf_interfaces_overridden(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + name="ge-0/0/2.0", + address_family=[ + dict( + afi="ipv4", + processes=dict( + area=dict(area_id="0.0.0.1"), + priority=6, + metric=7, + ), + ), + ], + ), + ], + state="overridden", + ), + ) + commands = [ + '' + "0.0.0.1ge-0/0/2.0" + "67", + '' + "10.200.16.75", + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_ospf_interfaces_overridden_idempotent(self): + self.get_connection.return_value = load_fixture( + "junos_ospf_interfaces_config.cfg", + ) + src = load_fixture("junos_ospf_interfaces.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + name="ge-0/0/2.0", + address_family=[ + dict( + afi="ipv4", + processes=dict( + area=dict(area_id="0.0.0.1"), + priority=6, + metric=7, + ), + ), + ], + ), + ], + state="overridden", + ), + ) + + self.execute_module(changed=False, commands=[]) + + def test_junos_ospf_interfaces_delete(self): + self.get_connection.return_value = load_fixture( + "junos_ospf_interfaces_config.cfg", + ) + src = load_fixture("junos_ospf_interfaces.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[dict(router_id="10.200.16.75", name="ge-0/0/2.0")], + state="deleted", + ), + ) + + commands = [ + '', + '', + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_ospf_interfaces_delete_idempotent(self): + set_module_args( + dict( + config=[dict(router_id="10.200.16.75", name="ge-0/0/2.0")], + state="deleted", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_junos_ospf_interfaces_rendered(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + name="ge-0/0/2.0", + address_family=[ + dict( + afi="ipv4", + processes=dict( + area=dict(area_id="0.0.0.1"), + priority=6, + metric=7, + ), + ), + ], + ), + ], + state="rendered", + ), + ) + commands = [ + '' + "0.0.0.1ge-0/0/2.0" + "67", + '' + "10.200.16.75", + ] + self.execute_module(changed=False, commands=commands) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ospfv2.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ospfv2.py new file mode 100644 index 00000000..3ec9f589 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ospfv2.py @@ -0,0 +1,811 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Red Hat +# GNU General Public License v2.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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_ospfv2 +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosOspfv2Module(TestJunosModule): + module = junos_ospfv2 + + def setUp(self): + super(TestJunosOspfv2Module, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.ospfv2.ospfv2.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.ospfv2.ospfv2.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.ospfv2.ospfv2." + "Ospfv2Facts.get_connection", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosOspfv2Module, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + output = load_fixture("junos_ospfv2_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def sorted_xml(self, xml_string): + temp = [] + index = 0 + while index < len(xml_string): + temp_line = "" + if xml_string[index] == "<": + while index < len(xml_string) and xml_string[index] != ">": + temp_line += xml_string[index] + index += 1 + temp_line += ">" + index += 1 + temp.append(temp_line) + else: + while index < len(xml_string) and xml_string[index] != "<": + temp_line += xml_string[index] + index += 1 + temp.append(temp_line) + return sorted(temp) + + def test_junos_ospfv2_merged(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + rfc1583compatibility="False", + external_preference=10, + overload=dict( + allow_route_leaking=True, + as_external=True, + stub_network=True, + timeout=1200, + ), + spf_options=dict( + delay=3000, + holddown=4000, + rapid_runs=9, + no_ignore_our_externals=True, + ), + prefix_export_limit=30000, + areas=[ + dict( + area_id="0.0.0.100", + stub=dict(default_metric=200, set=True), + area_ranges=[ + dict( + address="10.200.17.0/24", + exact=True, + restrict=True, + override_metric=2000, + ), + ], + interfaces=[ + dict( + name="so-0/0/0.0", + priority=3, + metric=5, + flood_reduction=False, + passive=True, + bandwidth_based_metrics=[ + dict( + bandwidth="1g", + metric=5, + ), + ], + timers=dict( + dead_interval=4, + hello_interval=2, + poll_interval=2, + retransmit_interval=2, + ), + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + '' + "30004000" + "9" + "1200" + "10" + "30000" + "" + "0.0.0.10010.200.17.0/24" + "2000" + "so-0/0/0.035" + "1g5" + "42" + "22" + "200", + '' + "10.200.16.75", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_ospfv2_merged_areas(self): + set_module_args( + dict( + config=[ + dict( + areas=[ + dict( + area_id="0.0.0.100", + stub=dict(default_metric=200, set=True), + area_ranges=[ + dict( + address="10.200.17.0/24", + ), + dict( + address="10.200.18.0/24", + ), + ], + interfaces=[ + dict( + name="so-0/1/0.0", + bandwidth_based_metrics=[ + dict( + bandwidth="1g", + metric=5, + ), + dict( + bandwidth="10g", + metric=5, + ), + ], + ), + dict( + name="so-0/1/0.0", + priority=3, + ), + ], + ), + dict( + area_id="0.0.0.200", + area_range="10.200.20.0/24", + interfaces=[ + dict( + name="so-0/1/0.0", + bandwidth_based_metrics=[ + dict( + bandwidth="1g", + metric=5, + ), + ], + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + '' + "0.0.0.100" + "10.200.17.0/24" + "10.200.18.0/24" + "so-0/1/0.0" + "1g5" + "10g5" + "so-0/1/0.03" + "200" + "0.0.0.20010.200.20.0/24" + "so-0/1/0.0" + "1g5" + "", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_ospfv2_gathered(self): + """ + :return: + """ + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + gather_list = [ + { + "areas": [ + { + "area_id": "0.0.0.100", + "area_range": "['10.200.17.0/24', '10.200.15.0/24']", + "area_ranges": [ + { + "address": "10.200.17.0/24", + "exact": True, + "override_metric": 2000, + "restrict": True, + }, + { + "address": "10.200.15.0/24", + "exact": True, + "override_metric": 2000, + "restrict": True, + }, + ], + "interfaces": [ + { + "bandwidth_based_metrics": [ + { + "bandwidth": "1g", + "metric": 5, + }, + { + "bandwidth": "10g", + "metric": 40, + }, + ], + "metric": 5, + "name": "so-0/0/0.0", + "passive": True, + "priority": 3, + "timers": { + "dead_interval": 4, + "hello_interval": 2, + "poll_interval": 2, + "retransmit_interval": 2, + }, + }, + ], + "stub": { + "default_metric": 100, + "set": True, + }, + }, + { + "area_id": "0.0.0.200", + "area_range": "['10.200.19.0/24']", + "area_ranges": [ + { + "address": "10.200.19.0/24", + "exact": True, + "override_metric": 2000, + "restrict": True, + }, + ], + "interfaces": [ + { + "authentication": { + "password": "$9$eX2vMLoaUH.5bsgJZjPf369", + "type": { + "simple_password": "$9$eX2vMLoaUH.5bsgJZjPf369", + }, + }, + "name": "so-0/1/0.0", + "priority": 3, + }, + { + "authentication": { + "md5": [ + { + "key": "$9$vBL87Vg4ZiqfDi/t0OSy7-V", + "key_id": 10, + }, + ], + }, + "name": "so-0/2/0.0", + "priority": 2, + }, + ], + }, + { + "area_id": "0.0.0.120", + "area_range": "['10.200.20.0/24']", + "area_ranges": [ + { + "address": "10.200.20.0/24", + "exact": True, + "override_metric": 2000, + "restrict": True, + }, + ], + "interfaces": [ + { + "authentication": { + "md5": [ + { + "key": "$9$IIShrvx7V2oGs2mTF3purev", + "key_id": 10, + }, + ], + }, + "name": "so-0/2/0.1", + "priority": 2, + }, + ], + }, + ], + "overload": { + "allow_route_leaking": True, + "as_external": True, + "stub_network": True, + "timeout": 1200, + }, + "reference_bandwidth": "10g", + "rfc1583compatibility": False, + "router_id": "10.200.16.75", + }, + ] + + def test_junos_ospfv2_replaced(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + rfc1583compatibility="False", + external_preference=10, + overload=dict( + allow_route_leaking=True, + as_external=True, + stub_network=True, + timeout=1200, + ), + spf_options=dict( + delay=3000, + holddown=4000, + rapid_runs=9, + no_ignore_our_externals=True, + ), + prefix_export_limit=30000, + areas=[ + dict( + area_id="0.0.0.100", + stub=dict(default_metric=200, set=True), + area_ranges=[ + dict( + address="10.200.17.0/24", + exact=True, + restrict=True, + override_metric=2000, + ), + ], + interfaces=[ + dict( + name="so-0/0/0.0", + priority=3, + metric=5, + flood_reduction=False, + passive=True, + bandwidth_based_metrics=[ + dict( + bandwidth="1g", + metric=5, + ), + ], + timers=dict( + dead_interval=4, + hello_interval=2, + poll_interval=2, + retransmit_interval=2, + ), + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + commands = [ + '' + '0.0.0.1000.0.0.200' + '' + '' + '' + "300040009" + "1200" + "" + "1030000" + "0.0.0.10010.200.17.0/24" + "2000" + "so-0/0/0.035" + "1g5" + "42" + "22" + "200", + '' + "10.200.16.75", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_ospfv2_overridden(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + rfc1583compatibility="False", + external_preference=10, + overload=dict( + allow_route_leaking=True, + as_external=True, + stub_network=True, + timeout=1200, + ), + spf_options=dict( + delay=3000, + holddown=4000, + rapid_runs=9, + no_ignore_our_externals=True, + ), + prefix_export_limit=30000, + areas=[ + dict( + area_id="0.0.0.100", + stub=dict(default_metric=200, set=True), + area_ranges=[ + dict( + address="10.200.17.0/24", + exact=True, + restrict=True, + override_metric=2000, + ), + ], + interfaces=[ + dict( + name="so-0/0/0.0", + priority=3, + metric=5, + flood_reduction=False, + passive=True, + bandwidth_based_metrics=[ + dict( + bandwidth="1g", + metric=5, + ), + ], + timers=dict( + dead_interval=4, + hello_interval=2, + poll_interval=2, + retransmit_interval=2, + ), + ), + ], + ), + ], + ), + ], + state="overridden", + ), + ) + commands = [ + '' + '0.0.0.100' + '0.0.0.200' + '' + '' + '' + "30004000" + "9" + "1200" + "" + "10" + "30000" + "0.0.0.100" + "10.200.17.0/24" + "2000" + "so-0/0/0.035" + "" + "1g5" + "42" + "22" + "200" + "", + '' + "10.200.16.75", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_ospfv2_deleted(self): + set_module_args( + dict( + config=[], + state="deleted", + ), + ) + commands = [ + '' + '0.0.0.1000.0.0.200' + '' + '' + '', + ] + result = self.execute_module(changed=True, commands=commands) + + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_ospfv2_parsed(self): + parsed_str = """ + + + + + + 3000 + 4000 + 9 + + + 20000 + + 1200 + + + + + 10g + + + 0.0.0.100 + + 100 + + + 10.200.17.0/24 + + + 2000 + + + 10.200.15.0/24 + + + 2000 + + + so-0/0/0.0 + + + + + 1g + 5 + + + 10g + 40 + + + 5 + 3 + 2 + 2 + 4 + 2 + + + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = [ + { + "areas": [ + { + "area_id": "0.0.0.100", + "interfaces": [ + { + "name": "so-0/0/0.0", + "priority": 3, + "metric": 5, + "timers": { + "hello_interval": 2, + "dead_interval": 4, + "retransmit_interval": 2, + "poll_interval": 2, + }, + "passive": True, + "bandwidth_based_metrics": [ + { + "metric": 5, + "bandwidth": "1g", + }, + { + "metric": 40, + "bandwidth": "10g", + }, + ], + }, + ], + "area_range": "['10.200.17.0/24', '10.200.15.0/24']", + "area_ranges": [ + { + "address": "10.200.17.0/24", + "override_metric": 2000, + "exact": True, + "restrict": True, + }, + { + "address": "10.200.15.0/24", + "override_metric": 2000, + "exact": True, + "restrict": True, + }, + ], + "stub": { + "set": True, + "default_metric": 100, + }, + }, + ], + "overload": { + "allow_route_leaking": True, + "as_external": True, + "stub_network": True, + "timeout": 1200, + }, + "prefix_export_limit": 20000, + "reference_bandwidth": "10g", + "rfc1583compatibility": False, + "spf_options": { + "delay": 3000, + "holddown": 4000, + "rapid_runs": 9, + "no_ignore_our_externals": True, + }, + }, + ] + + def test_junos_ospfv2_rendered(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + rfc1583compatibility="False", + external_preference=10, + overload=dict( + allow_route_leaking=True, + as_external=True, + stub_network=True, + timeout=1200, + ), + spf_options=dict( + delay=3000, + holddown=4000, + rapid_runs=9, + no_ignore_our_externals=True, + ), + prefix_export_limit=30000, + areas=[ + dict( + area_id="0.0.0.100", + stub=dict(default_metric=200, set=True), + area_ranges=[ + dict( + address="10.200.17.0/24", + exact=True, + restrict=True, + override_metric=2000, + ), + ], + interfaces=[ + dict( + name="so-0/0/0.0", + priority=3, + metric=5, + flood_reduction=False, + passive=True, + bandwidth_based_metrics=[ + dict( + bandwidth="1g", + metric=5, + ), + ], + timers=dict( + dead_interval=4, + hello_interval=2, + poll_interval=2, + retransmit_interval=2, + ), + ), + ], + ), + ], + ), + ], + state="rendered", + ), + ) + rendered = ( + '' + "30004000" + "9" + "1200" + "" + "10" + "30000" + "0.0.0.100" + "10.200.17.0/24" + "2000" + "so-0/0/0.0" + "35" + "1g" + "5" + "42" + "2" + "2" + "200" + "" + ) + result = self.execute_module(changed=False) + self.assertEqual( + self.sorted_xml(result["rendered"]), + self.sorted_xml(rendered), + ) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ospfv3.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ospfv3.py new file mode 100644 index 00000000..beef248b --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ospfv3.py @@ -0,0 +1,403 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import MagicMock, patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_ospfv3 +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosOspfv3Module(TestJunosModule): + module = junos_ospfv3 + + def setUp(self): + super(TestJunosOspfv3Module, self).setUp() + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.ospfv3.ospfv3.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_validate_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils.validate_config", + ) + self.validate_config = self.mock_validate_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.ospfv3.ospfv3.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_get_connection = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.ospfv3.ospfv3." + "Ospfv3Facts.get_connection", + ) + self.get_connection = self.mock_get_connection.start() + + self.conn = self.get_connection() + self.conn.get = MagicMock() + + self.mock_get_xml_dict = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.ospfv3.ospfv3.Ospfv3Facts._get_xml_dict", + ) + self._get_xml_dict = self.mock_get_xml_dict.start() + + def tearDown(self): + super(TestJunosOspfv3Module, self).tearDown() + self.mock_get_connection.stop() + self.mock_load_config.stop() + self.mock_validate_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + + def load_fixtures(self, commands=None, format="text", changed=False): + self.get_connection.return_value = load_fixture( + "junos_ospfv3_config.cfg", + ) + if changed: + self.load_config.return_value = load_fixture( + "get_configuration_rpc_reply_diff.txt", + ) + else: + self.load_config.return_value = None + + def test_junos_ospfv3_merged(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + areas=[ + dict( + area_id="0.0.0.100", + stub=dict(default_metric=200, set=True), + interfaces=[ + dict( + name="so-0/0/0.0", + priority=3, + metric=5, + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + '' + "0.0.0.100so-0/0/0.0" + "35" + "200", + '' + "10.200.16.75", + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_ospfv3_merged_idempotent(self): + self.get_connection.return_value = load_fixture( + "junos_ospfv3_config.cfg", + ) + src = load_fixture("junos_ospfv3.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[ + dict( + router_id="30", + areas=[ + dict( + area_id="100", + stub=dict(default_metric=10, set=True), + interfaces=[ + dict( + name="so-0/0/0.0", + priority=3, + metric=5, + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_junos_ospfv3_replaced(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + areas=[ + dict( + area_id="0.0.0.100", + stub=dict(default_metric=200, set=True), + interfaces=[ + dict( + name="so-0/0/0.0", + priority=3, + metric=5, + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + result = self.execute_module(changed=True) + commands = [ + '' + "0.0.0.100so-0/0/0.0" + "3" + "5" + "200" + "0.0.0.100" + "so-0/0/0.0" + "35" + "200", + '' + "10.200.16.7510.200.16.75", + ] + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_ospfv3_replaced_idempotent(self): + self.get_connection.return_value = load_fixture( + "junos_ospfv3_config.cfg", + ) + src = load_fixture("junos_ospfv3.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[ + dict( + router_id="30", + areas=[ + dict( + area_id="100", + stub=dict(default_metric=10, set=True), + interfaces=[ + dict( + name="so-0/0/0.0", + priority=3, + metric=5, + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + + self.execute_module(changed=False, commands=[]) + + def test_junos_ospfv3_overridden(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + areas=[ + dict( + area_id="0.0.0.100", + stub=dict(default_metric=200, set=True), + interfaces=[ + dict( + name="so-0/0/0.0", + priority=3, + metric=5, + ), + ], + ), + ], + ), + ], + state="overridden", + ), + ) + commands = [ + '' + "0.0.0.100so-0/0/0.0" + "3" + "5" + "200", + '' + "10.200.16.75", + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_ospfv3_overridden_idempotent(self): + self.get_connection.return_value = load_fixture( + "junos_ospfv3_config.cfg", + ) + src = load_fixture("junos_ospfv3.cfg", content="str") + set_module_args(dict(src=src)) + set_module_args( + dict( + config=[ + dict( + router_id="30", + areas=[ + dict( + area_id="100", + stub=dict(default_metric=10, set=True), + interfaces=[ + dict( + name="so-0/0/0.0", + priority=3, + metric=5, + ), + ], + ), + ], + ), + ], + state="overridden", + ), + ) + + self.execute_module(changed=False, commands=[]) + + def test_junos_ospfv3_delete(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + areas=[ + dict( + area_id="0.0.0.100", + stub=dict(default_metric=200, set=True), + interfaces=[dict(name="so-0/0/0.0")], + ), + ], + ), + ], + state="deleted", + ), + ) + + commands = [ + '' + "0.0.0.100so-0/0/0.0" + "200", + '' + "10.200.16.75", + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), commands) + + def test_junos_ospfv3_delete_idempotent(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.70", + areas=[ + dict( + area_id="0.0.0.100", + stub=dict(default_metric=200, set=True), + interfaces=[dict(name="so-0/0/0.0")], + ), + ], + ), + ], + state="deleted", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_junos_ospfv3_parsed(self): + set_module_args( + dict( + running_config='\n' + '\n' + '' + "\n\n\n\n0.0.0.100\n\n" + "200\n\n\nso-0/0/0.0" + "\n\n5\n3\n" + "\n\n\n\n\n" + "10.200.16.75\n\n" + "\n", + state="parsed", + ), + ) + result = self.execute_module(changed=False) + self.assertEqual([], result["parsed"]) + + def test_junos_ospfv3_rendered(self): + set_module_args( + dict( + config=[ + dict( + router_id="10.200.16.75", + areas=[ + dict( + area_id="0.0.0.100", + stub=dict(default_metric=200, set=True), + interfaces=[ + dict( + name="so-0/0/0.0", + priority=3, + metric=5, + ), + ], + ), + ], + ), + ], + state="rendered", + ), + ) + commands = ( + '' + "0.0.0.100so-0/0/0.0" + "35" + "200" + ) + self.execute_module(changed=False, commands=commands) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_package.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_package.py new file mode 100644 index 00000000..943c7e9e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_package.py @@ -0,0 +1,92 @@ +# (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 . + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import MagicMock, patch + +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule + + +jnpr_mock = MagicMock() +modules = { + "jnpr": jnpr_mock, + "jnpr.junos": jnpr_mock.junos, + "jnpr.junos.utils": jnpr_mock.junos.utils, + "jnpr.junos.utils.sw": jnpr_mock.junos.utils.sw, +} +module_patcher = patch.dict("sys.modules", modules) +module_patcher.start() + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_package + + +class TestJunosPackageModule(TestJunosModule): + module = junos_package + + def setUp(self): + super(TestJunosPackageModule, self).setUp() + self.mock_get_device = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_package.get_device", + ) + self.get_device = self.mock_get_device.start() + + def tearDown(self): + super(TestJunosPackageModule, self).tearDown() + self.mock_get_device.stop() + + def test_junos_package_src(self): + set_module_args(dict(src="junos-vsrx-12.1X46-D10.2-domestic.tgz")) + self.execute_module(changed=True) + + args, _kwargs = jnpr_mock.junos.utils.sw.SW().install.call_args + self.assertEqual(args, ("junos-vsrx-12.1X46-D10.2-domestic.tgz",)) + + def test_junos_package_src_fail(self): + jnpr_mock.junos.utils.sw.SW().install.return_value = 0 + set_module_args(dict(src="junos-vsrx-12.1X46-D10.2-domestic.tgz")) + result = self.execute_module(changed=True, failed=True) + + self.assertEqual(result["msg"], "Unable to install package on device") + + def test_junos_package_src_no_copy(self): + jnpr_mock.junos.utils.sw.SW().install.return_value = 1 + set_module_args( + dict(src="junos-vsrx-12.1X46-D10.2-domestic.tgz", no_copy=True), + ) + self.execute_module(changed=True) + + args, kwargs = jnpr_mock.junos.utils.sw.SW().install.call_args + self.assertEqual(args, ("junos-vsrx-12.1X46-D10.2-domestic.tgz",)) + self.assertEqual(kwargs["no_copy"], True) + + def test_junos_package_src_unlink(self): + jnpr_mock.junos.utils.sw.SW().install.return_value = 1 + set_module_args( + dict(src="junos-vsrx-12.1X46-D10.2-domestic.tgz", unlink=True), + ) + self.execute_module(changed=True) + + args, kwargs = jnpr_mock.junos.utils.sw.SW().install.call_args + self.assertEqual(args, ("junos-vsrx-12.1X46-D10.2-domestic.tgz",)) + self.assertEqual(kwargs["unlink"], True) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ping.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ping.py new file mode 100644 index 00000000..4a6d2701 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_ping.py @@ -0,0 +1,168 @@ +# (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 unittest.mock import MagicMock, patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_ping +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosPingModule(TestJunosModule): + module = junos_ping + + def setUp(self): + super(TestJunosPingModule, self).setUp() + + self.mock_get_connection = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_ping.get_connection", + ) + self.get_connection = self.mock_get_connection.start() + + self.conn = self.get_connection() + self.conn.get = MagicMock() + + def tearDown(self): + super(TestJunosPingModule, self).tearDown() + self.mock_get_connection.stop() + + def test_junos_ping_expected_success(self): + set_module_args(dict(count=2, dest="10.10.10.10")) + self.conn.get = MagicMock( + return_value=load_fixture( + "junos_ping_ping_10.10.10.10_count_2", + content="str", + ), + ) + result = self.execute_module() + self.assertEqual(result["commands"], "ping 10.10.10.10 count 2") + + def test_junos_ping_expected_failure(self): + set_module_args(dict(count=4, dest="10.10.10.20", state="absent")) + self.conn.get = MagicMock( + return_value=load_fixture( + "junos_ping_ping_10.10.10.20_count_4", + content="str", + ), + ) + result = self.execute_module() + self.assertEqual(result["commands"], "ping 10.10.10.20 count 4") + + def test_junos_ping_unexpected_success(self): + """Test for successful pings when destination should not be reachable - FAIL.""" + set_module_args(dict(count=2, dest="10.10.10.10", state="absent")) + self.conn.get = MagicMock( + return_value=load_fixture( + "junos_ping_ping_10.10.10.10_count_2", + content="str", + ), + ) + self.execute_module(failed=True) + + def test_junos_ping_unexpected_failure(self): + """Test for unsuccessful pings when destination should be reachable - FAIL.""" + set_module_args(dict(count=4, dest="10.10.10.20")) + self.conn.get = MagicMock( + return_value=load_fixture( + "junos_ping_ping_10.10.10.20_count_4", + content="str", + ), + ) + self.execute_module(failed=True) + + def test_junos_ping_failure_stats(self): + """Test for asserting stats when ping fails""" + set_module_args(dict(count=4, dest="10.10.10.20")) + self.conn.get = MagicMock( + return_value=load_fixture( + "junos_ping_ping_10.10.10.20_count_4", + content="str", + ), + ) + result = self.execute_module(failed=True) + self.assertEqual(result["packet_loss"], "100%") + self.assertEqual(result["packets_rx"], 0) + self.assertEqual(result["packets_tx"], 4) + + def test_junos_ping_success_stats(self): + set_module_args(dict(count=2, dest="10.10.10.10")) + self.conn.get = MagicMock( + return_value=load_fixture( + "junos_ping_ping_10.10.10.10_count_2", + content="str", + ), + ) + result = self.execute_module() + self.assertEqual(result["commands"], "ping 10.10.10.10 count 2") + self.assertEqual(result["packet_loss"], "0%") + self.assertEqual(result["packets_rx"], 2) + self.assertEqual(result["packets_tx"], 2) + self.assertEqual(result["rtt"]["min"], 15.71) + self.assertEqual(result["rtt"]["avg"], 16.87) + self.assertEqual(result["rtt"]["max"], 18.04) + self.assertEqual(result["rtt"]["stddev"], 1.165) + + def test_junos_ping_success_stats_with_options(self): + set_module_args( + dict(count=5, size=512, interval=2, dest="10.10.10.11"), + ) + self.conn.get = MagicMock( + return_value=load_fixture( + "junos_ping_ping_10.10.10.11_count_5_size_512_interval_2", + content="str", + ), + ) + result = self.execute_module() + self.assertEqual( + result["commands"], + "ping 10.10.10.11 count 5 size 512 interval 2", + ) + self.assertEqual(result["packet_loss"], "0%") + self.assertEqual(result["packets_rx"], 5) + self.assertEqual(result["packets_tx"], 5) + self.assertEqual(result["rtt"]["min"], 18.71) + self.assertEqual(result["rtt"]["avg"], 17.87) + self.assertEqual(result["rtt"]["max"], 20.04) + self.assertEqual(result["rtt"]["stddev"], 2.165) + + def test_junos_ping_success_stats_with_df_rapid(self): + set_module_args(dict(df_bit=True, rapid=True, dest="10.10.10.12")) + self.conn.get = MagicMock( + return_value=load_fixture( + "junos_ping_ping_10.10.10.12_count_5_do-not-fragment_rapid", + content="str", + ), + ) + result = self.execute_module() + self.assertEqual( + result["commands"], + "ping 10.10.10.12 count 5 do-not-fragment rapid", + ) + self.assertEqual(result["packet_loss"], "0%") + self.assertEqual(result["packets_rx"], 5) + self.assertEqual(result["packets_tx"], 5) + self.assertEqual(result["rtt"]["min"], 2.58) + self.assertEqual(result["rtt"]["avg"], 2.63) + self.assertEqual(result["rtt"]["max"], 2.74) + self.assertEqual(result["rtt"]["stddev"], 0.058) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_prefix_lists.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_prefix_lists.py new file mode 100644 index 00000000..9db905a4 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_prefix_lists.py @@ -0,0 +1,327 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_prefix_lists +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosPrefix_listsModule(TestJunosModule): + module = junos_prefix_lists + + def setUp(self): + super(TestJunosPrefix_listsModule, self).setUp() + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.prefix_lists.prefix_lists.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.prefix_lists.prefix_lists.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.prefix_lists.prefix_lists." + "Prefix_listsFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosPrefix_listsModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + if filename: + output = load_fixture(filename) + else: + output = load_fixture("junos_prefix_lists_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def test_junos_prefix_lists_merged_01(self): + set_module_args( + dict( + config=[ + dict( + name="Internal", + address_prefixes=["172.16.1.32", "172.16.3.32"], + ), + dict(name="Test1", dynamic_db=True), + dict( + name="Test2", + address_prefixes=[ + "172.16.2.32", + "172.16.7.32", + "172.16.9.32", + ], + ), + ], + state="merged", + ), + ) + commands = [ + '' + "Internal" + "172.16.1.32" + "172.16.3.32" + "" + "Test1" + "Test2" + "172.16.2.32" + "172.16.7.32" + "" + "172.16.9.32" + "", + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_prefix_lists_merged_idempotent_01(self): + set_module_args( + dict( + config=[ + dict(name="customer_64510"), + dict( + name="customer_64500", + dynamic_db=True, + address_prefixes=["172.16.1.16/28", "172.16.1.32/28"], + ), + ], + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_prefix_lists_replaced_01(self): + set_module_args( + dict( + config=[ + dict( + name="customer_64510", + address_prefixes=["172.16.1.32/28", "172.16.3.32/28"], + ), + dict( + name="customer_64500", + address_prefixes=["172.16.2.16/28", "172.16.1.32/28"], + ), + ], + state="replaced", + ), + ) + commands = [ + '' + 'customer_64510' + '' + "customer_64500" + "customer_64510" + "172.16.1.32/28" + "" + "172.16.3.32/28" + "customer_64500" + "172.16.2.16/28" + "172.16.1.32/28" + "", + ] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_prefix_lists_replaced_idempotent_01(self): + set_module_args( + dict( + config=[ + dict(name="customer_64510"), + dict( + name="customer_64500", + dynamic_db=True, + address_prefixes=["172.16.1.16/28", "172.16.1.32/28"], + ), + ], + state="replaced", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_prefix_lists_overridden_01(self): + set_module_args( + dict( + config=[ + dict( + name="customer_65500", + address_prefixes=["172.16.2.16/28", "172.16.1.32/28"], + ), + ], + state="overridden", + ), + ) + commands = [ + '' + 'customer_64510' + 'customer_64500' + "customer_65500" + "172.16.2.16/28" + "172.16.1.32/28" + "", + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_prefix_lists_overridden_idempotent_01(self): + set_module_args( + dict( + config=[ + dict(name="customer_64510"), + dict( + name="customer_64500", + dynamic_db=True, + address_prefixes=["172.16.1.16/28", "172.16.1.32/28"], + ), + ], + state="overridden", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_prefix_lists_parsed_01(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + customer_64510 + + + customer_64500 + + + 172.16.1.16/28 + + + 172.16.1.32/28 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_list = [ + {"name": "customer_64510"}, + { + "name": "customer_64500", + "dynamic_db": True, + "address_prefixes": ["172.16.1.16/28", "172.16.1.32/28"], + }, + ] + self.assertEqual(result["parsed"], parsed_list) + + def test_junos_prefix_lists_gathered_01(self): + """ + :return: + """ + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + gather_list = [ + {"name": "customer_64510"}, + { + "name": "customer_64500", + "dynamic_db": True, + "address_prefixes": ["172.16.1.16/28", "172.16.1.32/28"], + }, + ] + self.assertEqual(gather_list, result["gathered"]) + + def test_junos_prefix_lists_rendered_01(self): + """ + :return: + """ + set_module_args( + dict( + config=[ + dict( + name="Internal", + address_prefixes=["172.16.1.32", "172.16.3.32"], + ), + dict(name="Test1", dynamic_db=True), + dict( + name="Test2", + address_prefixes=[ + "172.16.2.32", + "172.16.7.32", + "172.16.9.32", + ], + ), + ], + state="rendered", + ), + ) + + rendered = ( + '' + "Internal" + "172.16.1.32" + "172.16.3.32" + "" + "Test1" + "Test2" + "172.16.2.32" + "172.16.7.32" + "" + "172.16.9.32" + "" + ) + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_routing_instances.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_routing_instances.py new file mode 100644 index 00000000..d281a7ef --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_routing_instances.py @@ -0,0 +1,490 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_routing_instances +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosRouting_instancesModule(TestJunosModule): + module = junos_routing_instances + + def setUp(self): + super(TestJunosRouting_instancesModule, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.routing_instances.routing_instances.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.routing_instances.routing_instances.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.routing_instances.routing_instances." + "Routing_instancesFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosRouting_instancesModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + if filename: + output = load_fixture(filename) + else: + output = load_fixture("junos_routing_instances_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def sort_routing_instances(self, entry_list): + for entry in entry_list: + if entry.get("instance"): + entry["routing_instances"].sort(key=lambda i: i.get("name")) + + def test_junos_routing_instances_domains_merged(self): + set_module_args( + dict( + config=[ + dict( + name="EVPN", + type="virtual-switch", + route_distinguisher="10.0.0.21:444", + bridge_domains=[ + dict( + name="BD456", + vlan_id=456, + enable_mac_move_action=True, + mcae_mac_flush=True, + no_local_switching=True, + service_id=20, + ), + dict( + name="BD457", + vlan_id=457, + ), + ], + ), + dict( + name="mgmt_junos", + ), + ], + state="merged", + ), + ) + commands = [ + '' + "EVPN" + "virtual-switch" + "" + "BD456" + "20" + "456" + "" + "" + "" + "" + "BD457" + "457" + "10.0.0.21:444" + "mgmt_junos", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_routing_instances_merged(self): + set_module_args( + dict( + config=[ + dict( + name="test", + type="vrf", + route_distinguisher="10.58.255.1:37", + vrf_imports=["test-policy"], + vrf_exports=["test-policy", "test-policy-1"], + interfaces=[ + dict(name="sp-0/0/0.0"), + dict(name="gr-0/0/0.0"), + ], + connector_id_advertise=True, + ), + ], + state="merged", + ), + ) + commands = [ + '' + "test" + "vrfsp-0/0/0.0" + "gr-0/0/0.0" + "10.58.255.1:37" + "test-policy" + "test-policytest-policy-1" + "", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_routing_instances_merged_idempotent(self): + set_module_args( + dict( + config=[ + dict( + name="forwardinst", + type="forwarding", + description="Configured by Ansible Content Team", + ), + ], + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_routing_instances_replaced(self): + """ + :return: + """ + set_module_args( + dict( + config=[ + dict( + name="test", + type="vrf", + route_distinguisher="10.58.255.1:37", + vrf_imports=["test-policy"], + vrf_exports=["test-policy", "test-policy-1"], + interfaces=[ + dict(name="sp-0/0/0.0"), + dict(name="gr-0/0/0.0"), + ], + connector_id_advertise=True, + ), + dict( + name="forwardinst", + type="forwarding", + description="Replaced and Configured by Ansible Content Team", + ), + ], + state="replaced", + ), + ) + + commands = [ + '' + 'forwardinst' + "test" + "vrfsp-0/0/0.0" + "gr-0/0/0.0" + "10.58.255.1:37" + "test-policy" + "test-policytest-policy-1" + "forwardinst" + "Replaced and Configured by Ansible Content Team" + "forwarding" + "", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_routing_instances_replaced_idempotent(self): + set_module_args( + dict( + config=[ + dict( + name="forwardinst", + type="forwarding", + description="Configured by Ansible Content Team", + ), + ], + state="replaced", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_routing_instances_overridden(self): + """ + :return: + """ + set_module_args( + dict( + config=[ + dict( + name="test1", + type="vrf", + route_distinguisher="10.58.255.1:37", + vrf_imports=["test-policy"], + vrf_exports=["test-policy", "test-policy-1"], + interfaces=[ + dict(name="sp-0/0/0.0"), + dict(name="gr-0/0/0.0"), + ], + connector_id_advertise=True, + ), + ], + state="overridden", + ), + ) + + commands = [ + '' + 'forwardinst' + "test1" + "vrfsp-0/0/0.0" + "gr-0/0/0.0" + "10.58.255.1:37" + "test-policytest-policy" + "test-policy-1", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_routing_instances_overridden_idempotent(self): + set_module_args( + dict( + config=[ + dict( + name="forwardinst", + type="forwarding", + description="Configured by Ansible Content Team", + ), + ], + state="overridden", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_routing_instances_rendered(self): + """ + :return: + """ + set_module_args( + dict( + config=[ + dict( + name="test", + type="vrf", + route_distinguisher="10.58.255.1:37", + vrf_imports=["test-policy"], + vrf_exports=["test-policy", "test-policy-1"], + interfaces=[ + dict(name="sp-0/0/0.0"), + dict(name="gr-0/0/0.0"), + ], + connector_id_advertise=True, + ), + ], + state="rendered", + ), + ) + + rendered = ( + '' + "test" + "vrfsp-0/0/0.0" + "gr-0/0/0.0" + "10.58.255.1:37" + "test-policy" + "test-policytest-policy-1" + "" + ) + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) + + def test_junos_routing_instances_rendered_02(self): + """ + :return: + """ + set_module_args( + dict( + config=[ + dict( + name="test", + type="mac-vrf", + route_distinguisher="10.58.255.1:37", + vrf_imports=["test-policy"], + vrf_exports=["test-policy", "test-policy-1"], + interfaces=[ + dict(name="sp-0/0/0.0"), + dict(name="gr-0/0/0.0"), + ], + connector_id_advertise=True, + ), + ], + state="rendered", + ), + ) + + rendered = ( + '' + "test" + "mac-vrfsp-0/0/0.0" + "gr-0/0/0.0" + "10.58.255.1:37" + "test-policy" + "test-policytest-policy-1" + "" + ) + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) + + def test_junos_routing_instances_gathered(self): + """ + :return: + """ + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + gather_list = [ + { + "name": "forwardinst", + "type": "forwarding", + "description": "Configured by Ansible Content Team", + }, + ] + self.assertEqual(sorted(gather_list), sorted(result["gathered"])) + + def test_junos_routing_instances_deleted(self): + """ + :return: + """ + set_module_args(dict(config=[], state="deleted")) + + commands = [ + '' + '', + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_routing_instances_delted_single_entry(self): + """ + :return: + """ + set_module_args( + dict(config=[dict(name="forwardinst")], state="deleted"), + ) + + commands = [ + '' + 'forwardinst', + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_routing_instances_parsed(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + forwardinst + Configured by Ansible Content Team + forwarding + + + test + vrf + + gr-0/0/0.0 + + + sp-0/0/0.0 + + + 10.58.255.1:37 + + test-policy + test-policy + test-policy-1 + + + + + + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_list = [ + { + "description": "Configured by Ansible Content Team", + "name": "forwardinst", + "type": "forwarding", + }, + { + "connector_id_advertise": True, + "interfaces": [{"name": "gr-0/0/0.0"}, {"name": "sp-0/0/0.0"}], + "name": "test", + "no_irb_layer_2_copy": True, + "no_local_switching": True, + "no_vrf_advertise": True, + "no_vrf_propagate_ttl": True, + "route_distinguisher": "10.58.255.1:37", + "type": "vrf", + "vrf_exports": ["test-policy", "test-policy-1"], + "vrf_imports": ["test-policy"], + }, + ] + self.sort_routing_instances(result["parsed"]) + self.sort_routing_instances(parsed_list) + self.assertEqual(result["parsed"], parsed_list) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_routing_options.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_routing_options.py new file mode 100644 index 00000000..0f506bc8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_routing_options.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_routing_options +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosRouting_optionsModule(TestJunosModule): + module = junos_routing_options + + def setUp(self): + super(TestJunosRouting_optionsModule, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.routing_options.routing_options.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.routing_options.routing_options.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.routing_options.routing_options." + "Routing_optionsFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosRouting_optionsModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + output = load_fixture("junos_routing_options_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def test_junos_routing_options_merged_01(self): + set_module_args( + dict( + config=dict( + autonomous_system=dict( + as_number="2", + loops=4, + asdot_notation=True, + ), + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + "24", + str(result["commands"]), + ) + + def test_junos_routing_options_merged_idempotent(self): + self.execute_show_command.return_value = load_fixture( + "junos_routing_options_config.cfg", + ) + set_module_args( + dict( + config=dict( + router_id="12.12.12.13", + autonomous_system=dict(as_number="1"), + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_routing_options_parsed_01(self): + parsed_str = """ + + + 18.4R1-S2.4 + + 12.12.12.12 + + 2 + 4 + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "autonomous_system": { + "as_number": "2", + "asdot_notation": True, + "loops": 4, + }, + "router_id": "12.12.12.12", + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_routing_options_replaced_01(self): + set_module_args( + dict( + config=dict( + autonomous_system=dict( + as_number="1", + loops=4, + asdot_notation=True, + ), + ), + state="replaced", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + "14", + str(result["commands"]), + ) + + def test_junos_routing_options_rendered(self): + set_module_args( + dict( + config=dict( + autonomous_system=dict( + as_number="2", + loops=4, + asdot_notation=True, + ), + router_id="12.12.12.12", + ), + state="rendered", + ), + ) + rendered = ( + '' + "24" + "12.12.12.12" + ) + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) + + def test_junos_routing_options_overridden(self): + set_module_args( + dict( + config=dict( + autonomous_system=dict( + as_number="1", + loops=4, + asdot_notation=True, + ), + ), + state="overridden", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + "14", + str(result["commands"]), + ) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_rpc.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_rpc.py new file mode 100644 index 00000000..11a3bb8a --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_rpc.py @@ -0,0 +1,137 @@ +# (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 . + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +try: + from lxml.etree import fromstring +except ImportError: + from xml.etree.ElementTree import fromstring + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_rpc +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +RPC_CLI_MAP = { + "get-software-information": "show version", + "get-interface-information": "show interfaces details", + "get-system-memory-information": "show system memory", + "get-chassis-inventory": "show chassis hardware", + "get-system-storage": "show system storage", + "load-configuration": "load configuration", +} + + +class TestJunosCommandModule(TestJunosModule): + module = junos_rpc + + def setUp(self): + super(TestJunosCommandModule, self).setUp() + self.mock_conn = patch("ansible.module_utils.connection.Connection") + self.conn = self.mock_conn.start() + + self.mock_netconf = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.NetconfConnection", + ) + self.netconf_conn = self.mock_netconf.start() + + self.mock_netconf_rpc = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf.NetconfConnection", + ) + self.netconf_rpc = self.mock_netconf_rpc.start() + + self.mock_exec_rpc = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_rpc.exec_rpc", + ) + self.exec_rpc = self.mock_exec_rpc.start() + + def tearDown(self): + super(TestJunosCommandModule, self).tearDown() + self.mock_conn.stop() + self.mock_netconf.stop() + self.mock_netconf_rpc.stop() + self.mock_exec_rpc.stop() + + def load_fixtures(self, commands=None, format="text", changed=False): + def load_from_file(*args, **kwargs): + element = fromstring(args[1]) + if element.text: + path = str(element.text) + else: + tag = str(element.tag) + if tag.startswith("{"): + tag = tag.split("}", 1)[1] + path = RPC_CLI_MAP[tag] + + filename = path.replace(" ", "_") + filename = "%s_%s.txt" % (filename, format) + + return load_fixture(filename) + + self.exec_rpc.side_effect = load_from_file + + def test_junos_rpc_xml(self): + set_module_args(dict(rpc="get-chassis-inventory")) + result = self.execute_module(format="xml") + self.assertTrue(result["xml"].find("\n")) + + def test_junos_rpc_text(self): + set_module_args(dict(rpc="get-software-information", output="text")) + result = self.execute_module(format="text") + self.assertTrue( + result["output_lines"][0].startswith("Hostname: vsrx01"), + ) + + def test_junos_rpc_json(self): + set_module_args(dict(rpc="get-software-information", output="json")) + result = self.execute_module(format="json") + self.assertTrue("software-information" in result["output"]) + + def test_junos_rpc_args(self): + set_module_args( + dict( + rpc="get-software-information", + args={"interface": "em0", "media": True}, + ), + ) + self.execute_module(format="xml") + args, kwargs = self.exec_rpc.call_args + reply = args[1] + self.assertTrue( + reply.find( + "em0", + ), + ) + + def test_junos_rpc_attrs(self): + set_module_args( + dict( + rpc="load-configuration", + output="xml", + attrs={"url": "/var/tmp/config.conf"}, + ), + ) + result = self.execute_module(format="xml") + self.assertTrue(result["xml"].find("")) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_scp.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_scp.py new file mode 100644 index 00000000..fc2bd1b8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_scp.py @@ -0,0 +1,121 @@ +# (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 + +import os + +from unittest.mock import MagicMock, patch + +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule + + +jnpr_mock = MagicMock() +modules = { + "jnpr": jnpr_mock, + "jnpr.junos": jnpr_mock.junos, + "jnpr.junos.utils": jnpr_mock.junos.utils, + "jnpr.junos.utils.scp": jnpr_mock.junos.utils.scp, +} +module_patcher = patch.dict("sys.modules", modules) +module_patcher.start() + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_scp + + +class TestJunosScpModule(TestJunosModule): + module = junos_scp + + def setUp(self): + super(TestJunosScpModule, self).setUp() + self.mock_get_device = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_scp.get_device", + ) + self.get_device = self.mock_get_device.start() + + self.mock_scp = patch( + "ansible_collections.junipernetworks.junos.plugins.modules.junos_scp.SCP", + ) + self.scp = self.mock_scp.start() + + self.scp_mock = MagicMock() + self.scp().__enter__.return_value = self.scp_mock + + def tearDown(self): + super(TestJunosScpModule, self).tearDown() + self.mock_get_device.stop() + self.mock_scp.stop() + + def test_junos_scp_src(self): + set_module_args(dict(src="test.txt")) + self.execute_module(changed=True) + + self.scp_mock.put.assert_called_once_with( + "test.txt", + remote_path=".", + recursive=False, + ) + + def test_junos_scp_src_expand_tilde(self): + set_module_args(dict(src="~/test.txt")) + self.execute_module(changed=True) + + self.scp_mock.put.assert_called_once_with( + os.path.expanduser("~/test.txt"), + remote_path=".", + recursive=False, + ) + + def test_junos_scp_src_fail(self): + self.scp_mock.put.side_effect = OSError( + "[Errno 2] No such file or directory: 'text.txt'", + ) + set_module_args(dict(src="test.txt")) + result = self.execute_module(changed=True, failed=True) + + self.assertEqual( + result["msg"], + "[Errno 2] No such file or directory: 'text.txt'", + ) + + def test_junos_scp_remote_src(self): + set_module_args(dict(src="test.txt", remote_src=True)) + self.execute_module(changed=True) + + self.scp_mock.get.assert_called_once_with( + "test.txt", + local_path=".", + recursive=False, + ) + + def test_junos_scp_all(self): + set_module_args( + dict(src="test", remote_src=True, dest="tmp", recursive=True), + ) + self.execute_module(changed=True) + + self.scp_mock.get.assert_called_once_with( + "test", + local_path="tmp", + recursive=True, + ) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_security_policies.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_security_policies.py new file mode 100644 index 00000000..22eb2b14 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_security_policies.py @@ -0,0 +1,1090 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_security_policies +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosSecurity_policiesModule(TestJunosModule): + module = junos_security_policies + + def setUp(self): + super(TestJunosSecurity_policiesModule, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.security_policies.security_policies.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.security_policies.security_policies.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.security_policies.security_policies" + ".Security_policiesFacts._get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosSecurity_policiesModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + output = load_fixture("junos_security_policies_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def sorted_xml(self, xml_string): + temp = [] + index = 0 + while index < len(xml_string): + temp_line = "" + if xml_string[index] == "<": + while index < len(xml_string) and xml_string[index] != ">": + temp_line += xml_string[index] + index += 1 + temp_line += ">" + index += 1 + temp.append(temp_line) + else: + while index < len(xml_string) and xml_string[index] != "<": + temp_line += xml_string[index] + index += 1 + temp.append(temp_line) + return sorted(temp) + + def test_junos_security_policies_merged_01(self): + set_module_args( + dict( + config={ + "from_zones": [ + { + "name": "one", + "to_zones": [ + { + "name": "two", + "policies": [ + { + "match": { + "application": { + "names": [ + "junos-dhcp-relay", + "junos-finger", + ], + }, + "destination_address": { + "addresses": ["a2", "a4"], + }, + "destination_address_excluded": True, + "dynamic_application": { + "any": True, + }, + "source_address": { + "addresses": ["a1", "a3"], + }, + "source_address_excluded": True, + "source_end_user_profile": "test_end_user_profile", + "source_identity": { + "unknown_user": True, + }, + "url_category": { + "names": [ + "Enhanced_Web_Chat", + "Enhanced_Web_Collaboration", + ], + }, + }, + "name": "test_policy_1", + "then": { + "count": True, + "deny": True, + "log": {"session_close": True}, + }, + }, + { + "match": { + "application": { + "names": [ + "junos-dhcp-relay", + ], + }, + "destination_address": { + "addresses": ["a2"], + }, + "source_address": { + "addresses": ["a1"], + }, + }, + "name": "test_policy_2", + "then": { + "reject": { + "enable": True, + "profile": "test_dyn_app", + "ssl_proxy": { + "enable": True, + "profile_name": "SECURITY-SSL-PROXY", + }, + }, + }, + }, + ], + }, + { + "name": "three", + "policies": [ + { + "match": { + "application": { + "names": [ + "junos-dhcp-relay", + ], + }, + "destination_address": { + "addresses": ["a2"], + }, + "source_address": { + "addresses": ["a1"], + }, + }, + "name": "test_policy_3", + "then": { + "permit": { + "destination_address": "drop-translated", + "application_services": { + "advanced_anti_malware_policy": "test_anti_malware", + "application_traffic_control_rule_set": "test_traffic_control", + "gprs_gtp_profile": "gtp1", + "gprs_sctp_profile": "sctp1", + "icap_redirect": "test_icap", + "idp_policy": "test_idp", + "reverse_redirect_wx": True, + "ssl_proxy": { + "enable": True, + "profile_name": "SECURITY-SSL-PROXY", + }, + "uac_policy": { + "enable": True, + }, + "utm_policy": "test_utm", + }, + "firewall_authentication": { + "pass_through": { + "access_profile": "WEBAUTH", + "auth_only_browser": True, + "auth_user_agent": "Opera1", + "client_match": "test-client", + "ssl_termination_profile": "test_ssl_term", + "web_redirect": True, + "web_redirect_to_https": True, + }, + "push_to_identity_management": True, + "user_firewall": { + "access_profile": "WEBAUTH", + "auth_only_browser": True, + "auth_user_agent": "Opera1", + "ssl_termination_profile": "test_ssl_term", + "web_redirect": True, + "web_redirect_to_https": True, + }, + "web_authentication": [ + "FWClient1", + "FWClient2", + ], + }, + "tcp_options": { + "initial_tcp_mss": 64, + "reverse_tcp_mss": 64, + "window_scale": True, + }, + }, + }, + }, + ], + }, + ], + }, + ], + "global": { + "policies": [ + { + "match": { + "application": { + "names": ["junos-dhcp-relay"], + }, + "destination_address": { + "addresses": ["a2"], + }, + "source_address": {"addresses": ["a1"]}, + }, + "name": "test_glob_1", + "then": {"deny": True}, + }, + { + "match": { + "application": { + "names": ["junos-dhcp-relay"], + }, + "destination_address": { + "addresses": ["a2"], + }, + "source_address": {"addresses": ["a1"]}, + }, + "name": "test_glob_2", + "then": {"deny": True}, + }, + ], + }, + }, + state="merged", + ), + ) + + result = self.execute_module(changed=True) + + commands = ( + '' + "onetwo" + "test_policy_1a1" + "a3" + "a2a4" + "junos-dhcp-relay" + "junos-fingertest_end_user_profile" + "unknown-user" + "Enhanced_Web_ChatEnhanced_Web_Collaboration" + "any" + " " + "test_policy_2a1" + "a2junos-dhcp-relay" + " test_dyn_app" + " SECURITY-SSL-PROXY" + "one" + "threetest_policy_3" + "a1a2" + "junos-dhcp-relay" + "test_anti_malware" + "" + "test_traffic_controlgtp1" + "sctp1" + "test_icaptest_idp" + " SECURITY-SSL-PROXY" + " test_utm" + "" + " WEBAUTH" + " Opera1" + "test-clienttest_ssl_term" + "" + "Opera1" + " WEBAUTH" + "test_ssl_term " + " " + " FWClient1FWClient2" + "" + " 6464" + "" + "test_glob_1a1" + "a2junos-dhcp-relay" + "" + "test_glob_2a1" + "a2junos-dhcp-relay" + "" + ) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) + + def test_junos_security_policies_merged_02(self): + set_module_args( + dict( + config={ + "from_zones": [ + { + "name": "one", + "to_zones": [ + { + "name": "two", + "policies": [ + { + "match": { + "application": {"any": True}, + "destination_address": { + "any_ipv4": True, + "any_ipv6": True, + "any": True, + }, + "dynamic_application": { + "names": [ + "test1", + "test2", + ], + "none": True, + }, + "source_address": { + "any_ipv4": True, + "any_ipv6": True, + "any": True, + }, + "source_identity": { + "unknown_user": True, + "unauthenticated_user": True, + "authenticated_user": True, + "names": ["test1"], + }, + "url_category": { + "any": True, + "none": True, + }, + }, + "name": "test_policy_1", + "then": { + "count": True, + "deny": True, + "log": {"session_init": True}, + }, + }, + ], + }, + { + "name": "three", + "policies": [ + { + "match": { + "application": { + "names": [ + "junos-dhcp-relay", + ], + }, + "destination_address": { + "any": True, + }, + "source_address": { + "any": True, + }, + }, + "name": "test_policy_3", + "then": { + "permit": { + "application_services": { + "idp": True, + "redirect_wx": True, + "uac_policy": { + "captive_portal": "test", + }, + }, + "firewall_authentication": { + "user_firewall": { + "domain": "test", + }, + }, + "destination_address": "drop-untranslated", + "tunnel": { + "ipsec_vpn": "test_vpn", + "pair_policy": "test_policy", + }, + }, + }, + }, + ], + }, + ], + }, + ], + }, + state="merged", + ), + ) + + result = self.execute_module(changed=True) + + commands = ( + '' + "onetwo" + "test_policy_1any-ipv4" + "any-ipv6any" + "any-ipv4any-ipv6" + "any" + "anyunknown-user" + "unauthenticated-userauthenticated-user" + "test1any" + "nonetest1" + "test2" + "none" + " " + "onethree" + "test_policy_3any" + "anyjunos-dhcp-relay" + "" + " test" + "" + " test" + " " + "" + "" + ) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) + + def test_junos_security_policies_parsed_01(self): + parsed_str = """ + + + + + + one + two + + test_policy_1 + + a1 + a3 + a2 + a4 + + + junos-dhcp-relay + junos-finger + authenticated-user + unknown-user + + test_end_user_profile + + any + Enhanced_Web_Chat + Enhanced_Web_Collaboration + + + + + + + + + + + test_policy_2 + + a1 + a2 + junos-dhcp-relay + + + + test_dyn_app + + SECURITY-SSL-PROXY + + + + + + + one + three + + test_policy_3 + + a1 + a2 + junos-dhcp-relay + + + + + + FWClient1 + FWClient2 + + + WEBAUTH + + Opera1 + test-client + test_ssl_term + + + + + WEBAUTH + + Opera1 + test-client + test_ssl_term + + + + + + + + + + gtp1 + sctp1 + test_idp + + SECURITY-SSL-PROXY + + + test_utm + test_icap + + test_traffic_control + + + test_anti_malware + + + 64 + 64 + + + + + + + + + test_glob_1 + + a1 + a2 + junos-dhcp-relay + + + + + + + test_glob_2 + + a1 + a2 + junos-dhcp-relay + + + + + + + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "from_zones": [ + { + "name": "one", + "to_zones": [ + { + "name": "two", + "policies": [ + { + "match": { + "application": { + "names": [ + "junos-dhcp-relay", + "junos-finger", + ], + }, + "destination_address": { + "addresses": ["a2", "a4"], + }, + "destination_address_excluded": True, + "dynamic_application": {"any": True}, + "source_address": { + "addresses": ["a1", "a3"], + }, + "source_address_excluded": True, + "source_end_user_profile": "test_end_user_profile", + "source_identity": { + "unknown_user": True, + }, + "url_category": { + "names": [ + "Enhanced_Web_Chat", + "Enhanced_Web_Collaboration", + ], + }, + }, + "name": "test_policy_1", + "then": { + "count": True, + "deny": True, + "log": {"session_close": True}, + }, + }, + { + "match": { + "application": { + "names": ["junos-dhcp-relay"], + }, + "destination_address": { + "addresses": ["a2"], + }, + "source_address": { + "addresses": ["a1"], + }, + }, + "name": "test_policy_2", + "then": { + "reject": { + "enable": True, + "profile": "test_dyn_app", + "ssl_proxy": { + "enable": True, + "profile_name": "SECURITY-SSL-PROXY", + }, + }, + }, + }, + ], + }, + { + "name": "three", + "policies": [ + { + "match": { + "application": { + "names": ["junos-dhcp-relay"], + }, + "destination_address": { + "addresses": ["a2"], + }, + "source_address": { + "addresses": ["a1"], + }, + }, + "name": "test_policy_3", + "then": { + "permit": { + "application_services": { + "advanced_anti_malware_policy": "test_anti_malware", + "application_traffic_control_rule_set": "test_traffic_control", + "gprs_gtp_profile": "gtp1", + "gprs_sctp_profile": "sctp1", + "icap_redirect": "test_icap", + "idp_policy": "test_idp", + "reverse_redirect_wx": True, + "ssl_proxy": { + "enable": True, + "profile_name": "SECURITY-SSL-PROXY", + }, + "uac_policy": {"enable": True}, + "utm_policy": "test_utm", + }, + "firewall_authentication": { + "pass_through": { + "access_profile": "WEBAUTH", + "auth_only_browser": True, + "auth_user_agent": "Opera1", + "client_match": "test-client", + "ssl_termination_profile": "test_ssl_term", + "web_redirect": True, + "web_redirect_to_https": True, + }, + "push_to_identity_management": True, + "user_firewall": { + "access_profile": "WEBAUTH", + "auth_only_browser": True, + "auth_user_agent": "Opera1", + "ssl_termination_profile": "test_ssl_term", + "web_redirect": True, + "web_redirect_to_https": True, + }, + "web_authentication": [ + "FWClient1", + "FWClient2", + ], + }, + "tcp_options": { + "initial_tcp_mss": 64, + "reverse_tcp_mss": 64, + "window_scale": True, + }, + }, + }, + }, + ], + }, + ], + }, + ], + "global": { + "policies": [ + { + "match": { + "application": {"names": ["junos-dhcp-relay"]}, + "destination_address": {"addresses": ["a2"]}, + "source_address": {"addresses": ["a1"]}, + }, + "name": "test_glob_1", + "then": {"deny": True}, + }, + { + "match": { + "application": {"names": ["junos-dhcp-relay"]}, + "destination_address": {"addresses": ["a2"]}, + "source_address": {"addresses": ["a1"]}, + }, + "name": "test_glob_2", + "then": {"deny": True}, + }, + ], + }, + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_security_policies_overridden_01(self): + set_module_args( + dict( + config={ + "global": { + "policies": [ + { + "description": "test update", + "match": { + "application": {"any": True}, + "destination_address": {"any_ipv6": True}, + "source_address": {"any": True}, + }, + "name": "test_glob_3", + "then": {"deny": True}, + }, + ], + }, + }, + state="overridden", + ), + ) + commands = ( + '' + "test_glob_3test updateany" + "any-ipv6any" + "" + ) + result = self.execute_module(changed=True) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) + + def test_junos_security_policies_gathered(self): + """ + :return: + """ + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + gather_list = { + "from_zones": [ + { + "name": "one", + "to_zones": [ + { + "name": "two", + "policies": [ + { + "match": { + "application": { + "names": [ + "junos-dhcp-relay", + "junos-finger", + ], + }, + "destination_address": { + "addresses": ["a2", "a4"], + }, + "destination_address_excluded": True, + "dynamic_application": { + "any": True, + "none": True, + "names": ["test"], + }, + "source_address": { + "addresses": ["a1", "a3"], + }, + "source_address_excluded": True, + "source_end_user_profile": "test_end_user_profile", + "source_identity": { + "unknown_user": True, + "unauthenticated_user": True, + "authenticated_user": True, + "any": True, + "names": ["test"], + }, + "url_category": { + "any": True, + "none": True, + "names": [ + "Enhanced_Web_Chat", + "Enhanced_Web_Collaboration", + ], + }, + }, + "name": "test_policy_1", + "then": { + "count": True, + "deny": True, + "log": {"session_close": True}, + }, + }, + { + "match": { + "application": { + "names": ["junos-dhcp-relay"], + }, + "destination_address": { + "addresses": ["a2"], + }, + "source_address": { + "addresses": ["a1"], + }, + }, + "name": "test_policy_2", + "then": { + "reject": { + "enable": True, + "profile": "test_dyn_app", + "ssl_proxy": { + "enable": True, + "profile_name": "SECURITY-SSL-PROXY", + }, + }, + }, + }, + ], + }, + { + "name": "three", + "policies": [ + { + "match": { + "application": {"any": True}, + "destination_address": { + "any": True, + "any_ipv4": True, + "any_ipv6": True, + }, + "source_address": { + "any": True, + "any_ipv4": True, + "any_ipv6": True, + }, + }, + "name": "test_policy_3", + "then": { + "permit": { + "application_services": { + "advanced_anti_malware_policy": "test_anti_malware", + "application_traffic_control_rule_set": "test_traffic_control", + "gprs_gtp_profile": "gtp1", + "gprs_sctp_profile": "sctp1", + "icap_redirect": "test_icap", + "idp": True, + "idp_policy": "test_idp", + "reverse_redirect_wx": True, + "redirect_wx": True, + "ssl_proxy": { + "enable": True, + "profile_name": "SECURITY-SSL-PROXY", + }, + "security_intelligence_policy": "test", + "uac_policy": { + "enable": True, + "captive_portal": "test", + }, + "utm_policy": "test_utm", + }, + "firewall_authentication": { + "pass_through": { + "access_profile": "WEBAUTH", + "auth_only_browser": True, + "auth_user_agent": "Opera1", + "client_match": "test-client", + "ssl_termination_profile": "test_ssl_term", + "web_redirect": True, + "web_redirect_to_https": True, + }, + "push_to_identity_management": True, + "user_firewall": { + "access_profile": "WEBAUTH", + "auth_only_browser": True, + "auth_user_agent": "Opera1", + "ssl_termination_profile": "test_ssl_term", + "web_redirect": True, + "web_redirect_to_https": True, + "domain": "test", + }, + "web_authentication": [ + "FWClient1", + "FWClient2", + ], + }, + "tcp_options": { + "initial_tcp_mss": 64, + "reverse_tcp_mss": 64, + "window_scale": True, + "sequence_check_required": True, + "syn_check_required": True, + }, + "tunnel": { + "ipsec_vpn": "test", + "pair_policy": "test", + }, + }, + }, + }, + ], + }, + ], + }, + ], + "global": { + "policies": [ + { + "match": { + "application": {"names": ["junos-dhcp-relay"]}, + "destination_address": {"addresses": ["a2"]}, + "source_address": {"addresses": ["a1"]}, + }, + "name": "test_glob_1", + "then": {"deny": True, "log": {"session_init": True}}, + }, + { + "match": { + "application": {"names": ["junos-dhcp-relay"]}, + "destination_address": {"addresses": ["a2"]}, + "source_address": {"addresses": ["a1"]}, + }, + "name": "test_glob_2", + "then": {"deny": True}, + }, + ], + }, + } + self.assertEqual(gather_list, result["gathered"]) + + def test_junos_security_policies_rendered(self): + set_module_args( + dict( + config={ + "global": { + "policies": [ + { + "description": "test update", + "match": { + "application": {"any": True}, + "destination_address": {"any_ipv6": True}, + "source_address": {"any": True}, + }, + "name": "test_glob_3", + "then": {"deny": True}, + }, + ], + }, + }, + state="rendered", + ), + ) + rendered = ( + '' + "test_glob_3test update" + "anyany-ipv6" + "any" + "" + ) + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) + + def test_junos_security_policies_replaced_01(self): + set_module_args( + dict( + config={ + "global": { + "policies": [ + { + "description": "test update", + "match": { + "application": {"any": True}, + "destination_address": {"any_ipv6": True}, + "source_address": {"any": True}, + }, + "name": "test_glob_3", + "then": {"deny": True}, + }, + ], + }, + }, + state="replaced", + ), + ) + result = self.execute_module(changed=True) + commands = ( + '' + "test_glob_3test updateany" + "any-ipv6any" + "" + ) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_security_policies_global.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_security_policies_global.py new file mode 100644 index 00000000..1c1131d9 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_security_policies_global.py @@ -0,0 +1,638 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_security_policies_global +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosSecurity_policies_globalModule(TestJunosModule): + module = junos_security_policies_global + + def setUp(self): + super(TestJunosSecurity_policies_globalModule, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.security_policies_global.security_policies_global.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.security_policies_global." + "security_policies_global.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.security_policies_global.security_policies_global." + "Security_policies_globalFacts._get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + self.maxDiff = None + + def tearDown(self): + super(TestJunosSecurity_policies_globalModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + output = load_fixture("junos_security_policies_global_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def sorted_xml(self, xml_string): + temp = [] + index = 0 + while index < len(xml_string): + temp_line = "" + if xml_string[index] == "<": + while index < len(xml_string) and xml_string[index] != ">": + temp_line += xml_string[index] + index += 1 + temp_line += ">" + index += 1 + temp.append(temp_line) + else: + while index < len(xml_string) and xml_string[index] != "<": + temp_line += xml_string[index] + index += 1 + temp.append(temp_line) + return sorted(temp) + + def test_junos_security_policies_global_merged_01(self): + set_module_args( + dict( + config={ + "default_policy": "permit-all", + "policy_rematch": {"enable": True, "extensive": True}, + "policy_stats": {"enable": True, "system_wide": True}, + "pre_id_default_policy_action": { + "log": {"session_init": True, "session_close": True}, + "session_timeout": {"icmp": 10, "others": 10}, + }, + "traceoptions": { + "file": { + "files": 3, + "match": "/[A-Z]*/gm", + "no_world_readable": True, + "size": "10k", + }, + "flag": "all", + "no_remote_trace": True, + }, + }, + state="merged", + ), + ) + result = self.execute_module(changed=True) + commands = ( + '' + " " + " enable" + "" + "1010" + "3" + "/[A-Z]*/gm10k" + "all" + "" + ) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) + + def test_junos_security_policies_global_merged_02(self): + set_module_args( + dict( + config={ + "default_policy": "deny-all", + "policy_rematch": {"enable": True, "extensive": True}, + "policy_stats": {"enable": True, "system_wide": False}, + "pre_id_default_policy_action": { + "log": {"session_init": True}, + "session_timeout": { + "icmp": 10, + "others": 10, + "icmp6": 10, + "ospf": 10, + "tcp": 10, + "udp": 10, + }, + }, + "traceoptions": { + "file": { + "files": 3, + "match": "/[A-Z]*/gm", + "world_readable": True, + "size": "10k", + }, + "flag": "configuration", + "no_remote_trace": True, + }, + }, + state="merged", + ), + ) + result = self.execute_module(changed=True) + commands = ( + '' + " " + " disable" + "" + "10101010" + "1010" + "3/[A-Z]*/gm10k" + "configuration" + "" + ) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) + + def test_junos_security_policies_global_merged_03(self): + set_module_args( + dict( + config={"traceoptions": {"flag": "compilation"}}, + state="merged", + ), + ) + result = self.execute_module(changed=True) + commands = ( + '' + "compilation" + "" + ) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) + + def test_junos_security_policies_global_merged_04(self): + set_module_args( + dict(config={"traceoptions": {"flag": "lookup"}}, state="merged"), + ) + result = self.execute_module(changed=True) + commands = ( + '' + "lookup" + "" + ) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) + + def test_junos_security_policies_global_parsed_01(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + + + 10k + 3 + + /[A-Z]*/gm + + + all + + + + + + + + + + enable + + + + + + + + 10 + 10 + + + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "default_policy": "permit-all", + "policy_rematch": {"enable": True, "extensive": True}, + "policy_stats": {"enable": True, "system_wide": True}, + "pre_id_default_policy_action": { + "log": {"session_init": True}, + "session_timeout": {"icmp": 10, "others": 10}, + }, + "traceoptions": { + "file": { + "files": 3, + "match": "/[A-Z]*/gm", + "no_world_readable": True, + "size": "10k", + }, + "flag": "compilation", + "no_remote_trace": True, + }, + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_security_policies_global_parsed_02(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + + 10k + 3 + + /[A-Z]*/gm + + + compilation + + + + + + + disable + + + + + + + + 10 + 10 + 10 + 10 + 10 + 10 + + + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "default_policy": "deny-all", + "policy_stats": {"enable": True, "system_wide": False}, + "pre_id_default_policy_action": { + "log": {"session_close": True}, + "session_timeout": { + "icmp": 10, + "others": 10, + "ospf": 10, + "icmp6": 10, + "tcp": 10, + "udp": 10, + }, + }, + "traceoptions": { + "file": { + "files": 3, + "match": "/[A-Z]*/gm", + "world_readable": True, + "size": "10k", + }, + "flag": "compilation", + }, + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_security_policies_global_parsed_03(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + + configuration + + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = {"traceoptions": {"flag": "configuration"}} + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_security_policies_global_parsed_04(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + + ipc + + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = {"traceoptions": {"flag": "ipc"}} + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_security_policies_global_parsed_05(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + + lookup + + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = {"traceoptions": {"flag": "lookup"}} + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_security_policies_global_parsed_06(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + + routing-socket + + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = {"traceoptions": {"flag": "routing-socket"}} + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_security_policies_global_parsed_07(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + + rules + + + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = {"traceoptions": {"flag": "rules"}} + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_security_policies_global_overridden_01(self): + set_module_args( + dict( + config={ + "default_policy": "permit-all", + "policy_rematch": {"enable": True, "extensive": True}, + "policy_stats": {"enable": True, "system_wide": True}, + "pre_id_default_policy_action": { + "log": {"session_init": True}, + "session_timeout": {"icmp": 10, "others": 10}, + }, + "traceoptions": { + "file": { + "files": 3, + "match": "/[A-Z]*/gm", + "no_world_readable": True, + "size": "10k", + }, + "flag": "ipc", + "no_remote_trace": True, + }, + }, + state="overridden", + ), + ) + result = self.execute_module(changed=True) + print(result["commands"]) + commands = ( + '' + " " + " enable" + "" + "1010" + "3" + "/[A-Z]*/gm10k" + "ipc" + '' + ) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) + + def test_junos_security_policies_global_gathered(self): + """ + :return: + """ + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + gather_list = { + "default_policy": "permit-all", + "policy_rematch": {"enable": True, "extensive": True}, + "policy_stats": {"enable": True, "system_wide": True}, + "pre_id_default_policy_action": { + "log": {"session_init": True}, + "session_timeout": {"icmp": 10, "others": 10}, + }, + "traceoptions": { + "file": { + "files": 3, + "match": "/[A-Z]*/gm", + "no_world_readable": True, + "size": "10k", + }, + "flag": "lookup", + "no_remote_trace": True, + }, + } + self.assertEqual(sorted(gather_list), sorted(result["gathered"])) + + def test_junos_security_policies_global_rendered(self): + set_module_args( + dict( + config={ + "default_policy": "permit-all", + "policy_rematch": {"enable": True, "extensive": True}, + "policy_stats": {"enable": True, "system_wide": True}, + "pre_id_default_policy_action": { + "log": {"session_init": True}, + "session_timeout": {"icmp": 10, "others": 10}, + }, + "traceoptions": { + "file": { + "files": 3, + "match": "/[A-Z]*/gm", + "no_world_readable": True, + "size": "10k", + }, + "flag": "routing-socket", + "no_remote_trace": True, + }, + }, + state="rendered", + ), + ) + rendered = ( + '' + " " + " enable" + "" + "1010" + "3" + "/[A-Z]*/gm10k" + "routing-socket" + "" + ) + result = self.execute_module(changed=False) + print(self.sorted_xml(result["rendered"])) + print(self.sorted_xml(rendered)) + self.assertEqual( + self.sorted_xml(result["rendered"]), + self.sorted_xml(rendered), + ) + + def test_junos_security_policies_global_replaced_01(self): + set_module_args( + dict( + config={ + "default_policy": "permit-all", + "policy_rematch": {"enable": True, "extensive": True}, + "policy_stats": {"enable": True, "system_wide": True}, + "pre_id_default_policy_action": { + "log": {"session_init": True}, + "session_timeout": {"icmp": 10, "others": 10}, + }, + "traceoptions": { + "file": { + "files": 3, + "match": "/[A-Z]*/gm", + "no_world_readable": True, + "size": "10k", + }, + "flag": "rules", + "no_remote_trace": True, + }, + }, + state="replaced", + ), + ) + result = self.execute_module(changed=True) + commands = ( + '' + " " + " enable" + "" + "1010" + "3" + "/[A-Z]*/gm10k" + "rules" + '' + ) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_security_zones.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_security_zones.py new file mode 100644 index 00000000..b5eb0385 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_security_zones.py @@ -0,0 +1,1245 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_security_zones +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosSecurity_zonesModule(TestJunosModule): + module = junos_security_zones + + def setUp(self): + super(TestJunosSecurity_zonesModule, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.security_zones.security_zones.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.security_zones.security_zones.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.security_zones.security_zones." + "Security_zonesFacts._get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosSecurity_zonesModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + output = load_fixture("junos_security_zones_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def sorted_xml(self, xml_string): + temp = [] + index = 0 + while index < len(xml_string): + temp_line = "" + if xml_string[index] == "<": + while index < len(xml_string) and xml_string[index] != ">": + temp_line += xml_string[index] + index += 1 + temp_line += ">" + index += 1 + temp.append(temp_line) + else: + while index < len(xml_string) and xml_string[index] != "<": + temp_line += xml_string[index] + index += 1 + temp.append(temp_line) + return sorted(temp) + + def test_junos_security_zones_merged_01(self): + set_module_args( + dict( + config={ + "functional_zone_management": { + "description": "test description", + "host_inbound_traffic": { + "protocols": [ + {"name": "all"}, + {"except": True, "name": "bgp"}, + ], + "system_services": [ + {"name": "all"}, + {"except": True, "name": "dhcp"}, + ], + }, + "interfaces": ["ge-0/0/1.0", "ge-0/0/2.0"], + "screen": "test_screen", + }, + "zones": [ + { + "address_book": { + "address_sets": [ + { + "addresses": [ + "test_adr1", + "test_adr2", + ], + "name": "test_adrset1", + }, + { + "addresses": [ + "test_adr3", + "test_adr4", + ], + "name": "test_adrset2", + }, + { + "address_sets": [ + "test_adrset1", + "test_adrset2", + ], + "addresses": ["test_adr5"], + "description": "test description", + "name": "test_adrset3", + }, + ], + "addresses": [ + { + "description": "test desc", + "ip_prefix": "10.0.0.0/24", + "name": "test_adr1", + }, + { + "dns_name": { + "ipv6_only": True, + "name": "1.1.1.1", + }, + "name": "test_adr2", + }, + { + "name": "test_adr3", + "range_address": { + "from": "10.2.0.1", + "to": "10.2.0.2", + }, + }, + { + "name": "test_adr4", + "wildcard_address": "10.3.0.1/24", + }, + { + "description": "test desc", + "ip_prefix": "10.1.0.0/24", + "name": "test_adr5", + }, + ], + }, + "advance_policy_based_routing_profile": "test_profile", + "advanced_connection_tracking": { + "mode": "allow-any-host", + "timeout": "20", + "track_all_policies_to_this_zone": True, + }, + "application_tracking": True, + "description": "test description", + "enable_reverse_reroute": True, + "host_inbound_traffic": { + "protocols": [ + {"name": "all"}, + {"except": True, "name": "bgp"}, + ], + "system_services": [ + {"name": "all"}, + {"except": True, "name": "dhcp"}, + ], + }, + "interfaces": ["ge-0/0/3.0", "ge-0/0/4.0"], + "name": "test_sec_zone1", + "screen": "test_screen", + "source_identity_log": True, + "tcp_rst": True, + "unidirectional_session_refreshing": True, + }, + ], + }, + state="merged", + ), + ) + result = self.execute_module(changed=True) + commands = ( + 't' + "est descriptionallbgpalldhcpge-0/0/1.0ge-0/0/2.0test_screentest_sec_zone1test_adr110.0.0.0/24test desctest_adr21.1.1.1test_adr310.2.0.110.2.0.2test_adr410.3.0.1/24test_adr510.1.0.0/24test desctest_adrset1test_adr1test" + "_adr2test_adrset2test_adr3test_adr4test_adrset3test_adr5test_adrset1test_adrset2test descriptiontest_profileallow-any-host20test descriptionallbgpalldhcpge-0/0/3.0ge-0/0/4.0
test_screen
" + ) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) + + def test_junos_security_zones_parsed(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + + test description + + + all + + + bgp + + + + all + + + dhcp + + + + + ge-0/0/1.0 + + + ge-0/0/2.0 + + test_screen + + + + test_sec_zone1 + +
+ test_adr1 + 10.0.0.0/24 + test desc +
+
+ test_adr2 + + 1.1.1.1 + + +
+
+ test_adr3 + + 10.2.0.1 + + 10.2.0.2 + + +
+
+ test_adr4 + + 10.3.0.1/24 + +
+
+ test_adr5 + 10.1.0.0/24 + test desc +
+ + test_adrset1 +
+ test_adr1 +
+
+ test_adr2 +
+
+ + test_adrset2 +
+ test_adr3 +
+
+ test_adr4 +
+
+ + test_adrset3 +
+ test_adr5 +
+ + test_adrset1 + + + test_adrset2 + + test description +
+
+ + test_profile + + + allow-any-host + 20 + + + + test description + + + + all + + + bgp + + + + all + + + dhcp + + + + + ge-0/0/3.0 + + test_screen + + + +
+
+
+
+
+ """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "functional_zone_management": { + "description": "test description 2", + "host_inbound_traffic": { + "protocols": [ + {"name": "all"}, + {"except": True, "name": "bgp"}, + {"except": True, "name": "bfd"}, + ], + "system_services": [ + {"name": "all"}, + {"except": True, "name": "dhcp"}, + {"except": True, "name": "dhcpv6"}, + ], + }, + "interfaces": ["ge-0/0/1.0", "ge-0/0/2.0"], + "screen": "test_screen", + }, + "zones": [ + { + "address_book": { + "address_sets": [ + { + "addresses": ["test_adr1", "test_adr2"], + "name": "test_adrset1", + }, + { + "addresses": ["test_adr3", "test_adr4"], + "name": "test_adrset2", + }, + { + "address_sets": [ + "test_adrset1", + "test_adrset2", + ], + "addresses": ["test_adr5"], + "description": "test description", + "name": "test_adrset3", + }, + ], + "addresses": [ + { + "description": "test desc", + "ip_prefix": "10.0.0.0/24", + "name": "test_adr1", + }, + { + "dns_name": { + "ipv6_only": True, + "name": "1.1.1.1", + }, + "name": "test_adr2", + }, + { + "name": "test_adr3", + "range_address": { + "from": "10.2.0.1", + "to": "10.2.0.2", + }, + }, + { + "name": "test_adr4", + "wildcard_address": "10.3.0.1/24", + }, + { + "description": "test desc", + "ip_prefix": "10.1.0.0/24", + "name": "test_adr5", + }, + ], + }, + "advance_policy_based_routing_profile": "test_profile", + "advanced_connection_tracking": { + "mode": "allow-any-host", + "timeout": "20", + "track_all_policies_to_this_zone": True, + }, + "application_tracking": True, + "description": "test description", + "enable_reverse_reroute": True, + "host_inbound_traffic": { + "protocols": [ + {"name": "all"}, + {"except": True, "name": "bgp"}, + ], + "system_services": [ + {"name": "all"}, + {"except": True, "name": "dhcp"}, + ], + }, + "interfaces": {"ge-0/0/3.0"}, + "name": "test_sec_zone1", + "screen": "test_screen", + "source_identity_log": True, + "tcp_rst": True, + "unidirectional_session_refreshing": True, + }, + { + "name": "test_sec_zone2", + "source_identity_log": True, + "tcp_rst": True, + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_security_zones_parsed_01(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + + + test description + + + all + + + bgp + + + + all + + + dhcp + + + + + ge-0/0/1.0 + + + ge-0/0/2.0 + + test_screen + + + + test_sec_zone1 + +
+ test_adr1 + 10.0.0.0/24 + test desc +
+
+ test_adr2 + + 1.1.1.1 + + +
+
+ test_adr3 + + 10.2.0.1 + + 10.2.0.2 + + +
+
+ test_adr4 + + 10.3.0.1/24 + +
+
+ test_adr5 + 10.1.0.0/24 + test desc +
+ + test_adrset1 +
+ test_adr1 +
+
+ test_adr2 +
+
+ + test_adrset2 +
+ test_adr3 +
+
+ test_adr4 +
+
+ + test_adrset3 +
+ test_adr5 +
+ + test_adrset1 + + + test_adrset2 + + test description +
+
+ + test_profile + + + allow-any-host + 20 + + + + test description + + + + all + + + bgp + + + + all + + + dhcp + + + + + ge-0/0/3.0 + + + ge-0/0/4.0 + + test_screen + + + +
+
+
+
+
+ """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "functional_zone_management": { + "description": "test description 2", + "host_inbound_traffic": { + "protocols": [ + {"name": "all"}, + {"except": True, "name": "bgp"}, + {"except": True, "name": "bfd"}, + ], + "system_services": [ + {"name": "all"}, + {"except": True, "name": "dhcp"}, + {"except": True, "name": "dhcpv6"}, + ], + }, + "interfaces": ["ge-0/0/1.0", "ge-0/0/2.0"], + "screen": "test_screen", + }, + "zones": [ + { + "address_book": { + "address_sets": [ + { + "addresses": ["test_adr1", "test_adr2"], + "name": "test_adrset1", + }, + { + "addresses": ["test_adr3", "test_adr4"], + "name": "test_adrset2", + }, + { + "address_sets": [ + "test_adrset1", + "test_adrset2", + ], + "addresses": ["test_adr5"], + "description": "test description", + "name": "test_adrset3", + }, + ], + "addresses": [ + { + "description": "test desc", + "ip_prefix": "10.0.0.0/24", + "name": "test_adr1", + }, + { + "dns_name": { + "ipv6_only": True, + "name": "1.1.1.1", + }, + "name": "test_adr2", + }, + { + "name": "test_adr3", + "range_address": { + "from": "10.2.0.1", + "to": "10.2.0.2", + }, + }, + { + "name": "test_adr4", + "wildcard_address": "10.3.0.1/24", + }, + { + "description": "test desc", + "ip_prefix": "10.1.0.0/24", + "name": "test_adr5", + }, + ], + }, + "advance_policy_based_routing_profile": "test_profile", + "advanced_connection_tracking": { + "mode": "allow-any-host", + "timeout": "20", + "track_all_policies_to_this_zone": True, + }, + "application_tracking": True, + "description": "test description", + "enable_reverse_reroute": True, + "host_inbound_traffic": { + "protocols": [ + {"name": "all"}, + {"except": True, "name": "bgp"}, + ], + "system_services": [ + {"name": "all"}, + {"except": True, "name": "dhcp"}, + ], + }, + "interfaces": ["ge-0/0/3.0", "ge-0/0/4.0"], + "name": "test_sec_zone1", + "screen": "test_screen", + "source_identity_log": True, + "tcp_rst": True, + "unidirectional_session_refreshing": True, + }, + { + "name": "test_sec_zone2", + "source_identity_log": True, + "tcp_rst": True, + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_security_zones_overridden_01(self): + set_module_args( + dict( + config={ + "functional_zone_management": { + "description": "test description 2", + "host_inbound_traffic": { + "protocols": [{"name": "all"}], + "system_services": [{"name": "all"}], + }, + "interfaces": ["ge-0/0/1.0", "ge-0/0/2.0"], + "screen": "test_screen", + }, + "zones": [ + { + "address_book": { + "address_sets": [ + { + "addresses": [ + "test_adr1", + "test_adr2", + ], + "name": "test_adrset1", + }, + { + "addresses": [ + "test_adr3", + "test_adr4", + ], + "name": "test_adrset2", + }, + { + "address_sets": [ + "test_adrset1", + "test_adrset2", + ], + "addresses": ["test_adr5"], + "description": "test description", + "name": "test_adrset3", + }, + ], + "addresses": [ + { + "description": "test desc", + "ip_prefix": "10.0.0.0/24", + "name": "test_adr1", + }, + { + "dns_name": { + "ipv6_only": True, + "name": "1.1.1.1", + }, + "name": "test_adr2", + }, + { + "name": "test_adr3", + "range_address": { + "from": "10.2.0.1", + "to": "10.2.0.2", + }, + }, + { + "name": "test_adr4", + "wildcard_address": "10.3.0.1/24", + }, + { + "description": "test desc", + "ip_prefix": "10.1.0.0/24", + "name": "test_adr5", + }, + ], + }, + "advance_policy_based_routing_profile": "test_profile", + "application_tracking": True, + "description": "test description", + "enable_reverse_reroute": True, + "host_inbound_traffic": { + "protocols": [ + {"name": "all"}, + {"except": True, "name": "bgp"}, + ], + "system_services": [ + {"name": "all"}, + {"except": True, "name": "dhcp"}, + ], + }, + "interfaces": ["ge-0/0/3.0", "ge-0/0/4.0"], + "name": "test_sec_zone1", + "screen": "test_screen", + "source_identity_log": True, + "tcp_rst": True, + }, + ], + }, + state="overridden", + ), + ) + result = self.execute_module(changed=True) + commands = ( + 'test description 2allallge-0" + "/0/1.0ge-0/0/2.0test_screentest_sec_zone1test" + "_adr110.0.0.0/24test desctest_adr21.1.1.1test" + "_adr310.2.0.110.2.0.2test_adr410.3.0.1/24test_adr510.1.0.0/24test desctest_adrset1test_adr1test_adr2test_adrset2test_adr3test_adr4test_adrset3test_adr5test_adrset1test_adrset2test description" + "test_profiletest descriptionallbgpalldhcpge-0/0/3.0ge-0/0/4.0test_screen" + ) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) + + def test_junos_security_zones_gathered(self): + """ + :return: + """ + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + gather_list = { + "functional_zone_management": { + "description": "test description 2", + "host_inbound_traffic": { + "protocols": [ + {"name": "all"}, + {"except": True, "name": "bgp"}, + {"except": True, "name": "bfd"}, + ], + "system_services": [ + {"name": "all"}, + {"except": True, "name": "dhcp"}, + {"except": True, "name": "dhcpv6"}, + ], + }, + "interfaces": ["ge-0/0/1.0", "ge-0/0/2.0"], + "screen": "test_screen", + }, + "zones": [ + { + "address_book": { + "address_sets": [ + { + "addresses": ["test_adr1", "test_adr2"], + "name": "test_adrset1", + }, + { + "addresses": ["test_adr3", "test_adr4"], + "name": "test_adrset2", + }, + { + "address_sets": [ + "test_adrset1", + "test_adrset2", + ], + "addresses": ["test_adr5"], + "description": "test description", + "name": "test_adrset3", + }, + ], + "addresses": [ + { + "description": "test desc", + "ip_prefix": "10.0.0.0/24", + "name": "test_adr1", + }, + { + "dns_name": { + "ipv6_only": True, + "name": "1.1.1.1", + }, + "name": "test_adr2", + }, + { + "name": "test_adr3", + "range_address": { + "from": "10.2.0.1", + "to": "10.2.0.2", + }, + }, + { + "name": "test_adr4", + "wildcard_address": "10.3.0.1/24", + }, + { + "description": "test desc", + "ip_prefix": "10.1.0.0/24", + "name": "test_adr5", + }, + ], + }, + "advance_policy_based_routing_profile": "test_profile", + "application_tracking": True, + "description": "test description", + "enable_reverse_reroute": True, + "host_inbound_traffic": { + "protocols": [ + {"name": "all"}, + {"except": True, "name": "bgp"}, + ], + "system_services": [ + {"name": "all"}, + {"except": True, "name": "dhcp"}, + ], + }, + "interfaces": ["ge-0/0/3.0", "ge-0/0/4.0"], + "name": "test_sec_zone1", + "screen": "test_screen", + "source_identity_log": True, + "tcp_rst": True, + }, + { + "name": "test_sec_zone2", + "source_identity_log": True, + "tcp_rst": True, + }, + ], + } + self.assertEqual(sorted(gather_list), sorted(result["gathered"])) + + def test_junos_security_zones_rendered(self): + set_module_args( + dict( + config={ + "functional_zone_management": { + "description": "test description", + "host_inbound_traffic": { + "protocols": [ + {"name": "all"}, + {"except": True, "name": "bgp"}, + ], + "system_services": [ + {"name": "all"}, + {"except": True, "name": "dhcp"}, + ], + }, + "interfaces": ["ge-0/0/1.0", "ge-0/0/2.0"], + "screen": "test_screen", + }, + "zones": [ + { + "address_book": { + "address_sets": [ + { + "addresses": [ + "test_adr1", + "test_adr2", + ], + "name": "test_adrset1", + }, + { + "addresses": [ + "test_adr3", + "test_adr4", + ], + "name": "test_adrset2", + }, + { + "address_sets": [ + "test_adrset1", + "test_adrset2", + ], + "addresses": ["test_adr5"], + "description": "test description", + "name": "test_adrset3", + }, + ], + "addresses": [ + { + "description": "test desc", + "ip_prefix": "10.0.0.0/24", + "name": "test_adr1", + }, + { + "dns_name": { + "ipv6_only": True, + "name": "1.1.1.1", + }, + "name": "test_adr2", + }, + { + "name": "test_adr3", + "range_address": { + "from": "10.2.0.1", + "to": "10.2.0.2", + }, + }, + { + "name": "test_adr4", + "wildcard_address": "10.3.0.1/24", + }, + { + "description": "test desc", + "ip_prefix": "10.1.0.0/24", + "name": "test_adr5", + }, + ], + }, + "advance_policy_based_routing_profile": "test_profile", + "application_tracking": True, + "description": "test description", + "enable_reverse_reroute": True, + "host_inbound_traffic": { + "protocols": [ + {"name": "all"}, + {"except": True, "name": "bgp"}, + ], + "system_services": [ + {"name": "all"}, + {"except": True, "name": "dhcp"}, + ], + }, + "interfaces": ["ge-0/0/3.0", "ge-0/0/4.0"], + "name": "test_sec_zone1", + "screen": "test_screen", + "source_identity_log": True, + "tcp_rst": True, + }, + ], + }, + state="rendered", + ), + ) + rendered = ( + 't' + "est descriptionallbgpalldhcpge-0/0/1.0ge-0/0/2.0test_screentest_sec_zone1test_adr110.0.0.0/24test desctest_adr21.1.1.1test_adr310.2.0.110.2.0.2test_adr410.3.0.1/24test_adr510.1.0.0/24test desctest_adrset1test_adr1test" + "_adr2test_adrset2test_adr3test_adr4test_adrset3test_adr5test_adrset1test_adrset2test descriptiontest_profiletest descriptionallbgpalldhcpge-0/0/3.0ge-0/0/4.0test_screen" + ) + result = self.execute_module(changed=False) + self.assertEqual( + self.sorted_xml(result["rendered"]), + self.sorted_xml(rendered), + ) + + def test_junos_security_zones_replaced_01(self): + set_module_args( + dict( + config={ + "functional_zone_management": { + "description": "test description 2", + "host_inbound_traffic": { + "protocols": [{"name": "all"}], + "system_services": [{"name": "all"}], + }, + "interfaces": ["ge-0/0/1.0", "ge-0/0/2.0"], + "screen": "test_screen", + }, + "zones": [ + { + "address_book": { + "address_sets": [ + { + "addresses": [ + "test_adr1", + "test_adr2", + ], + "name": "test_adrset1", + }, + { + "addresses": [ + "test_adr3", + "test_adr4", + ], + "name": "test_adrset2", + }, + { + "address_sets": [ + "test_adrset1", + "test_adrset2", + ], + "addresses": ["test_adr5"], + "description": "test description", + "name": "test_adrset3", + }, + ], + "addresses": [ + { + "description": "test desc", + "ip_prefix": "10.0.0.0/24", + "name": "test_adr1", + }, + { + "dns_name": { + "ipv6_only": True, + "name": "1.1.1.1", + }, + "name": "test_adr2", + }, + { + "name": "test_adr3", + "range_address": { + "from": "10.2.0.1", + "to": "10.2.0.2", + }, + }, + { + "name": "test_adr4", + "wildcard_address": "10.3.0.1/24", + }, + { + "description": "test desc", + "ip_prefix": "10.1.0.0/24", + "name": "test_adr5", + }, + ], + }, + "advance_policy_based_routing_profile": "test_profile", + "application_tracking": True, + "description": "test description", + "enable_reverse_reroute": True, + "host_inbound_traffic": { + "protocols": [ + {"name": "all"}, + {"except": True, "name": "bgp"}, + ], + "system_services": [ + {"name": "all"}, + {"except": True, "name": "dhcp"}, + ], + }, + "interfaces": ["ge-0/0/3.0", "ge-0/0/4.0"], + "name": "test_sec_zone1", + "screen": "test_screen", + "source_identity_log": True, + "tcp_rst": True, + }, + ], + }, + state="replaced", + ), + ) + result = self.execute_module(changed=True) + commands = ( + 'test description 2allallge-0" + "/0/1.0ge-0/0/2.0test_screentest_sec_zone1test" + "_adr110.0.0.0/24test desctest_adr21.1.1.1test" + "_adr310.2.0.110.2.0.2test_adr410.3.0.1/24test_adr510.1.0.0/24test desctest_adrset1test_adr1test_adr2test_adrset2test_adr3test_adr4test_adrset3test_adr5test_adrset1test_adrset2test description" + "test_profiletest descriptionallbgpalldhcpge-0/0/3.0ge-0/0/4.0test_screen" + ) + self.assertEqual( + self.sorted_xml(commands), + self.sorted_xml(str(result["commands"])), + ) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_snmp_server.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_snmp_server.py new file mode 100644 index 00000000..f29381a1 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_snmp_server.py @@ -0,0 +1,1083 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_snmp_server +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosSnmp_serverModule(TestJunosModule): + module = junos_snmp_server + + def setUp(self): + super(TestJunosSnmp_serverModule, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.snmp_server.snmp_server.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.snmp_server.snmp_server.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.snmp_server.snmp_server." + "Snmp_serverFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosSnmp_serverModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + output = load_fixture("junos_snmp_server_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def test_junos_snmp_server_merged_arp_01(self): + set_module_args( + dict( + config=dict(arp=dict(set=True, host_name_resolution=True)), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + '', + str(result["commands"]), + ) + self.assertIn( + "", + str(result["commands"]), + ) + + def test_junos_snmp_server_merged_views(self): + set_module_args( + dict( + config=dict( + views=[ + dict( + name="all", + oids=[dict(oid=".1")], + ), + ], + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + '', + str(result["commands"]), + ) + self.assertIn( + "all.1", + str(result["commands"]), + ) + self.assertIn( + "", + str(result["commands"]), + ) + + def test_junos_snmp_server_merged_trap_options(self): + set_module_args( + dict( + config=dict( + trap_options=dict( + agent_address=dict( + outgoing_interface=True, + ), + context_oid=True, + ), + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + '', + str(result["commands"]), + ) + self.assertIn( + "outgoing-interface", + str(result["commands"]), + ) + self.assertIn( + "", + str(result["commands"]), + ) + + def test_junos_snmp_server_merged_trap_groups(self): + set_module_args( + dict( + config=dict( + trap_groups=[ + dict( + categories=dict( + authentication=True, + ), + name="egress", + ), + ], + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + '', + str(result["commands"]), + ) + self.assertIn( + "egress", + str(result["commands"]), + ) + self.assertIn( + "", + str(result["commands"]), + ) + + def test_junos_snmp_server_merged_trap_groups_02(self): + set_module_args( + dict( + config=dict( + trap_groups=[ + dict( + categories=dict( + chassis=True, + chassis_cluster=True, + configuration=True, + dot3oam_events=True, + link=True, + ), + name="monitor", + ), + ], + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + '', + str(result["commands"]), + ) + self.assertIn( + "", + str(result["commands"]), + ) + + def test_junos_snmp_server_merged_trap_groups_otn_alrams(self): + set_module_args( + dict( + config=dict( + trap_groups=[ + dict( + categories=dict( + otn_alarms=dict( + oc_lof=True, + oc_lom=True, + oc_los=True, + ), + ), + name="monitor", + ), + ], + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + '', + str(result["commands"]), + ) + self.assertIn( + "", + str(result["commands"]), + ) + self.assertIn( + "monitor", + str(result["commands"]), + ) + + def test_junos_snmp_server_merged_trap_options_set(self): + set_module_args( + dict( + config=dict( + trap_options=dict( + set=True, + ), + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + expected_commands = '' + self.assertEqual(expected_commands, "/n".join(result["commands"])) + + def test_junos_snmp_server_merged_trap_options_02(self): + set_module_args( + dict( + config=dict( + trap_options=dict( + enterprise_oid=True, + source_address=dict( + address="192.168.2.0", + ), + ), + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + '', + str(result["commands"]), + ) + self.assertIn( + "192.168.2.0", + str(result["commands"]), + ) + self.assertIn( + "", + str(result["commands"]), + ) + + def test_junos_snmp_server_merged_client_02(self): + set_module_args( + dict( + config=dict( + client_lists=[ + dict( + name="cl2", + addresses=[dict(address="192.16.4.0/24")], + ), + ], + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + self.assertIn( + '', + str(result["commands"]), + ) + self.assertIn( + "cl2", + str(result["commands"]), + ) + self.assertIn( + "192.16.4.0/24", + str(result["commands"]), + ) + self.assertIn( + "", + str(result["commands"]), + ) + + def test_junos_snmp_server_merged_clients_03(self): + set_module_args( + dict( + config=dict( + client_lists=[ + dict( + name="cl3", + addresses=[ + dict(address="172.16.1.0/24"), + dict(address="10.11.11.11", restrict=True), + ], + ), + dict( + name="cl4", + addresses=[dict(address="172.16.4.0/24")], + ), + ], + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + commands = [ + '', + "cl3", + "172.16.1.0/24", + "", + "10.11.11.11", + "cl4", + "172.16.4.0/24", + "", + ] + for command in commands: + self.assertIn(command, str(result["commands"])) + + def test_junos_snmp_server_merged_routing_access_04(self): + set_module_args( + dict( + config=dict( + routing_instance_access=dict( + set=True, + access_lists=["clv1"], + ), + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + commands = [ + '', + "clv1", + "", + ] + for command in commands: + self.assertIn(command, str(result["commands"])) + + def test_junos_snmp_server_merged_communities_05(self): + set_module_args( + dict( + config=dict( + communities=[ + dict( + name="comm1", + clients=[ + dict(address="24.0.0.0/32", restrict=True), + ], + routing_instances=[ + dict( + name="clv1", + clients=[ + dict( + address="13.13.13.13/24", + restrict=True, + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + commands = [ + '' + "comm1", + "24.0.0.0/32", + "clv1", + "13.13.13.13/24", + "", + ] + for command in commands: + self.assertIn(command, str(result["commands"])) + + def test_junos_snmp_server_merged_06(self): + set_module_args( + dict( + config=dict( + communities=[ + dict( + name="comm1", + clients=[ + dict(address="24.0.0.0/32", restrict=True), + dict(address="30.0.0.0/32", restrict=True), + ], + routing_instances=[ + dict( + name="clv1", + clients=[ + dict( + address="13.13.13.13/24", + restrict=True, + ), + dict(address="24.0.0.0/32"), + dict(address="30.0.0.0/32"), + ], + ), + dict( + name="clv2", + clients=[dict(address="15.15.15.15/24")], + ), + ], + ), + dict(name="comm2"), + ], + contact="rohitthakur2590", + customization=dict(ether_stats_ifd_only=True), + description="Local SNMP Server", + engine_id=dict( + local="local1", + use_default_ip_address=True, + use_mac_address=True, + ), + filter_duplicates=True, + filter_interfaces=dict( + all_internal_interfaces=True, + interfaces=["eth1", "eth2"], + ), + health_monitor=dict( + falling_threshold=50, + idp=True, + interval=100, + rising_threshold=60, + ), + if_count_with_filter_interfaces=True, + interfaces=["eth1", "eth2", "eth3"], + location="inter_lab", + logical_system_trap_filter=True, + name="SNMP_LAB_SERVER", + nonvolatile=dict(commit_delay=30), + rmon=dict( + alarms=[ + dict( + id=4, + variable="1.x.y.z", + sample_type="absolute-value", + rising_threshold=1020, + ), + dict( + id=5, + variable="1.x.y.z", + sample_type="absolute-value", + rising_threshold=1020, + ), + ], + events=[ + dict(id=100, type="log"), + dict(id=200, type="log"), + ], + ), + routing_instance_access=dict( + access_lists=["clv1", "clv2"], + ), + subagent=dict(tcp=dict(routing_instances_default=True)), + snmp_v3=dict( + notify=[dict(name="not1", type="inform", tag="tag2")], + notify_filter=[ + dict( + name="not_fil_01", + oids=[dict(include=True, oid="1.a.s.b.d")], + ), + dict( + name="not_fil_02", + oids=[ + dict(include=True, oid="1.x.b.b.d"), + dict(include=True, oid="1.a.c.b.d"), + ], + ), + ], + snmp_community=[ + dict( + community_index="v3_comm1", + community_name="mycommu", + security_name="sec101", + context="cont1", + tag="109", + ), + dict( + community_index="v3_comm2", + community_name="mycomm", + security_name="sec102", + context="cont1", + tag="109", + ), + ], + target_addresses=[ + dict( + name="tar201", + address="162.12.10.2", + port=23122, + timeout=300, + retry_count=200, + tag_list="tag101", + address_mask="24", + routing_instance="clv2", + target_parameters="tarparam2", + ), + dict( + name="tar202", + address="162.12.10.2", + port=23122, + timeout=300, + retry_count=200, + tag_list="tag101", + address_mask="24", + routing_instance="clv2", + target_parameters="tarparam2", + ), + ], + target_parameters=[ + dict( + name="param111", + notify_filter="not121", + parameters=dict( + message_processing_model="v1", + security_model="v1", + security_level="none", + security_name="secure111", + ), + ), + ], + ), + traceoptions=dict( + file=dict( + files=20, + match="snmp_cfg", + no_world_readable=True, + size=20000, + ), + flag=dict( + all=True, + general=True, + interface_stats=True, + nonvolatile_sets=True, + pdu=True, + protocol_timeouts=True, + routing_socket=True, + subagent=True, + timer=True, + varbind_error=True, + ), + memory_trace=dict(size=1350), + ), + trap_groups=[ + dict( + name="trgrp_01", + destination_port=2346, + categories=dict( + authentication=True, + chassis=True, + otn_alarms=dict( + oc_lof=True, + otu_uas_threshold=True, + ), + ), + targets=["11.11.11.11", "12.12.12.12"], + routing_instance="clv1", + ), + ], + ), + state="merged", + ), + ) + result = self.execute_module(changed=True) + commands = [ + '', + "clv1", + "clv2", + "comm1", + "24.0.0.0/3230.0.0.0/32", + "clv1", + "13.13.13.13/2424.0.0.0/32", + "30.0.0.0/32", + "clv215.15.15.15/24", + "comm2", + "rohitthakur2590", + "Local SNMP Server", + "local1", + ] + for command in commands: + self.assertIn(command, str(result["commands"])) + + def test_junos_snmp_server_parsed_07(self): + parsed_str = """ + + + 18.4R1-S2.4 + + SNMP_LAB_SERVER + Local SNMP Server + inter_lab + rohitthakur2590 + eth1.0 + eth2.0 + eth3.0 + + + eth1 + + + eth2 + + + + + + + 30 + + + + tar201 +
162.12.10.2
+ 23122 + 300 + 200 + tag101 + 24.0.0.0 + clv2 + tarparam2 +
+ + tar202 +
162.12.10.2
+ 23122 + 300 + 200 + tag101 + 24.0.0.0 + clv2 + tarparam2 +
+ + param111 + + v1 + v1 + none + secure111 + + + not121 + + + + not1 + inform + tag2 + + + not_fil_01 + + 1.a.s.b.d + + + + + not_fil_02 + + 1.x.b.b.d + + + + 1.a.c.b.d + + + + + v3_comm1 + $9$gUoGiQF/tpB5QORhr8LjHq + sec101 + cont1 + 109 + + + v3_comm2 + $9$9te0A0IKMX-dslKwgoGq. + sec102 + cont1 + 109 + +
+ + + + + + + + + + + + comm1 + + 24.0.0.0/32 + + + + 30.0.0.0/32 + + + + clv1 + + 13.13.13.13/24 + + + + 24.0.0.0/32 + + + 30.0.0.0/32 + + + + clv2 + + 15.15.15.15/24 + + + + + comm2 + + + trgrp_01 + 2346 + + + + + + + + + + 11.11.11.11 + + + 12.12.12.12 + + clv1 + + + + clv1 + + + clv2 + + + + + + 1350 + + + 20000 + 20 + + snmp_cfg + + + all + + + general + + + interface-stats + + + nonvolatile-sets + + + pdu + + + protocol-timeouts + + + routing-socket + + + subagent + + + timer + + + varbind-error + + + + + 4 + 1.x.y.z + absolute-value + 1020 + + + 5 + 1.x.y.z + absolute-value + 1020 + + + 100 + log + + + 200 + log + + + + 100 + 60 + 50 + + + + + + +
+
+
+ """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_dict = { + "communities": [ + { + "clients": [ + {"address": "24.0.0.0/32", "restrict": True}, + {"address": "30.0.0.0/32", "restrict": True}, + ], + "name": "comm1", + "routing_instances": [ + { + "clients": [ + { + "address": "13.13.13.13/24", + "restrict": True, + }, + {"address": "24.0.0.0/32"}, + {"address": "30.0.0.0/32"}, + ], + "name": "clv1", + }, + { + "clients": [{"address": "15.15.15.15/24"}], + "name": "clv2", + }, + ], + }, + {"name": "comm2"}, + ], + "contact": "rohitthakur2590", + "customization": {"ether_stats_ifd_only": True}, + "description": "Local SNMP Server", + "engine_id": {"use_mac_address": True}, + "filter_duplicates": True, + "filter_interfaces": { + "all_internal_interfaces": True, + "interfaces": ["eth1", "eth2"], + }, + "health_monitor": { + "falling_threshold": 50, + "idp": True, + "interval": 100, + "rising_threshold": 60, + }, + "if_count_with_filter_interfaces": True, + "location": "inter_lab", + "logical_system_trap_filter": True, + "name": "SNMP_LAB_SERVER", + "nonvolatile": {"commit_delay": 30}, + "rmon": { + "alarms": [ + { + "id": "4", + "rising_threshold": 1020, + "sample_type": "absolute-value", + "variable": "1.x.y.z", + }, + { + "id": "5", + "rising_threshold": 1020, + "sample_type": "absolute-value", + "variable": "1.x.y.z", + }, + ], + "events": [ + {"id": 100, "type": "log"}, + {"id": 200, "type": "log"}, + ], + }, + "routing_instance_access": {"access_lists": ["clv1", "clv2"]}, + "snmp_v3": { + "notify": [{"name": "not1", "tag": "tag2", "type": "inform"}], + "notify_filter": [ + { + "name": "not_fil_01", + "oids": [{"include": True, "oid": "1.a.s.b.d"}], + }, + { + "name": "not_fil_02", + "oids": [ + {"include": True, "oid": "1.x.b.b.d"}, + {"include": True, "oid": "1.a.c.b.d"}, + ], + }, + ], + "snmp_community": [ + { + "community_index": "v3_comm1", + "community_name": "$9$gUoGiQF/tpB5QORhr8LjHq", + "context": "cont1", + "security_name": "sec101", + "tag": "109", + }, + { + "community_index": "v3_comm2", + "community_name": "$9$9te0A0IKMX-dslKwgoGq.", + "context": "cont1", + "security_name": "sec102", + "tag": "109", + }, + ], + "target_addresses": [ + { + "address": "162.12.10.2", + "address_mask": "24.0.0.0", + "name": "tar201", + "port": 23122, + "retry_count": 200, + "routing_instance": "clv2", + "tag_list": "tag101", + "target_parameters": "tarparam2", + "timeout": 300, + }, + { + "address": "162.12.10.2", + "address_mask": "24.0.0.0", + "name": "tar202", + "port": 23122, + "retry_count": 200, + "routing_instance": "clv2", + "tag_list": "tag101", + "target_parameters": "tarparam2", + "timeout": 300, + }, + ], + "target_parameters": [ + { + "name": "param111", + "notify_filter": "{'filter': 'not121'}", + "parameters": { + "message_processing_model": "v1", + "security_level": "none", + "security_model": "v1", + "security_name": "secure111", + }, + }, + ], + }, + "subagent": {"tcp": {"routing_instances_default": True}}, + "traceoptions": { + "file": { + "files": 20, + "match": "snmp_cfg", + "no_world_readable": True, + "size": 20000, + }, + "flag": { + "all": True, + "general": True, + "interface_stats": True, + "nonvolatile_sets": True, + "pdu": True, + "protocol_timeouts": True, + "routing_socket": True, + "subagent": True, + "timer": True, + "varbind_error": True, + }, + "memory_trace": {"size": 1350}, + }, + "trap_groups": [ + { + "categories": { + "authentication": True, + "chassis": True, + "otn_alarms": { + "oc_lof": True, + "otu_uas_threshold": True, + }, + }, + "destination_port": 2346, + "name": "trgrp_01", + "routing_instance": "clv1", + "targets": ["11.11.11.11", "12.12.12.12"], + }, + ], + } + self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + + def test_junos_ntp_global_rendered(self): + set_module_args( + dict( + config=dict( + client_lists=[ + dict( + name="cl2", + addresses=[dict(address="192.16.4.0/24")], + ), + ], + ), + state="rendered", + ), + ) + rendered = ( + 'cl2' + "192.16.4.0/24" + "" + ) + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_vlans.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_vlans.py new file mode 100644 index 00000000..1f0890a5 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/network/junos/test_junos_vlans.py @@ -0,0 +1,258 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +############################################# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from unittest.mock import patch + +from ansible_collections.junipernetworks.junos.plugins.modules import junos_vlans +from ansible_collections.junipernetworks.junos.tests.unit.modules.utils import set_module_args + +from .junos_module import TestJunosModule, load_fixture + + +class TestJunosVlansModule(TestJunosModule): + module = junos_vlans + + def setUp(self): + super(TestJunosVlansModule, self).setUp() + + self.mock_lock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.lock_configuration", + ) + self.lock_configuration = self.mock_lock_configuration.start() + + self.mock_unlock_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos.unlock_configuration", + ) + self.unlock_configuration = self.mock_unlock_configuration.start() + + self.mock_load_config = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.vlans.vlans.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_commit_configuration = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.config.vlans.vlans.commit_configuration", + ) + self.mock_commit_configuration = self.mock_commit_configuration.start() + + self.mock_execute_show_command = patch( + "ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.facts.vlans.vlans." + "VlansFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestJunosVlansModule, self).tearDown() + self.mock_load_config.stop() + self.mock_lock_configuration.stop() + self.mock_unlock_configuration.stop() + self.mock_commit_configuration.stop() + self.mock_execute_show_command.stop() + + def load_fixtures( + self, + commands=None, + format="text", + changed=False, + filename=None, + ): + def load_from_file(*args, **kwargs): + output = load_fixture("junos_vlans_config.cfg") + return output + + self.execute_show_command.side_effect = load_from_file + + def sort_vlans(self, entry_list): + entry_list.sort(key=lambda i: i.get("name")) + + def test_junos_vlans_merged(self): + set_module_args( + dict( + config=[dict(name="vlan2", vlan_id=2, l3_interface="irb.12")], + state="merged", + ), + ) + commands = [ + '' + "vlan22" + "irb.12", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_vlans_merged_idempotent(self): + set_module_args( + dict(config=[dict(name="vlan1", vlan_id=1)], state="merged"), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_vlans_replaced(self): + """ + :return: + """ + set_module_args( + dict( + config=[ + dict(name="vlan1", vlan_id=1, l3_interface="irb.10"), + dict(name="vlan2", vlan_id=2), + ], + state="replaced", + ), + ) + + commands = [ + '' + 'vlan1' + 'vlan2' + "vlan11" + "irb.10" + "vlan22", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_vlans_replaced_idempotent(self): + set_module_args( + dict(config=[dict(name="vlan1", vlan_id=1)], state="replaced"), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_vlans_overridden(self): + """ + :return: + """ + set_module_args( + dict( + config=[dict(name="vlan3", vlan_id=3, l3_interface="irb.13")], + state="overridden", + ), + ) + + commands = [ + '' + 'vlan1' + "vlan33" + "irb.13", + ] + result = self.execute_module(changed=True, commands=commands) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_vlans_overridden_idempotent(self): + set_module_args( + dict(config=[dict(name="vlan1", vlan_id=1)], state="overridden"), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["before"], result["after"]) + + def test_junos_vlans_gathered(self): + """ + :return: + """ + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + gather_list = [{"name": "vlan1", "vlan_id": 1}] + self.assertEqual(sorted(gather_list), sorted(result["gathered"])) + + def test_junos_vlans_deleted(self): + """ + :return: + """ + set_module_args(dict(config=[dict(name="vlan1")], state="deleted")) + + commands = [ + '' + 'vlan1', + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_vlans_deleted_01(self): + """ + :return: + """ + set_module_args(dict(config=[], state="deleted")) + + commands = [ + '' + 'vlan1', + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_junos_vlans_rendered(self): + """ + :return: + """ + set_module_args( + dict( + config=[ + dict(name="vlan1", vlan_id=1), + dict(name="vlan2", vlan_id=2, l3_interface="irb.12"), + ], + state="rendered", + ), + ) + rendered = ( + '' + "vlan11" + "vlan22" + "irb.12" + ) + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(rendered)) + + def test_junos_vlans_parsed(self): + parsed_str = """ + + + 18.4R1-S2.4 + + + vlan1 + 1 + + + vlan2 + 2 + irb.12 + + + + + """ + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_list = [ + {"name": "vlan1", "vlan_id": 1}, + {"l3_interface": "irb.12", "name": "vlan2", "vlan_id": 2}, + ] + self.sort_vlans(result["parsed"]) + self.sort_vlans(parsed_list) + self.assertEqual(result["parsed"], parsed_list) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/modules/utils.py b/ansible_collections/junipernetworks/junos/tests/unit/modules/utils.py new file mode 100644 index 00000000..87be9cf8 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/modules/utils.py @@ -0,0 +1,55 @@ +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type +import json + +from unittest import TestCase +from unittest.mock import patch + +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes + + +def set_module_args(args): + if "_ansible_remote_tmp" not in args: + args["_ansible_remote_tmp"] = "/tmp" + if "_ansible_keep_remote_files" not in args: + args["_ansible_keep_remote_files"] = False + + args = json.dumps({"ANSIBLE_MODULE_ARGS": args}) + basic._ANSIBLE_ARGS = to_bytes(args) + + +class AnsibleExitJson(Exception): + pass + + +class AnsibleFailJson(Exception): + pass + + +def exit_json(*args, **kwargs): + if "changed" not in kwargs: + kwargs["changed"] = False + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): + kwargs["failed"] = True + raise AnsibleFailJson(kwargs) + + +class ModuleTestCase(TestCase): + def setUp(self): + self.mock_module = patch.multiple( + basic.AnsibleModule, + exit_json=exit_json, + fail_json=fail_json, + ) + self.mock_module.start() + self.mock_sleep = patch("time.sleep") + self.mock_sleep.start() + set_module_args({}) + self.addCleanup(self.mock_module.stop) + self.addCleanup(self.mock_sleep.stop) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/plugins/__init__.py b/ansible_collections/junipernetworks/junos/tests/unit/plugins/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/junipernetworks/junos/tests/unit/plugins/terminal/__init__.py b/ansible_collections/junipernetworks/junos/tests/unit/plugins/terminal/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ansible_collections/junipernetworks/junos/tests/unit/plugins/terminal/test_junos.py b/ansible_collections/junipernetworks/junos/tests/unit/plugins/terminal/test_junos.py new file mode 100644 index 00000000..a07bfa3e --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/plugins/terminal/test_junos.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright: (c) 2018, Fran Fitzpatrick fxfitz +# 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 unittest.mock import MagicMock, call + +import pytest + +from ansible.errors import AnsibleConnectionFailure + +from ansible_collections.junipernetworks.junos.plugins.terminal import junos + + +@pytest.fixture +def junos_terminal(): + mock_connection = MagicMock() + return junos.TerminalModule(mock_connection) + + +def test_on_open_shell_sets_terminal_parameters(junos_terminal): + expected_calls = [ + call(b"set cli timestamp disable"), + call(b"set cli screen-length 0"), + call(b"set cli screen-width 1024"), + ] + junos_terminal._exec_cli_command = MagicMock() + junos_terminal._get_prompt = MagicMock() + + junos_terminal._get_prompt.return_value = b"user@localhost >" + junos_terminal.on_open_shell() + junos_terminal._exec_cli_command.assert_has_calls(expected_calls) + + +def test_on_open_shell_enters_cli_if_root_prompt(junos_terminal): + expected_calls = [ + call(b"cli"), + call(b"set cli timestamp disable"), + call(b"set cli screen-length 0"), + call(b"set cli screen-width 1024"), + ] + junos_terminal._exec_cli_command = MagicMock() + junos_terminal._get_prompt = MagicMock() + + junos_terminal._connection.get_prompt.return_value = b"root@localhost%" + junos_terminal.on_open_shell() + junos_terminal._exec_cli_command.assert_has_calls(expected_calls) + + +def test_on_open_shell_raises_problem_setting_terminal_config(junos_terminal): + junos_terminal._connection.exec_command.side_effect = AnsibleConnectionFailure + with pytest.raises(AnsibleConnectionFailure) as exc: + junos_terminal.on_open_shell() + + assert "unable to set terminal parameters" in str(exc.value) diff --git a/ansible_collections/junipernetworks/junos/tests/unit/requirements.txt b/ansible_collections/junipernetworks/junos/tests/unit/requirements.txt new file mode 100644 index 00000000..a9772bea --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tests/unit/requirements.txt @@ -0,0 +1,42 @@ +boto3 +placebo +pycrypto +passlib +pypsrp +python-memcached +pytz +pyvmomi +redis +requests +setuptools > 0.6 # pytest-xdist installed via requirements does not work with very old setuptools (sanity_ok) +unittest2 ; python_version < '2.7' +importlib ; python_version < '2.7' +netaddr +ipaddress +netapp-lib +solidfire-sdk-python + +# requirements for F5 specific modules +f5-sdk ; python_version >= '2.7' +f5-icontrol-rest ; python_version >= '2.7' +deepdiff + +# requirement for Fortinet specific modules +pyFMG + +# requirement for aci_rest module +xmljson + +# requirement for winrm connection plugin tests +pexpect + +# requirement for the linode module +linode-python # APIv3 +linode_api4 ; python_version > '2.6' # APIv4 + +# requirement for the gitlab module +python-gitlab +httmock + +# requirment for kubevirt modules +openshift ; python_version >= '2.7' diff --git a/ansible_collections/junipernetworks/junos/tox-ansible.ini b/ansible_collections/junipernetworks/junos/tox-ansible.ini new file mode 100644 index 00000000..5e1f4b36 --- /dev/null +++ b/ansible_collections/junipernetworks/junos/tox-ansible.ini @@ -0,0 +1,10 @@ +[ansible] + +skip = + py3.7 + py3.8 + 2.9 + 2.10 + 2.11 + 2.12 + 2.13 diff --git a/ansible_collections/junos_facts.yml b/ansible_collections/junos_facts.yml new file mode 100644 index 00000000..7c47f87a --- /dev/null +++ b/ansible_collections/junos_facts.yml @@ -0,0 +1,11 @@ +--- +- name: Test Junos Facts Module + hosts: junos + gather_facts: false + collections: + - junipernetworks.junos + tasks: + - name: Gather Junos Facts + junos_facts: + register: junos_facts_output +