diff options
Diffstat (limited to 'ansible_collections/junipernetworks/junos/plugins')
64 files changed, 5818 insertions, 2774 deletions
diff --git a/ansible_collections/junipernetworks/junos/plugins/action/junos.py b/ansible_collections/junipernetworks/junos/plugins/action/junos.py index 7c0389a8b..4c5d480af 100644 --- a/ansible_collections/junipernetworks/junos/plugins/action/junos.py +++ b/ansible_collections/junipernetworks/junos/plugins/action/junos.py @@ -21,10 +21,20 @@ 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.junipernetworks.junos.plugins.module_utils.network.junos.junos import ( + junos_provider_spec, +) display = Display() @@ -41,14 +51,114 @@ class ActionModule(ActionNetworkModule): persistent_connection = self._play_context.connection.split(".")[-1] warnings = [] - if persistent_connection not in ("netconf", "network_cli"): - 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), - } + 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: diff --git a/ansible_collections/junipernetworks/junos/plugins/cliconf/junos.py b/ansible_collections/junipernetworks/junos/plugins/cliconf/junos.py index 72ffec99e..75a2e23bd 100644 --- a/ansible_collections/junipernetworks/junos/plugins/cliconf/junos.py +++ b/ansible_collections/junipernetworks/junos/plugins/cliconf/junos.py @@ -106,7 +106,7 @@ class Cliconf(CliconfBase): return self._device_info - def get_config(self, source="running", format="text", flags=None): + def get_config(self, source="running", flags=None, format="text"): if source != "running": raise ValueError( "fetching configuration from %s is not supported" % source, @@ -136,7 +136,6 @@ class Cliconf(CliconfBase): replace=None, comment=None, ): - operations = self.get_device_operations() self.check_edit_config_capability( operations, @@ -188,8 +187,8 @@ class Cliconf(CliconfBase): prompt=None, answer=None, sendonly=False, - output=None, newline=True, + output=None, check_all=False, ): if output: diff --git a/ansible_collections/junipernetworks/junos/plugins/doc_fragments/junos.py b/ansible_collections/junipernetworks/junos/plugins/doc_fragments/junos.py index 23bf60bb2..bf4aad342 100644 --- a/ansible_collections/junipernetworks/junos/plugins/doc_fragments/junos.py +++ b/ansible_collections/junipernetworks/junos/plugins/doc_fragments/junos.py @@ -9,7 +9,6 @@ __metaclass__ = type class ModuleDocFragment(object): - # Standard files documentation fragment DOCUMENTATION = r"""options: {} notes: diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/argspec/bgp_global/bgp_global.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/argspec/bgp_global/bgp_global.py index 2cbbdf5e2..63c4347b2 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/argspec/bgp_global/bgp_global.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/argspec/bgp_global/bgp_global.py @@ -1260,6 +1260,7 @@ class Bgp_globalArgs(object): # pylint: disable=R0903 "purged", "merged", "replaced", + "overridden", "deleted", "gathered", "parsed", diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/argspec/ospf_interfaces/ospf_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/argspec/ospf_interfaces/ospf_interfaces.py index 5bf718991..be2515642 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/argspec/ospf_interfaces/ospf_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/argspec/ospf_interfaces/ospf_interfaces.py @@ -58,15 +58,16 @@ class Ospf_interfacesArgs(object): # pylint: disable=R0903 "authentication": { "options": { "md5": { + "elements": "dict", "options": { - "key_id": {"type": "str"}, + "key_id": {"type": "int"}, "key_value": { "type": "str", "no_log": True, }, "start_time": {"type": "str"}, }, - "type": "dict", + "type": "list", }, "simple_password": { "type": "str", @@ -106,7 +107,7 @@ class Ospf_interfacesArgs(object): # pylint: disable=R0903 "no_neighbor_down_notification": { "type": "bool", }, - "node_link_protection": {"type": "str"}, + "node_link_protection": {"type": "bool"}, "poll_interval": {"type": "int"}, "priority": {"type": "int"}, "passive": {"type": "bool"}, diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/argspec/ospfv2/ospfv2.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/argspec/ospfv2/ospfv2.py index a160512a2..c93722137 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/argspec/ospfv2/ospfv2.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/argspec/ospfv2/ospfv2.py @@ -39,6 +39,16 @@ class Ospfv2Args(object): # pylint: disable=R0903 "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": { @@ -51,7 +61,25 @@ class Ospfv2Args(object): # pylint: disable=R0903 "options": { "authentication": { "type": "dict", - "options": {"type": {"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", @@ -88,7 +116,12 @@ class Ospfv2Args(object): # pylint: disable=R0903 "external_preference": {"type": "int"}, "overload": { "type": "dict", - "options": {"timeout": {"type": "int"}}, + "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"}, @@ -103,6 +136,7 @@ class Ospfv2Args(object): # pylint: disable=R0903 "delay": {"type": "int"}, "holddown": {"type": "int"}, "rapid_runs": {"type": "int"}, + "no_ignore_our_externals": {"type": "bool"}, }, }, }, diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/acl_interfaces/acl_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/acl_interfaces/acl_interfaces.py index 67f5fe309..e4b263eac 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/acl_interfaces/acl_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/acl_interfaces/acl_interfaces.py @@ -60,7 +60,7 @@ class Acl_interfaces(ConfigBase): data=data, ) acl_interfaces_facts = facts["ansible_network_resources"].get( - "junos_acl_interfaces", + "acl_interfaces", ) if not acl_interfaces_facts: return [] diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/acls/acls.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/acls/acls.py index 540ffe271..05e174279 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/acls/acls.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/acls/acls.py @@ -59,7 +59,7 @@ class Acls(ConfigBase): self.gather_network_resources, data=data, ) - acls_facts = facts["ansible_network_resources"].get("junos_acls") + acls_facts = facts["ansible_network_resources"].get("acls") if not acls_facts: return [] return acls_facts diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/bgp_global/bgp_global.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/bgp_global/bgp_global.py index da512c6f9..08e3f9048 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/bgp_global/bgp_global.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/bgp_global/bgp_global.py @@ -168,7 +168,7 @@ class Bgp_global(ConfigBase): config_xmls = self._state_purged(want, have) elif state in ("merged", "rendered"): config_xmls = self._state_merged(want, have) - elif state == "replaced": + elif state in ("replaced", "overridden"): config_xmls = self._state_replaced(want, have) if config_xmls: diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/interfaces/interfaces.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/interfaces/interfaces.py index ad6b58668..1b7edef27 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/interfaces/interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/interfaces/interfaces.py @@ -210,7 +210,6 @@ class Interfaces(ConfigBase): the current configuration """ intf_xml = [] - for config in want: intf = build_root_xml_node("interface") build_child_xml_node(intf, "name", config["name"]) @@ -225,8 +224,8 @@ class Interfaces(ConfigBase): if config.get("duplex"): build_child_xml_node(intf, "link-mode", config["duplex"]) - if config.get("enabled") is False: - build_child_xml_node(intf, "disable") + if config.get("enabled") is not None: + build_child_xml_node(intf, "enable" if config.get("enabled") else "disable") if config.get("units"): units = config.get("units") diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/lag_interfaces/lag_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/lag_interfaces/lag_interfaces.py index 2b17498ee..c52190ca7 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/lag_interfaces/lag_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/lag_interfaces/lag_interfaces.py @@ -245,7 +245,6 @@ class Lag_interfaces(ConfigBase): "aggregated-ether-options", ) if config["mode"]: - lacp_node = build_child_xml_node(ether_options_node, "lacp") build_child_xml_node(lacp_node, config["mode"]) diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/lldp_global/lldp_global.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/lldp_global/lldp_global.py index 4efac0315..5b0d5c78f 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/lldp_global/lldp_global.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/lldp_global/lldp_global.py @@ -209,7 +209,7 @@ class Lldp_global(ConfigBase): "hold-multiplier", want["hold_multiplier"], ) - enable = want.get("enable") + enable = want.get("enabled") if enable is not None: if enable is False: build_child_xml_node(lldp_root, "disable") diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/ospf_interfaces/ospf_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/ospf_interfaces/ospf_interfaces.py index 2cbc8f24f..990cae77e 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/ospf_interfaces/ospf_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/ospf_interfaces/ospf_interfaces.py @@ -179,7 +179,6 @@ class Ospf_interfaces(ConfigBase): for xml in config_xmls: self.protocols.append(xml) - return [tostring(xml) for xml in self.root.getchildren()] def _state_replaced(self, want, have): @@ -293,6 +292,36 @@ class Ospf_interfaces(ConfigBase): existing_config = have[0] if existing_config["name"] == ospf_interfaces["name"]: intf_node.attrib.update(delete) + + if "authentication" in processes: + auth = processes.get("authentication") + auth_node = build_child_xml_node(intf_node, "authentication") + if "simple_password" in auth: + build_child_xml_node( + auth_node, + "simple-password", + auth.get("simple_password"), + ) + if "md5" in auth: + md5_lst = auth.get("md5") + for md5 in md5_lst: + md5_node = build_child_xml_node(auth_node, "md5") + build_child_xml_node( + md5_node, + "name", + md5.get("key_id"), + ) + build_child_xml_node( + md5_node, + "key", + md5.get("key_value"), + ) + if "start_time" in md5: + build_child_xml_node( + md5_node, + "start-time", + md5.get("start_time"), + ) if processes.get("priority"): build_child_xml_node( intf_node, @@ -357,6 +386,48 @@ class Ospf_interfaces(ConfigBase): "retransmit-interval", processes.get("retransmit_interval"), ) + if "node_link_protection" in processes: + if processes.get("node_link_protection"): + build_child_xml_node( + intf_node, + "node-link-protection", + ) + if "no_advertise_adjacency_segment" in processes: + if processes.get("no_advertise_adjacency_segment"): + build_child_xml_node( + intf_node, + "no-advertise-adjacency-segment", + ) + if "no_neighbor_down_notification" in processes: + if processes.get("no_neighbor_down_notification"): + build_child_xml_node( + intf_node, + "no-neighbor-down-notification", + ) + if "no_interface_state_traps" in processes: + if processes.get("no_interface_state_traps"): + build_child_xml_node( + intf_node, + "no-interface-state-traps", + ) + if "no_eligible_remote_backup" in processes: + if processes.get("no_eligible_remote_backup"): + build_child_xml_node( + intf_node, + "no-eligible-remote-backup", + ) + if "no_eligible_backup" in processes: + if processes.get("no_eligible_backup"): + build_child_xml_node( + intf_node, + "no-eligible-backup", + ) + if "demand_circuit" in processes: + if processes.get("demand_circuit"): + build_child_xml_node( + intf_node, + "demand-circuit", + ) ospf_interfaces_xml.append(protocol) return ospf_interfaces_xml diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/ospfv2/ospfv2.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/ospfv2/ospfv2.py index 23730746f..46952929f 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/ospfv2/ospfv2.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/ospfv2/ospfv2.py @@ -57,7 +57,7 @@ class Ospfv2(ConfigBase): gather_subset = ["!all", "!min"] - gather_network_resources = ["ospf"] + gather_network_resources = ["ospfv2"] def __init__(self, module): super(Ospfv2, self).__init__(module) @@ -221,18 +221,59 @@ class Ospfv2(ConfigBase): """ ospf_xml = [] delete = {"delete": "delete"} + ospf_node = None if have: + ospf_node = build_child_xml_node(self.protocols, "ospf") for have_ospf in have: have_areas = have_ospf.get("areas") or [] for area in have_areas: - ospf_node = build_child_xml_node(self.protocols, "ospf") area_node = build_child_xml_node( ospf_node, "area", area["area_id"], ) area_node.attrib.update(delete) - ospf_xml.append(ospf_node) + for item in have: + if item.get("spf_options"): + spf_node = build_child_xml_node( + ospf_node, + "spf-options", + ) + spf_node.attrib.update(delete) + if item.get("external_preference"): + ref_node = build_child_xml_node( + ospf_node, + "external-preference", + ) + ref_node.attrib.update(delete) + if item.get("reference_bandwidth"): + ref_node = build_child_xml_node( + ospf_node, + "reference-bandwidth", + ) + ref_node.attrib.update(delete) + if item.get("rfc1583compatibility") is False: + rfc_node = build_child_xml_node( + ospf_node, + "no-rfc-1583", + ) + rfc_node.attrib.update(delete) + if item.get("overload"): + over_node = build_child_xml_node( + ospf_node, + "overload", + ) + over_node.attrib.update(delete) + if item.get("prefix_export_limit"): + pel_node = build_child_xml_node( + ospf_node, + "prefix-export-limit", + ) + pel_node.attrib.update(delete) + + if ospf_node is not None: + ospf_xml.append(ospf_node) + return ospf_xml def _state_merged(self, want, have): @@ -285,6 +326,11 @@ class Ospfv2(ConfigBase): "rapid-runs", ospf["spf_options"].get("rapid_runs"), ) + if ospf["spf_options"].get("no_ignore_our_externals"): + build_child_xml_node( + spf_options_node, + "no-ignore-our-externals", + ) if ospf.get("overload"): overload_node = build_child_xml_node(protocol, "overload") @@ -294,6 +340,22 @@ class Ospfv2(ConfigBase): "timeout", ospf["overload"].get("timeout"), ) + if ospf["overload"].get("allow_route_leaking"): + build_child_xml_node( + overload_node, + "allow-route-leaking", + ) + if ospf["overload"].get("as_external"): + build_child_xml_node( + overload_node, + "as-external", + ) + + if ospf["overload"].get("stub_network"): + build_child_xml_node( + overload_node, + "stub-network", + ) if ospf.get("external_preference"): build_child_xml_node( @@ -332,6 +394,7 @@ class Ospfv2(ConfigBase): area_node = build_child_xml_node(protocol, "area") area_id = area.get("area_id") build_child_xml_node(area_node, "name", area_id) + # Included for compatibility, remove after 2025-07-01 if area.get("area_range"): area_range_node = build_child_xml_node( area_node, @@ -342,88 +405,153 @@ class Ospfv2(ConfigBase): "name", area["area_range"], ) - - for intf in area.get("interfaces"): - intf_node = build_child_xml_node( - area_node, - "interface", - ) - build_child_xml_node( - intf_node, - "name", - intf.get("name"), - ) - - if intf.get("priority"): - build_child_xml_node( - intf_node, - "priority", - intf.get("priority"), + if "area_ranges" in area: + for a_range in area.get("area_ranges"): + range_node = build_child_xml_node( + area_node, + "area-range", ) - if intf.get("flood_reduction"): build_child_xml_node( - intf_node, - "flood-reduction", - None, + range_node, + "name", + a_range["address"], ) + if "exact" in a_range: + build_child_xml_node( + range_node, + "exact", + ) - if intf.get("metric"): + if "restrict" in a_range: + build_child_xml_node( + range_node, + "restrict", + ) + if a_range.get("override_metric"): + build_child_xml_node( + range_node, + "override-metric", + a_range.get("override_metric"), + ) + if "interfaces" in area: + for intf in area.get("interfaces"): + intf_node = build_child_xml_node( + area_node, + "interface", + ) build_child_xml_node( intf_node, - "metric", - intf["metric"], + "name", + intf.get("name"), ) - if intf.get("passive"): - build_child_xml_node(intf_node, "passive") - - if intf.get("bandwidth_based_metrics"): - bw_metrics_node = build_child_xml_node( - intf_node, - "bandwidth-based-metrics", - ) - bw_metrics = intf.get("bandwidth_based_metrics") - for bw_metric in bw_metrics: - bw_metric_node = build_child_xml_node( - bw_metrics_node, - "bandwidth", - ) + if intf.get("priority"): build_child_xml_node( - bw_metric_node, - "name", - bw_metric.get("bandwidth"), - ) - build_child_xml_node( - bw_metric_node, - "metric", - bw_metric.get("metric"), + intf_node, + "priority", + intf.get("priority"), ) - if intf.get("timers"): - if intf["timers"].get("dead_interval"): + + if intf.get("flood_reduction"): build_child_xml_node( intf_node, - "dead-interval", - intf["timers"].get("dead_interval"), + "flood-reduction", + None, ) - if intf["timers"].get("hello_interval"): + + if intf.get("metric"): build_child_xml_node( intf_node, - "hello-interval", - intf["timers"].get("hello_interval"), + "metric", + intf["metric"], ) - if intf["timers"].get("poll_interval"): - build_child_xml_node( + + if intf.get("passive"): + build_child_xml_node(intf_node, "passive") + + if intf.get("bandwidth_based_metrics"): + bw_metrics_node = build_child_xml_node( intf_node, - "poll-interval", - intf["timers"].get("poll_interval"), + "bandwidth-based-metrics", ) - if intf["timers"].get("retransmit_interval"): - build_child_xml_node( + bw_metrics = intf.get("bandwidth_based_metrics") + for bw_metric in bw_metrics: + bw_metric_node = build_child_xml_node( + bw_metrics_node, + "bandwidth", + ) + build_child_xml_node( + bw_metric_node, + "name", + bw_metric.get("bandwidth"), + ) + build_child_xml_node( + bw_metric_node, + "metric", + bw_metric.get("metric"), + ) + if intf.get("authentication"): + auth = intf.get("authentication") + auth_node = build_child_xml_node( intf_node, - "retransmit-interval", - intf["timers"].get("retransmit_interval"), + "authentication", ) + if "password" in auth.keys(): + build_child_xml_node( + auth_node, + "simple-password", + auth.get("password"), + ) + elif "md5" in auth.keys(): + md5 = auth.get("md5") + md_node = build_child_xml_node( + auth_node, + "md5", + ) + for item in md5: + build_child_xml_node( + md_node, + "name", + item["key_id"], + ) + build_child_xml_node( + md_node, + "key", + item["key"], + ) + + if "start_time" in item: + build_child_xml_node( + md_node, + "start-time", + item["start_time"], + ) + if intf.get("timers"): + if intf["timers"].get("dead_interval"): + build_child_xml_node( + intf_node, + "dead-interval", + intf["timers"].get("dead_interval"), + ) + if intf["timers"].get("hello_interval"): + build_child_xml_node( + intf_node, + "hello-interval", + intf["timers"].get("hello_interval"), + ) + if intf["timers"].get("poll_interval"): + build_child_xml_node( + intf_node, + "poll-interval", + intf["timers"].get("poll_interval"), + ) + if intf["timers"].get("retransmit_interval"): + build_child_xml_node( + intf_node, + "retransmit-interval", + intf["timers"].get("retransmit_interval"), + ) if area.get("stub"): if area["stub"]["set"]: diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/ospfv3/ospfv3.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/ospfv3/ospfv3.py index a9aea34ec..1de305498 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/ospfv3/ospfv3.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/ospfv3/ospfv3.py @@ -73,7 +73,7 @@ class Ospfv3(ConfigBase): self.gather_network_resources, data=data, ) - ospfv3_facts = facts["ansible_network_resources"].get("junos_ospfv3") + ospfv3_facts = facts["ansible_network_resources"].get("ospfv3") if not ospfv3_facts: return [] return ospfv3_facts diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/snmp_server/snmp_server.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/snmp_server/snmp_server.py index 754b890d1..70d4d597c 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/snmp_server/snmp_server.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/config/snmp_server/snmp_server.py @@ -527,111 +527,134 @@ class Snmp_server(ConfigBase): mem_node = build_child_xml_node(trace_node, "memory-trace") build_child_xml_node(mem_node, "size", mem.get("size")) - if "trap_groups" in want.keys(): - groups = want.get("trap_groups") + if "trap_groups" in want.keys(): + groups = want.get("trap_groups") - for trap in groups: - trap_node = build_child_xml_node(snmp_node, "trap-group") - for key in trap.keys(): - if key == "name": - build_child_xml_node( - trap_node, - "name", - trap["name"], - ) - if key == "destination_port": - build_child_xml_node( - trap_node, - "destination-port", - trap["destination_port"], - ) - if key == "categories": - cat_node = build_child_xml_node( - trap_node, - "categories", - ) - categories = trap.get("categories") - for key in categories: - if key == "otn_alarms": - alarms = categories.get("otn_alarms") - alarm_node = build_child_xml_node( - cat_node, - "otn-alarms", - ) - for key in alarms: - build_child_xml_node( - alarm_node, - key.replace("_", "-"), - ) - else: + for trap in groups: + trap_node = build_child_xml_node(snmp_node, "trap-group") + for key in trap.keys(): + if key == "name": + build_child_xml_node( + trap_node, + "name", + trap["name"], + ) + if key == "destination_port": + build_child_xml_node( + trap_node, + "destination-port", + trap["destination_port"], + ) + if key == "categories": + cat_node = build_child_xml_node( + trap_node, + "categories", + ) + categories = trap.get("categories") + for key in categories: + if key == "otn_alarms": + alarms = categories.get("otn_alarms") + alarm_node = build_child_xml_node( + cat_node, + "otn-alarms", + ) + for key in alarms: build_child_xml_node( - cat_node, + alarm_node, key.replace("_", "-"), ) - if key == "routing_instance": - build_child_xml_node( - trap_node, - "routing-instance", - trap.get(key), - ) - if key == "version": - build_child_xml_node( - trap_node, - "version", - trap.get(key), - ) - if key == "targets": - targets = trap.get("targets") - for target in targets: - tar_node = build_child_xml_node( - trap_node, - "targets", + else: + build_child_xml_node( + cat_node, + key.replace("_", "-"), ) - build_child_xml_node(tar_node, "name", target) - - # trap_options - if "trap_options" in want.keys(): - options = want.get("trap_options") - - if options.keys() == {"set"}: - build_child_xml_node(snmp_node, "trap-options") - else: - trap_node = build_child_xml_node(snmp_node, "trap-options") - if "agent_address" in options.keys(): - agent = options.get("agent_address") - if agent.get("outgoing_interface"): - build_child_xml_node( - trap_node, - "agent-address", - "outgoing-interface", - ) - if options.get("context_oid"): - build_child_xml_node(trap_node, "context-id") - # TODO logical_system - if "routing_instance" in options.keys(): - inst = options.get("routing_instances") - inst_node = build_child_xml_node( + if key == "routing_instance": + build_child_xml_node( trap_node, "routing-instance", + trap.get(key), ) - build_child_xml_node(inst_node, "name", inst) - if "source_address" in options.keys(): - address = options.get("source_address") - source_node = build_child_xml_node( + if key == "version": + build_child_xml_node( trap_node, - "source-address", + "version", + trap.get(key), ) - if "address" in address.keys(): - build_child_xml_node( - source_node, - "address", - address.get("address"), + if key == "targets": + targets = trap.get("targets") + for target in targets: + tar_node = build_child_xml_node( + trap_node, + "targets", ) - if "lowest_loopback" in address.keys(): + build_child_xml_node(tar_node, "name", target) + # trap_options + if "trap_options" in want.keys(): + options = want.get("trap_options") + if options.keys() == {"set"}: + build_child_xml_node(snmp_node, "trap-options") + else: + trap_node = build_child_xml_node(snmp_node, "trap-options") + if "agent_address" in options.keys(): + agent = options.get("agent_address") + if agent.get("outgoing_interface"): + agent_node = build_child_xml_node( + trap_node, + "agent-address", + "outgoing-interface", + ) + + if options.get("context_oid"): + build_child_xml_node(trap_node, "context-oid") + if "routing_instance" in options.keys(): + inst = options.get("routing_instances") + build_child_xml_node( + trap_node, + "routing-instance", + inst, + ) + if "source_address" in options.keys(): + address = options.get("source_address") + source_node = build_child_xml_node( + trap_node, + "source-address", + ) + if "address" in address.keys(): + build_child_xml_node( + source_node, + "address", + address.get("address"), + ) + if "lowest_loopback" in address.keys(): + build_child_xml_node( + source_node, + "lowest-loopback", + ) + if "views" in want.keys(): + views = want.get("views") + for view in views: + view_node = build_child_xml_node(snmp_node, "view") + + if "name" in view.keys(): + build_child_xml_node( + view_node, + "name", + view.get("name"), + ) + if "oids" in view.keys(): + oids = view.get("oids") + for oid in oids: + oids_node = build_child_xml_node(view_node, "oid") + if "oid" in oid.keys(): build_child_xml_node( - source_node, - "lowest-loopback", + oids_node, + "name", + oid["oid"], ) + if "exclude" in oid.keys(): + build_child_xml_node(oids_node, "exclude") + if "include" in oid.keys(): + build_child_xml_node(oids_node, "include") # snmp_v3 if "snmp_v3" in want.keys(): snmpv3 = want.get("snmp_v3") @@ -859,31 +882,6 @@ class Snmp_server(ConfigBase): "privacy-password", sub_dict["password"], ) - if "views" in want.keys(): - views = want.get("views") - for view in views: - view_node = build_child_xml_node(snmp_node, "view") - - if "name" in view.keys(): - build_child_xml_node( - view_node, - "name", - view.get("name"), - ) - if "oids" in view.keys(): - oids = view.get("oids") - for oid in oids: - oids_node = build_child_xml_node(view_node, "oid") - if "oid" in oid.keys(): - build_child_xml_node( - oids_node, - "name", - oid["oid"], - ) - if "exclude" in oid.keys(): - build_child_xml_node(oids_node, "exclude") - if "include" in oid.keys(): - build_child_xml_node(oids_node, "include") def _state_deleted(self, want, have): """The command generator when state is deleted diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/acl_interfaces/acl_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/acl_interfaces/acl_interfaces.py index ac91f53ba..3642a373a 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/acl_interfaces/acl_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/acl_interfaces/acl_interfaces.py @@ -93,12 +93,16 @@ class Acl_interfacesFacts(object): 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) diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/acls/acls.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/acls/acls.py index a48217d64..7ff8fb2c3 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/acls/acls.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/acls/acls.py @@ -98,13 +98,13 @@ class AclsFacts(object): facts = {} if objs: - facts["junos_acls"] = [] + facts["acls"] = [] params = utils.validate_config( self.argument_spec, {"config": objs}, ) for cfg in params["config"]: - facts["junos_acls"].append(utils.remove_empties(cfg)) + facts["acls"].append(utils.remove_empties(cfg)) ansible_facts["ansible_network_resources"].update(facts) return ansible_facts diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/bgp_global/bgp_global.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/bgp_global/bgp_global.py index a8cfa99c7..0436284c8 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/bgp_global/bgp_global.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/bgp_global/bgp_global.py @@ -616,7 +616,6 @@ class Bgp_globalFacts(object): # Read import value if "import" in conf.keys(): - imports = conf.get("import") import_lst = [] if isinstance(imports, dict): diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/facts.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/facts.py index bf596dcc4..90db102d0 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/facts.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/facts.py @@ -127,7 +127,7 @@ FACT_RESOURCE_SUBSETS = dict( l3_interfaces=L3_interfacesFacts, lldp_global=Lldp_globalFacts, lldp_interfaces=Lldp_interfacesFacts, - ospf=Ospfv2Facts, + ospfv2=Ospfv2Facts, ospfv3=Ospfv3Facts, ospf_interfaces=Ospf_interfacesFacts, vlans=VlansFacts, diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/l2_interfaces/l2_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/l2_interfaces/l2_interfaces.py index 19d85e0d0..c68f77f41 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/l2_interfaces/l2_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/l2_interfaces/l2_interfaces.py @@ -23,9 +23,6 @@ from ansible_collections.ansible.netcommon.plugins.module_utils.network.common i from ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.argspec.l2_interfaces.l2_interfaces import ( L2_interfacesArgs, ) -from ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.utils.utils import ( - get_resource_config, -) try: @@ -53,14 +50,14 @@ class L2_interfacesFacts(object): self.generated_spec = utils.generate_dict(facts_argument_spec) - def get_config(self, connection, config_filter): + def get_device_data(self, connection, config_filter): """ :param connection: :param config_filter: :return: """ - return get_resource_config(connection, config_filter=config_filter) + return connection.get_configuration(filter=config_filter) def populate_facts(self, connection, ansible_facts, data=None): """Populate the facts for interfaces @@ -79,7 +76,7 @@ class L2_interfacesFacts(object): <interfaces/> </configuration> """ - data = self.get_config(connection, config_filter=config_filter) + data = self.get_device_data(connection, config_filter) if isinstance(data, string_types): data = etree.fromstring( @@ -130,33 +127,31 @@ class L2_interfacesFacts(object): enhanced_layer = False # Layer 2 is configured on interface - if mode: - 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": - 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", - ) - + 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/junipernetworks/junos/plugins/module_utils/network/junos/facts/lacp/lacp.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/lacp/lacp.py index 6c3ecd904..d3ca2142a 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/lacp/lacp.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/lacp/lacp.py @@ -90,7 +90,6 @@ class LacpFacts(object): "configuration/chassis/aggregated-devices/ethernet/lacp", ) if resources: - lacp_root = resources[0] config["system_priority"] = utils.get_xml_conf_arg( lacp_root, diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/legacy/base.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/legacy/base.py index 11f6544aa..10ad6080c 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/legacy/base.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/legacy/base.py @@ -129,7 +129,6 @@ class Hardware(FactsBase): return xml_dict def populate(self): - reply = self.rpc("get-system-memory-information") data = reply.find( ".//system-memory-information/system-memory-summary-information", @@ -215,7 +214,6 @@ class Interfaces(FactsBase): class OFacts(FactsBase): def populate(self): - device = get_device(self.module) facts = dict(device.facts) diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/lldp_global/lldp_global.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/lldp_global/lldp_global.py index df82a2695..3b48e9720 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/lldp_global/lldp_global.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/lldp_global/lldp_global.py @@ -102,7 +102,7 @@ class Lldp_globalFacts(object): "hold-multiplier", ) if utils.get_xml_conf_arg(lldp_root, "disable", data="tag"): - config["enable"] = False + config["enabled"] = False params = utils.validate_config( self.argument_spec, diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/ospf_interfaces/ospf_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/ospf_interfaces/ospf_interfaces.py index 15319fa32..55c162d25 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/ospf_interfaces/ospf_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/ospf_interfaces/ospf_interfaces.py @@ -112,7 +112,7 @@ class Ospf_interfacesFacts(object): objs = [] for resource in resources: - if resource: + if resource is not None: xml = self._get_xml_dict(resource) objs = self.render_config(self.generated_spec, xml) @@ -230,20 +230,23 @@ class Ospf_interfacesFacts(object): auth_dict["simple_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"), - }, - ) + 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) diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/ospfv2/ospfv2.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/ospfv2/ospfv2.py index 24c8fa86d..44bbb9732 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/ospfv2/ospfv2.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/ospfv2/ospfv2.py @@ -116,14 +116,14 @@ class Ospfv2Facts(object): self.router_id = "" objs = [] for resource in resources: - if resource: + 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: + if objs is not None: facts["ospfv2"] = [] params = utils.validate_config( self.argument_spec, @@ -156,9 +156,9 @@ class Ospfv2Facts(object): :rtype: dictionary :returns: The generated config """ + config = deepcopy(spec) ospf = conf.get("ospf") - if ospf.get("area"): rendered_areas = [] areas = ospf.get("area") @@ -213,27 +213,39 @@ class Ospfv2Facts(object): "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["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] - - for md5_auth in md5_list: - auth_dict["type"]["md5"].append( - { - "key_id": md5_auth.get("name"), - "key": md5_auth.get("key"), - }, - ) + 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) @@ -242,10 +254,22 @@ class Ospfv2Facts(object): 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(): @@ -261,26 +285,39 @@ class Ospfv2Facts(object): if "default-lsa" in area.get("nssa").keys(): rendered_area["nssa"]["default-lsa"] = True rendered_areas.append(rendered_area) - - 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", - ) - config["overload"] = ospf.get("overload") - 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") config["areas"] = rendered_areas - if self.router_id != "": - config["router_id"] = self.router_id["router-id"] + 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/junipernetworks/junos/plugins/module_utils/network/junos/facts/ospfv3/ospfv3.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/ospfv3/ospfv3.py index 2f95e0e8d..8bbd04fcd 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/ospfv3/ospfv3.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/ospfv3/ospfv3.py @@ -117,7 +117,7 @@ class Ospfv3Facts(object): objs = [] for resource in resources: - if resource: + if resource is not None: xml = self._get_xml_dict(resource) obj = self.render_config(self.generated_spec, xml) if obj: @@ -125,14 +125,14 @@ class Ospfv3Facts(object): facts = {} if objs: - facts["junos_ospfv3"] = [] + facts["ospfv3"] = [] params = utils.validate_config( self.argument_spec, {"config": objs}, ) for cfg in params["config"]: - facts["junos_ospfv3"].append(utils.remove_empties(cfg)) + facts["ospfv3"].append(utils.remove_empties(cfg)) ansible_facts["ansible_network_resources"].update(facts) return ansible_facts diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/security_policies/security_policies.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/security_policies/security_policies.py index dc6a20878..0c4d25e5e 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/security_policies/security_policies.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/security_policies/security_policies.py @@ -146,7 +146,6 @@ class Security_policiesFacts(object): 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"]][ diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/security_zones/security_zones.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/security_zones/security_zones.py index 5368bf77f..1e77168ac 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/security_zones/security_zones.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/facts/security_zones/security_zones.py @@ -226,7 +226,6 @@ class Security_zonesFacts(object): 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"] @@ -283,13 +282,14 @@ class Security_zonesFacts(object): security_zone["host-inbound-traffic"], ) if "interfaces" in security_zone: - if isinstance(security_zone["interfaces"], string_types): + if isinstance(security_zone["interfaces"], dict): security_zone["interfaces"] = [ security_zone["interfaces"], ] - temp_sec_zone["interfaces"] = [ - interface["name"] for interface in 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: diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/junos.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/junos.py index 36452b123..fc7e6342f 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/junos.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/junos.py @@ -27,6 +27,7 @@ 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, @@ -57,6 +58,30 @@ 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: @@ -72,10 +97,13 @@ def tostring(element, encoding="UTF-8", pretty_print=False): ) +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": @@ -153,7 +181,6 @@ def load_configuration( rollback=None, format="xml", ): - if all((candidate is None, rollback is None)): module.fail_json(msg="one of candidate or rollback must be specified") diff --git a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/utils/utils.py b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/utils/utils.py index 1f1250a34..4f9158cfe 100644 --- a/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/utils/utils.py +++ b/ansible_collections/junipernetworks/junos/plugins/module_utils/network/junos/utils/utils.py @@ -34,7 +34,6 @@ except ImportError: def get_resource_config(connection, config_filter=None, attrib=None): - if attrib is None: attrib = {"inherit": "inherit"} diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_acl_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_acl_interfaces.py index ccc604a11..9465cac7b 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_acl_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_acl_interfaces.py @@ -131,15 +131,15 @@ EXAMPLES = """ - 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 + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: inbound_acl + direction: in + - name: outbound_acl + direction: out + state: deleted # After state: # ------------- @@ -175,15 +175,15 @@ EXAMPLES = """ - 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 + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: inbound_acl + direction: in + - name: outbound_acl + direction: out + state: merged # After state: # ------------- @@ -226,15 +226,15 @@ EXAMPLES = """ - 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 + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: inbound_acl + direction: in + - name: outbound_acl + direction: out + state: overridden # After state: # ------------- @@ -278,13 +278,13 @@ EXAMPLES = """ - 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 + - name: ge-1/0/0 + access_groups: + - afi: ipv4 + acls: + - name: inbound_acl + direction: in + state: replaced # After state: # ------------- @@ -303,8 +303,6 @@ EXAMPLES = """ # } # family inet6; # } - - """ RETURN = """ before: diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_acls.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_acls.py index 2b1bafc7a..0b38587b0 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_acls.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_acls.py @@ -278,16 +278,16 @@ EXAMPLES = """ - 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 + - afi: ipv4 + acls: + - name: allow_ssh_acl + aces: + - name: ssh_rule + source: + port_protocol: + eq: ssh + protocol: tcp + state: merged # After state: # ------------- @@ -302,7 +302,6 @@ EXAMPLES = """ # } # } # } - """ RETURN = """ before: diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_banner.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_banner.py index d57f8f6aa..ce81a141a 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_banner.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_banner.py @@ -49,7 +49,7 @@ options: description: - Specifies whether or not the configuration is active or deactivated type: bool - default: yes + default: true requirements: - ncclient (>=v0.5.2) notes: diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_bgp_address_family.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_bgp_address_family.py index b40e5e816..66928d3c5 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_bgp_address_family.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_bgp_address_family.py @@ -489,6 +489,90 @@ EXAMPLES = """ graceful_restart_forwarding_state_bit: 'from-fib' state: merged +# Task Output: +# ------------ +# +# before: {} +# +# commands: +# - <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>20</nc:maximum><nc:teardown><nc:limit-threshold>98</nc:limit-threshold> +# <nc:idle-timeout><nc:timeout>2001</nc:timeout></nc:idle-timeout></nc:teardown></nc:accepted-prefix-limit> +# <nc:damping/><nc:defer-initial-multipath-build><nc:maximum-delay>2</nc:maximum-delay> +# </nc:defer-initial-multipath-build></nc:signaling></nc:evpn><nc:inet><nc:flow><nc:legacy-redirect-ip-action> +# <nc:send/><nc:receive/></nc:legacy-redirect-ip-action><nc:loops>4</nc:loops><nc:no-install/> +# <nc:output-queue-priority><nc:expedited/></nc:output-queue-priority><nc:secondary-independent-resolution/> +# </nc:flow><nc:unicast><nc:extended-nexthop/><nc:extended-nexthop-color/><nc:local-ipv4-address>9.9.9.9</nc:local-ipv4-address> +# </nc:unicast><nc:labeled-unicast><nc:entropy-label><nc:no-next-hop-validation/></nc:entropy-label> +# <nc:explicit-null><nc:connected-only/></nc:explicit-null><nc:per-prefix-label/><nc:per-group-label/> +# <nc:prefix-limit><nc:maximum>20</nc:maximum><nc:teardown>99<nc:idle-timeout><nc:forever/></nc:idle-timeout> +# </nc:teardown></nc:prefix-limit><nc:resolve-vpn/><nc:rib><nc:inet.3/></nc:rib><nc:route-refresh-priority> +# <nc:expedited/><nc:priority>3</nc:priority></nc:route-refresh-priority></nc:labeled-unicast><nc:any> +# <nc:accepted-prefix-limit><nc:maximum>20</nc:maximum><nc:teardown><nc:limit-threshold>99</nc:limit-threshold> +# <nc:idle-timeout><nc:timeout>2000</nc:timeout></nc:idle-timeout></nc:teardown></nc:accepted-prefix-limit> +# <nc:damping/><nc:defer-initial-multipath-build><nc:maximum-delay>2</nc:maximum-delay></nc:defer-initial-multipath-build> +# <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:graceful-restart> +# <nc:forwarding-state-bit>from-fib</nc:forwarding-state-bit></nc:graceful-restart></nc:any></nc:inet></nc:family> +# </nc:bgp></nc:protocols> +# - <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"/> +# +# 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 # ----------- # @@ -562,6 +646,8 @@ EXAMPLES = """ # } # } # } + +# # Using replaced # # Before state @@ -651,38 +737,154 @@ EXAMPLES = """ - 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 + 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: +# - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:bgp><nc:family> +# <nc:evpn delete="delete"/></nc:family><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> +# - <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"/> +# +# 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 -# 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; @@ -759,6 +961,7 @@ EXAMPLES = """ # } # } # } + # Using overridden # # Before state @@ -837,23 +1040,96 @@ EXAMPLES = """ - 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 + 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: +# - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:bgp><nc:family> +# <nc:evpn delete="delete"/><nc:inet delete="delete"/></nc:family><nc:family><nc:evpn delete="delete"/> +# </nc:family><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> +# - <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"/> +# # After state # ----------- # @@ -960,19 +1236,91 @@ EXAMPLES = """ - name: Delete Junos BGP address family config based on the afi junipernetworks.junos.junos_bgp_address_family: - config: - address_family: - - afi: 'inet' - state: deleted + 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: +# - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:bgp> +# <nc:family><nc:inet delete="delete"/></nc:family></nc:bgp></nc:protocols> +# - <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"/> +# +# 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 -# preference 2; -# hold-time 5; -# advertise-inactive; -# out-delay 10; # family evpn { # signaling { # accepted-prefix-limit { @@ -992,10 +1340,6 @@ EXAMPLES = """ # ------------ # # admin# show protocols bgp -# preference 2; -# hold-time 5; -# advertise-inactive; -# out-delay 10; # family inet { # unicast { # local-ipv4-address 9.9.9.9; @@ -1068,18 +1412,79 @@ EXAMPLES = """ - name: Delete complete Junos BGP address family config junipernetworks.junos.junos_bgp_address_family: - config: - state: deleted + 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: +# - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:bgp><nc:family><nc:evpn delete="delete"/><nc:inet delete="delete"/> +# </nc:family></nc:bgp></nc:protocols> +# - <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"/> +# +# after: {} # After state # ----------- # # admin# show protocols bgp -# preference 2; -# hold-time 5; -# advertise-inactive; -# out-delay 10; - +# # Using gathered # @@ -1087,10 +1492,6 @@ EXAMPLES = """ # ------------ # # admin# show protocols bgp -# preference 2; -# hold-time 5; -# advertise-inactive; -# out-delay 10; # family inet { # unicast { # local-ipv4-address 9.9.9.9; @@ -1167,92 +1568,64 @@ EXAMPLES = """ 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" -# } -# ] -# } +# 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 # ------------ @@ -1396,96 +1769,66 @@ EXAMPLES = """ running_config: "{{ lookup('file', './parsed.cfg') }}" state: parsed # +# Task Output: +# ------------ # -# ------------------------- -# Module Execution Result -# ------------------------- -# -# -# "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" -# } -# ] -# } +# 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: @@ -1548,14 +1891,10 @@ EXAMPLES = """ graceful_restart_forwarding_state_bit: 'from-fib' state: rendered +# Task Output: +# ------------ # -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# -# "rendered": "<nc:protocols xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> +# rendered: "<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>20</nc:maximum> # <nc:teardown><nc:limit-threshold>98</nc:limit-threshold><nc:idle-timeout><nc:timeout>2001</nc:timeout> # </nc:idle-timeout></nc:teardown></nc:accepted-prefix-limit><nc:damping/><nc:defer-initial-multipath-build> @@ -1581,7 +1920,6 @@ EXAMPLES = """ # <nc:routing-uptime>23000</nc:routing-uptime></nc:minimum-delay></nc:delay-route-advertisements> # <nc:graceful-restart><nc:forwarding-state-bit>from-fib</nc:forwarding-state-bit> # </nc:graceful-restart></nc:any></nc:inet></nc:family></nc:bgp></nc:protocols>" - """ RETURN = """ before: @@ -1612,6 +1950,26 @@ commands: </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'] +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +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. """ diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_bgp_global.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_bgp_global.py index de4715ff0..70c779e32 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_bgp_global.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_bgp_global.py @@ -947,6 +947,7 @@ options: - purged - merged - replaced + - overridden - deleted - gathered - parsed @@ -956,16 +957,15 @@ options: EXAMPLES = """ # Using merged # -# Before state -# ------------ +# Before state: +# ------------- # -# admin# show protocols bgp -# [edit] +# vsrx# show bgp summary +# BGP is not running -# admin# show routing-options autonomous-system -# [edit] +# vsrx# show routing-options autonomous-system -- name: Merge Junos BGP config +- name: Merge provided bgp config with device configuration junipernetworks.junos.junos_bgp_global: config: as_number: "65534" @@ -973,8 +973,6 @@ EXAMPLES = """ asdot_notation: true 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 authentication_algorithm: "md5" @@ -997,13 +995,50 @@ EXAMPLES = """ preference: 2 state: merged -# After state -# ----------- +# Task Output: +# ------------ +# before: {} +# +# commands: +# - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:bgp><nc:accept-remote-nexthop/> +# <nc:add-path-display-ipv4-address/><nc:advertise-from-main-vpn-tables/><nc:advertise-> +# - <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:autonomous-system>65534<nc:loops>3</nc:loops><nc:asdot-notation/></nc:autonomous-system></nc:routing-options> # -# admin# show routing-options autonomous-system +# 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; -# admin# show protocols bgp +# vsrx# show protocols bgp # precision-timers; # advertise-from-main-vpn-tables; # holddown-all-stale-labels; @@ -1026,22 +1061,17 @@ EXAMPLES = """ # bmp { # monitor enable; # } -# advertise-bgp-static { -# policy static-to-bgp; -# } # add-path-display-ipv4-address; # egress-te-sid-stats; - -# Using merged +# Using replaced # -# Before state -# ------------ +# Before state: +# ------------- # -# admin# show routing-options autonomous-system -# 65534 loops 3 asdot-notation; - -# admin# show protocols bgp +# vsrx# show routing-options autonomous-system +# [edit] +# vsrx# show protocols bgp # precision-timers; # advertise-from-main-vpn-tables; # holddown-all-stale-labels; @@ -1064,146 +1094,123 @@ EXAMPLES = """ # bmp { # monitor enable; # } -# advertise-bgp-static { -# policy static-to-bgp; -# } # add-path-display-ipv4-address; # egress-te-sid-stats; -- name: Update running Junos BGP config +- name: Replace running config with provided config junipernetworks.junos.junos_bgp_global: config: - 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 - state: merged + 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 -# After state -# ----------- +# Task Output: +# ------------ # -# admin# show routing-options autonomous-system -# 65534 loops 3 asdot-notation; +# 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' -# admin# show protocols bgp -# precision-timers; -# advertise-from-main-vpn-tables; -# holddown-all-stale-labels; -# egress-te-backup-paths { -# template customer1 { -# peer 11.11.11.11; -# peer 11.11.11.12; -# peer 11.11.11.13; -# remote-nexthop { -# 2.2.2.2; -# } -# } -# } -# description "This is configured with Junos_bgp resource module"; -# accept-remote-nexthop; +# commands: +# - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:bgp> +# <nc:accept-remote-nexthop delete="delete"/><nc:add-path-display-ipv4-address delete="delete"/><nc:advertise-bgp-t +# delete="delete"/><nc:include-mp-next-hop delete="delete"/><nc:ipsec-sa delete="delete"/><nc:keep delete="delete"/> +# <nc:local-address delete="delete"/><nc:local-interface delete="delete"/t +# delete="delete"/></nc:bgp><nc:bgp><nc:advertise-inactive/><nc:egress-te-sid-stats/> +# <nc:authentication-algorithm>md5</nc:authentication-algorithm><nc:description>Replace running bgp conf> +# - <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:autonomous-system delete="delete"/></nc:routing-options> + +# +# 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; -# no-advertise-peer-as; -# no-aggregator-id; # out-delay 10; -# log-updown; -# damping; # bgp-error-tolerance { -# malformed-route-limit 20000000; +# malformed-route-limit 40000000; # } # authentication-algorithm md5; -# no-client-reflect; -# include-mp-next-hop; -# bmp { -# monitor enable; -# } -# add-path-display-ipv4-address; -# egress-te-sid-stats; -# group internal { -# type internal; -# accept-remote-nexthop; -# out-delay 30; -# vpn-apply-export; -# peer-as 65534; -# add-path-display-ipv4-address; -# allow [ 0.0.0.0/0 1.1.1.0/24 ]; -# neighbor 11.11.11.11 { -# out-delay 11; -# peer-as 65534; -# } -# neighbor 11.11.11.12 { -# out-delay 12; -# peer-as 65534; -# } -# } -# group external { -# accept-remote-nexthop; -# out-delay 20; -# peer-as 65534; -# add-path-display-ipv4-address; -# neighbor 12.12.12.12 { -# accept-remote-nexthop; -# out-delay 21; -# peer-as 65534; -# add-path-display-ipv4-address; -# } -# neighbor 11.11.11.13 { -# accept-remote-nexthop; -# out-delay 31; -# peer-as 65534; -# add-path-display-ipv4-address; +# 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 replaced +# Using overridden +# "(NOTE: This will work same as replaced operation)" # -# Before state -# ------------ +# Before state: +# ------------- # -# admin# show routing-options autonomous-system +# vsrx# show routing-options autonomous-system # [edit] -# admin# show protocols bgp +# vsrx# show protocols bgp # precision-timers; # advertise-from-main-vpn-tables; # holddown-all-stale-labels; @@ -1226,40 +1233,93 @@ EXAMPLES = """ # bmp { # monitor enable; # } -# advertise-bgp-static { -# policy static-to-bgp; -# } # add-path-display-ipv4-address; # egress-te-sid-stats; -- name: Replace Junos BGP global config +- name: Override running config with provided config junipernetworks.junos.junos_bgp_global: - config: - advertise_bgp_static: - policy: "static-to-bgp" - 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: "This is configured with Junos_bgp resource module replace" - egress_te_sid_stats: true - hold_time: 5 - out_delay: 10 - preference: "2" - state: replaced - -# After state -# ----------- + 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: +# - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:bgp> +# <nc:accept-remote-nexthop delete="delete"/><nc:add-path-display-ipv4-address delete="delete"/><nc:advertise-bgp-t +# delete="delete"/><nc:include-mp-next-hop delete="delete"/><nc:ipsec-sa delete="delete"/><nc:keep delete="delete"/> +# <nc:local-address delete="delete"/><nc:local-interface delete="delete"/t +# delete="delete"/></nc:bgp><nc:bgp><nc:advertise-inactive/><nc:egress-te-sid-stats/> +# <nc:authentication-algorithm>md5</nc:authentication-algorithm><nc:description>Replace running bgp conf> +# - <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:autonomous-system delete="delete"/></nc:routing-options> + # -# admin# show protocols bgp -# description "This is configured with Junos_bgp resource module replace"; +# 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; @@ -1268,9 +1328,6 @@ EXAMPLES = """ # malformed-route-limit 40000000; # } # authentication-algorithm md5; -# advertise-bgp-static { -# policy static-to-bgp; -# } # bfd-liveness-detection { # version automatic; # minimum-receive-interval 8; @@ -1282,136 +1339,149 @@ EXAMPLES = """ # } # egress-te-sid-stats; -# admin# show routing-options autonomous-system -# [edit] +# vsrx# show routing-options autonomous-system -# # Using deleted -# +# "(NOTE: This WILL delete the bgp global attributes)" # Before state # ------------ # -# admin# 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; +# vsrx# show protocols bgp +# description "Replace running bgp config"; # 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; +# malformed-route-limit 40000000; # } # authentication-algorithm md5; -# no-client-reflect; -# include-mp-next-hop; -# bmp { -# monitor enable; +# bfd-liveness-detection { +# version automatic; +# minimum-receive-interval 8; +# multiplier 30; +# no-adaptation; +# transmit-interval { +# minimum-interval 4; +# } # } -# add-path-display-ipv4-address; # egress-te-sid-stats; -# group internal { -# out-delay 12; -# } -# admin# show routing-options autonomous-system -# 65534 loops 3 asdot-notation; -- name: Delete Junos BGP global config +- name: Delete bgp section of running config junipernetworks.junos.junos_bgp_global: config: state: deleted -# After state -# ----------- -# admin# show protocols bgp -# group internal { -# out-delay 12; -# } +# 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: +# - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:bgp><nc:accept-remote-nexthop delete="delete"/> +# <nc:add-path-display-ipv4-address delete="delete"/><nc:advertise-bgp-t +# delete="delete"/><nc:include-mp-next-hop delete="delete"/><nc:ipsec-sa delete="delete"/><nc:keep delete="delete"/> +# <nc:local-address delete="delete"/><nc:local-interface delete="delete"/t +# delete="delete"/></nc:bgp></nc:protocols> +# - <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"/> -# admin# show protocols bgp -# [edit] +# after: {} + +# After state: +# ------------ +# vsrx# show protocols bgp + +# vsrx# show routing-options autonomous-system -# admin# show routing-options autonomous-system -# [edit] # Using gathered # -# Before state -# ------------ +# Before state: +# ------------- # -# admin# show protocols bgp -# description "This is configured with Junos_bgp resource module replace"; +# 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 40000000; +# malformed-route-limit 20000000; # } # 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; -# } +# no-client-reflect; +# include-mp-next-hop; +# bmp { +# monitor enable; # } +# add-path-display-ipv4-address; # egress-te-sid-stats; -- name: Gather Junos BGP global config +- name: Gather BGP facts from running config junipernetworks.junos.junos_bgp_global: config: state: gathered -# -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# "gathered": { -# "advertise_bgp_static": { -# "policy": "static-to-bgp" -# }, -# "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": "This is configured with Junos_bgp resource module replace", -# "egress_te_sid_stats": true, -# "hold_time": 5, -# "out_delay": 10, -# "preference": "2" -# } -# -# -# Using purged -# -# Before state + +# 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: +# ------------- # -# admin# show protocols bgp +# vsrx# show protocols bgp # precision-timers; # advertise-from-main-vpn-tables; # holddown-all-stale-labels; @@ -1436,41 +1506,68 @@ EXAMPLES = """ # } # add-path-display-ipv4-address; # egress-te-sid-stats; -# group internal { -# out-delay 12; -# } -# admin# show routing-options autonomous-system -# 65534 loops 3 asdot-notation; -- name: Purge Junos BGP global config +- name: Purge BGP config from running config junipernetworks.junos.junos_bgp_global: config: state: purged -# After state -# ---------- -# admin# show protocols bgp -# -# [edit] -# admin# show routing-options autonomous-system -# -#[edit] +# 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: +# - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:bgp delete="delete"/></nc:protocols> +# - <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:autonomous-system delete="delete"/></nc:routing-options> + +# after: {} + +# After state: +# ------------ +# vsrx# show protocols bgp + +# vsrx# show routing-options autonomous-system # Using rendered -# -# -- name: Render the commands for provided configuration + +- 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" - 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: @@ -1479,41 +1576,25 @@ EXAMPLES = """ 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 -# -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# -# "rendered": " -# <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>" +# Task Output: +# ------------ + +# rendered: +# <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:bgp><nc:accept-remote-nexthop/><nc:add-path-display-ipv4-address/> +# <nc:advertise-from-main-vpn-tables/><nc:ad> + # # Using parsed # parsed.cfg @@ -1619,64 +1700,66 @@ EXAMPLES = """ # </rpc-reply> -- name: Parsed the device configuration to get output commands +- name: Parsed the device configuration to get ansible facts junipernetworks.junos.junos_bgp_global: running_config: "{{ lookup('file', './parsed.cfg') }}" state: parsed -# -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# -# "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, -# "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" -# } -# +# 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: @@ -1723,6 +1806,26 @@ commands: </nc:bmp> </nc:bgp> </nc:protocols>', '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: + - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +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. """ @@ -1745,6 +1848,7 @@ def main(): required_if = [ ("state", "merged", ("config",)), ("state", "replaced", ("config",)), + ("state", "overridden", ("config",)), ("state", "rendered", ("config",)), ("state", "parsed", ("running_config",)), ] diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_command.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_command.py index ec713f230..602a24138 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_command.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_command.py @@ -114,17 +114,17 @@ EXAMPLES = """ - name: run multiple commands on remote nodes junipernetworks.junos.junos_command: commands: - - show version - - show interfaces + - show version + - show interfaces - name: run multiple commands and evaluate the output junipernetworks.junos.junos_command: commands: - - show version - - show interfaces + - show version + - show interfaces wait_for: - - result[0] contains Juniper - - result[1] contains Loopback0 + - result[0] contains Juniper + - result[1] contains Loopback0 - name: run commands and specify the output format junipernetworks.junos.junos_command: @@ -204,7 +204,6 @@ USE_PERSISTENT_CONNECTION = True def rpc(module, items): - responses = list() for item in items: name = item["name"] diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_config.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_config.py index c8bfde10c..5b5151d39 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_config.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_config.py @@ -62,7 +62,7 @@ options: back to initial defaults. This argument will effectively remove all current configuration statements on the remote device. type: bool - default: no + default: false confirm: description: - The C(confirm) argument will configure a time out value in minutes for the commit @@ -95,7 +95,7 @@ options: playbook root directory or role root directory, if playbook is part of an ansible role. If the directory does not exist, it is created. type: bool - default: no + default: false update: description: - This argument will decide how to load the configuration data particularly when @@ -124,19 +124,19 @@ options: - This argument will execute commit operation on remote device. It can be used to confirm a previous commit. type: bool - default: no + 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: no + 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(yes), - if C(backup) is set to I(no) this option will be silently ignored. + 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: @@ -172,8 +172,7 @@ requirements: 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 - #why-do-the-config-modules-always-return-changed-true-with-abbreviated-commands). +- 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. @@ -191,20 +190,20 @@ EXAMPLES = """ - 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" + - 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 + - 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: yes + check_commit: true - name: rollback the configuration to id 10 junipernetworks.junos.junos_config: @@ -212,31 +211,30 @@ EXAMPLES = """ - name: zero out the current configuration junipernetworks.junos.junos_config: - zeroize: yes + 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 + - 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: yes + confirm_commit: true - name: for idempotency, use full-form commands junipernetworks.junos.junos_config: lines: - # - set int ge-0/0/1 unit 0 desc "Test interface" - - set interfaces ge-0/0/1 unit 0 description "Test interface" + - set interfaces ge-0/0/1 unit 0 description "Test interface" - name: configurable backup path junipernetworks.junos.junos_config: src: srx.cfg - backup: yes + backup: true backup_options: filename: backup.cfg dir_path: /home/user @@ -245,27 +243,27 @@ EXAMPLES = """ RETURN = """ backup_path: description: The full path to the backup file - returned: when backup is yes + 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 yes and filename is not specified in backup options + 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 yes and filename is not specified in backup options + 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 yes + 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 yes + returned: when backup is true type: str sample: "22:28:34" """ @@ -366,7 +364,6 @@ def filter_delete_statements(module, candidate): def configure_device(module, warnings, candidate): - kwargs = {} config_format = None @@ -468,7 +465,7 @@ def main(): result["__backup__"] = reply rollback_id = module.params["rollback"] - if rollback_id: + if isinstance(rollback_id, int) and rollback_id >= 0: diff = rollback(module, rollback_id) if commit: kwargs = {"comment": module.params["comment"]} diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_hostname.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_hostname.py index 093645a6f..86eb0f7df 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_hostname.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_hostname.py @@ -300,7 +300,6 @@ EXAMPLES = """ # "hostname": "vsrx-18.4R1" # } # - """ RETURN = """ before: diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_interfaces.py index f3b749d63..04f65df96 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_interfaces.py @@ -134,57 +134,163 @@ notes: being managed. - Tested against vSRX JUNOS version 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). + 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 deleted +# Using merged # Before 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"; +# description "test interface"; +# speed 1g; # } -# ge-0/0/2 { -# description "Configured by Ansible-2"; -# ether-options { -# auto-negotiation; -# } +# 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: "Delete given options for the interface (Note: This won't delete the interface itself if any other values are configured for interface)" +- 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 - speed: 1g - mtu: 1800 - - name: ge-0/0/2 - description: Configured by Ansible -2 - state: deleted + - 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: +# - <nc:interfaces xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:interface><nc:name>ge-0/0/1</nc:name> +# <nc:description>Configured by Ansible-1</nc:description><nc:mtu>1800</nc:mtu><nc:unit><nc:name>0</nc:name> +# <nc:description>This is logical intf unit0</nc:description></nc:unit></nc:interface><nc:interface><nc:name>ge-0/0/2</nc:name> +# <nc:description>Configured by Ansible-2</nc:description><nc:disable/></nc:interface></nc:interfaces> +# 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 { -# ether-options { -# auto-negotiation; -# } +# 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 merged +# Using deleted # Before state: # ------------- -# user@junos01# show interfaces +# # ge-0/0/1 { -# description "test interface"; -# speed 1g; +# description "Configured by Ansible-1"; +# speed 1g; +# mtu 1800; +# unit 0 { +# description "This is logical intf unit0"; +# } # } # fe-0/0/2 { # vlan-tagging; @@ -195,82 +301,262 @@ EXAMPLES = """ # 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: Merge provided configuration with device configuration (default operation - is merge) +- 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 - 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 + - 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: +# - <nc:interfaces xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:interface> +# <nc:name>ge-0/0/1</nc:name><nc:description delete="delete"/> +# <nc:speed delete="delete"/><nc:mtu delete="delete"/><nc:link-mode delete="delete"/> +# <nc:disable delete="delete"/><nc:hold-time><nc:up delete="delete"/><nc:down delete="delete"/></nc:hold-time><nc:unit> +# <nc:name>0</nc:name><nc:description delete="delete"/></nc:unit></nc:interface><nc:interface><nc:name>ge-0/0/2</nc:name> +# <nc:description delete="delete"/><nc:speed delete="delete"/><nc:mtu delete="delete"/><nc:link-mode delete="delete"/> +# <nc:disable delete="delete"/><nc:hold-time><nc:up delete="delete"/><nc:down delete="delete"/></nc:hold-time></nc:interface> +# </nc:interfaces> +# 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 { -# description "Configured by Ansible-1"; -# speed 1g; -# mtu 1800 -# unit 0 { -# description "This is logical intf unit0"; -# } +# unit 0; # } -# ge-0/0/2 { -# disable; -# description "Configured by Ansible-2"; +# 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 { -# description "Configured by Ansible-1"; -# speed 1g; -# mtu 1800 +# unit 0; # } -# ge-0/0/2 { -# disable; -# description "Configured by Ansible-2"; -# ether-options { -# auto-negotiation; -# } +# 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; +# } +# } # } -# ge-0/0/11 { -# description "Configured by Ansible-11"; +# 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: - - name: ge-0/0/2 - description: Configured by Ansible-2 - enabled: false - mtu: 2800 - - name: ge-0/0/3 - description: Configured by Ansible-3 + - 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: +# - <nc:interfaces xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:interface><nc:name>ge-0/0/1</nc:name><nc:description delete="delete"/> +# <nc:speed delete="delete"/><nc:mtu delete="delete"/><nc:link-mode delete="delete"/> +# <nc:disable delete="delete"/><nc:hold-time><nc:up delete="delete"/><nc:down delete="delete"/> +# </nc:hold-time></nc:interface><nc:interface><nc:name>fe-0/0/2</nc:name><nc:description delete="delete"/> +# <nc:speed delete="delete"/><nc:mtu delete="delete"/><nc:link-mode delete="delete"/><nc:disable delete="delete"/> +# <nc:hold-time><nc:up delete="delete"/><nc:down delete="delete"/></nc:hold-time></nc:interface><nc:interface> +# <nc:name>ge-0/0/3</nc:name><nc:description delete="delete"/><nc:speed delete="delete"/><nc:mtu delete="delete"/> +# <nc:link-mode delete="delete"/><nc:disable delete="delete"/><nc:hold-time> +# <nc:up delete="delete"/><nc:down delete="delete"/></nc:hold-time></nc:interface> +# <nc:interface><nc:name>fxp0</nc:name><nc:description delete="delete"/><nc:speed delete="delete"/> +# <nc:link-mode delete="delete"/><nc:disable delete="delete"/> +# <nc:hold-time><nc:up delete="delete"/><nc:down delete="delete"/> +# </nc:hold-time></nc:interface><nc:interface><nc:name>lo0</nc:name> +# <nc:description delete="delete"/><nc:disable delete="delete"/> +# <nc:hold-time><nc:up delete="delete"/><nc:down delete="delete"/> +# </nc:hold-time></nc:interface><nc:interface><nc:name>ge-0/0/1</nc:name> +# </nc:interface><nc:interface><nc:name>fe-0/0/2</nc:name> +# <nc:description>Configured by Ansible-2</nc:description> +# <nc:mtu>2800</nc:mtu><nc:disable/></nc:interface><nc:interface> +# <nc:name>ge-0/0/3</nc:name><nc:description>Updated by Ansible-3</nc:description> +# </nc:interface><nc:interface><nc:name>fxp0</nc:name></nc:interface><nc:interface> +# <nc:name>lo0</nc:name></nc:interface></nc:interfaces> +# 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/2 { -# disable; -# description "Configured by Ansible-2"; -# mtu 2800 +# 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 "Configured by Ansible-3"; +# description "Updated by Ansible-3"; +# } +# fxp0 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# lo0 { +# unit 0 { +# family inet { +# address 192.0.2.1/32; +# } +# } # } @@ -278,143 +564,212 @@ EXAMPLES = """ # Before state: # ------------- +# # user@junos01# show interfaces # ge-0/0/1 { -# description "Configured by Ansible-1"; -# speed 1g; -# mtu 1800 +# unit 0; # } -# ge-0/0/2 { -# disable; -# mtu 1800; -# speed 1g; -# description "Configured by Ansible-2"; -# ether-options { -# auto-negotiation; -# } +# 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"; # } -# ge-0/0/11 { -# description "Configured by Ansible-11"; +# fxp0 { +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } +# lo0 { +# unit 0 { +# family inet { +# address 192.0.2.1/32; +# } +# } # } -- name: Replaces device configuration of listed interfaces with provided configuration +- 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 + - 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: +# - <nc:interfaces xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:interface> +# <nc:name>ge-0/0/2</nc:name><nc:description delete="delete"/><nc:speed delete="delete"/> +# <nc:mtu delete="delete"/><nc:link-mode delete="delete"/><nc:disable delete="delete"/> +# <nc:hold-time><nc:up delete="delete"/><nc:down delete="delete"/></nc:hold-time></nc:interface> +# <nc:interface><nc:name>ge-0/0/3</nc:name><nc:description delete="delete"/><nc:speed delete="delete"/> +# <nc:mtu delete="delete"/><nc:link-mode delete="delete"/><nc:disable delete="delete"/><nc:hold-time> +# <nc:up delete="delete"/><nc:down delete="delete"/></nc:hold-time></nc:interface><nc:interface><nc:name>ge-0/0/2</nc:name> +# <nc:description>Configured by Ansible-2</nc:description><nc:mtu>2800</nc:mtu><nc:disable/></nc:interface><nc:interface> +# <nc:name>ge-0/0/3</nc:name><nc:description>Configured by Ansible-3</nc:description></nc:interface></nc:interfaces> +# 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 { -# description "Configured by Ansible-1"; -# speed 1g; -# mtu 1800 -# } -# ge-0/0/2 { -# disable; -# description "Configured by Ansible-2"; -# mtu 2800 -# } -# ge-0/0/3 { -# description "Configured by Ansible-3"; -# } -# ge-0/0/11 { -# description "Configured by Ansible-11"; +# unit 0; # } -# Using gathered -# Before state: -# ------------ -# -# vagrant@vsrx# show interfaces # fe-0/0/2 { -# description "This is interface DESCRIPTION"; +# description "Configured by Ansible-2"; +# disable; # vlan-tagging; +# mtu 2800; # unit 10 { -# description "UNIT 10 DESCRIPTION"; # vlan-id 10; # } # unit 11 { -# description "UNIT 11 DESCRIPTION"; # 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 { -# description OUTER; # unit 0 { -# description "Sample config"; # family inet { # dhcp; # } # } # } -# -- name: Gather junos interfaces as in given arguments - junipernetworks.junos.junos_interfaces: - state: gathered -# Task Output (redacted) -# ----------------------- -# -# "gathered": [ -# { -# "description": "This is interface DESCRIPTION", -# "enabled": true, -# "name": "fe-0/0/2", -# "units": [ -# { -# "description": "UNIT 10 DESCRIPTION", -# "name": 10 -# }, -# { -# "description": "UNIT 11 DESCRIPTION", -# "name": 11 -# } -# ] -# }, -# { -# "description": "OUTER", -# "enabled": true, -# "name": "fxp0", -# "units": [ -# { -# "description": "Sample config", -# "name": 0 -# } -# ] +# lo0 { +# unit 0 { +# family inet { +# address 192.0.2.1/32; # } -# ] -# After state: +# } +# } + +# Using gathered + +# Before state: # ------------ # # vagrant@vsrx# show interfaces +# ge-0/0/1 { +# unit 0; +# } # fe-0/0/2 { -# description "This is interface DESCRIPTION"; +# description "Configured by Ansible-2"; +# disable; # vlan-tagging; +# mtu 2800; # unit 10 { -# description "UNIT 10 DESCRIPTION"; # vlan-id 10; # } # unit 11 { -# description "UNIT 11 DESCRIPTION"; # 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 { -# description OUTER; # unit 0 { -# description "Sample config"; # 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 # ------------ # @@ -448,46 +803,48 @@ EXAMPLES = """ # </interfaces> # </configuration> # </rpc-reply> -# - name: Convert interfaces config to argspec without connecting to the appliance + +# - 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 (redacted) -# ----------------------- -# "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" -# } -# ] + +# 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 Ansibull - mtu: 2048 - speed: 20m - hold_time: - up: 3200 - down: 3200 + - name: ge-0/0/2 + description: Configured by Ansible + mtu: 2048 + speed: 20m + hold_time: + up: 3200 + down: 3200 state: rendered -# Task Output (redacted) -# ----------------------- -# "rendered": <nc:interfaces + +# Task Output +# ----------- +# +# rendered: <nc:interfaces # xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> # <nc:interface> # <nc:name>ge-0/0/2</nc:name> -# <nc:description>Configured by Ansibull</nc:description> +# <nc:description>Configured by Ansible</nc:description> # <nc:speed>20m</nc:speed> # <nc:mtu>2048</nc:mtu> # <nc:hold-time> @@ -496,7 +853,6 @@ EXAMPLES = """ # </nc:hold-time> # </nc:interface> # </nc:interfaces>" - """ RETURN = """ before: @@ -547,6 +903,29 @@ xml: </interfaces> </configuration> </rpc-reply>', '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: + - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +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 diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_l2_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_l2_interfaces.py index d5def410b..bbd5f25b5 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_l2_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_l2_interfaces.py @@ -113,122 +113,169 @@ 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). +- 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 deleted +# Using merged # Before state: # ------------- # # ansible@junos01# show interfaces # ge-0/0/1 { -# description "L2 interface"; -# speed 1g; -# unit 0 { -# family ethernet-switching { -# interface-mode access; -# vlan { -# members vlan30; -# } -# } -# } -#} -#ge-0/0/2 { -# description "non L2 interface"; -# unit 0 { -# family inet { -# address 192.168.56.14/24; -# } -# } - -- 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 - -# After state: -# ------------ -# -# ansible@junos01# show interfaces -# ge-0/0/1 { -# description "L2 interface"; -# speed 1g; +# unit 0 { +# family inet; +# family inet6; +# } +# } +# ge-0/0/2 { +# unit 0 { +# family inet; +# family inet6; +# } # } -#ge-0/0/2 { -# description "non L2 interface"; -# unit 0 { -# family inet { -# address 192.168.56.14/24; -# } -# } - - -# Using merged - -# Before state: -# ------------- -# ansible@junos01# show interfaces # ge-0/0/3 { -# description "test interface"; -# speed 1g; -#} +# unit 0 { +# family ethernet-switching { +# interface-mode access; +# } +# } +# } # ge-0/0/4 { -# description interface-trunk; -# native-vlan-id 100; -# unit 0 { -# family ethernet-switching { -# interface-mode trunk; -# vlan { -# members [ vlan40 ]; -# } -# } -# } -# } - -- name: Merge provided configuration with device configuration (default operation - is merge) +# 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 + - 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: +# - <nc:interfaces xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:interface> +# <nc:name>ge-0/0/3</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>v101</nc:members> +# </nc:vlan> +# </nc:ethernet-switching> +# </nc:family> +# </nc:unit> +# </nc:interface> +# <nc:interface> +# <nc:name>ge-0/0/4</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>vlan30</nc:members> +# </nc:vlan> +# </nc:ethernet-switching> +# </nc:family> +# </nc:unit> +# <nc:native-vlan-id>50</nc:native-vlan-id> +# </nc:interface> +# </nc:interfaces> +# 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 { -# description "test interface"; -# speed 1g; -# unit 0 { -# family ethernet-switching { -# interface-mode access; -# vlan { -# members v101; -# } -# } -# } +# unit 0 { +# family ethernet-switching { +# interface-mode access; +# vlan { +# members v101; +# } +# } +# } # } # ge-0/0/4 { -# description interface-trunk; -# native-vlan-id 50; -# unit 0 { -# family ethernet-switching { -# interface-mode trunk; -# vlan { -# members [ vlan40 vlan30 ]; -# } -# } -# } +# native-vlan-id 50; +# unit 0 { +# family ethernet-switching { +# interface-mode trunk; +# vlan { +# members vlan30; +# } +# } +# } +# } +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } # } @@ -237,94 +284,211 @@ EXAMPLES = """ # 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 { -# description "test interface"; -# speed 1g; -#} +# unit 0 { +# family ethernet-switching { +# interface-mode access; +# vlan { +# members v101; +# } +# } +# } +# } # ge-0/0/4 { -# description interface-trunk; -# native-vlan-id 100; -# unit 0 { -# family ethernet-switching { -# interface-mode trunk; -# vlan { -# members [ vlan40 ]; -# } -# } -# } -# } -# ge-0/0/5 { -# description "Configured by Ansible-11"; -# unit 0 { -# family ethernet-switching { -# interface-mode access; -# vlan { -# members v101; -# } -# } -# } +# 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/3 - access: - vlan: v101 - name: ge-0/0/4 trunk: allowed_vlans: - - vlan30 - native_vlan: 50 + - 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: +# - <nc:interfaces xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:interface> +# <nc:name>ge-0/0/4</nc:name> +# <nc:unit> +# <nc:name>0</nc:name> +# <nc:family> +# <nc:ethernet-switching> +# <nc:interface-mode delete="delete"/> +# <nc:vlan delete="delete"/> +# </nc:ethernet-switching> +# </nc:family> +# </nc:unit> +# <nc:native-vlan-id delete="delete"/> +# </nc:interface> +# <nc:interface> +# <nc:name>ge-0/0/4</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>v101</nc:members> +# </nc:vlan> +# </nc:ethernet-switching> +# </nc:family> +# </nc:unit> +# <nc:native-vlan-id>30</nc:native-vlan-id> +# </nc:interface> +# <nc:interface> +# <nc:name>ge-0/0/3</nc:name> +# <nc:unit> +# <nc:name>0</nc:name> +# <nc:family> +# <nc:ethernet-switching> +# <nc:interface-mode delete="delete"/> +# <nc:vlan delete="delete"/> +# </nc:ethernet-switching> +# </nc:family> +# </nc:unit> +# <nc:native-vlan-id delete="delete"/> +# </nc:interface> +# </nc:interfaces> +# 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 { -# interface-mode access; -# vlan { -# members v101; -# } -# } -# } +# unit 0 { +# family ethernet-switching; +# } # } # ge-0/0/4 { -# description interface-trunk; -# native-vlan-id 50; -# unit 0 { -# family ethernet-switching { -# interface-mode trunk; -# vlan { -# members [ vlan30 ]; -# } -# } -# } +# 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 { -# description "test interface"; -# speed 1g; -#} +# unit 0 { +# family ethernet-switching; +# } +# } # ge-0/0/4 { -# description interface-trunk; -# native-vlan-id 100; -# unit 0 { -# family ethernet-switching { -# interface-mode trunk; -# vlan { -# members [ vlan40 ]; -# } -# } -# } +# 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 @@ -340,111 +504,268 @@ EXAMPLES = """ 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: +# - <nc:interfaces xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:interface> +# <nc:name>ge-0/0/4</nc:name> +# <nc:unit> +# <nc:name>0</nc:name> +# <nc:family> +# <nc:ethernet-switching> +# <nc:interface-mode delete="delete"/> +# <nc:vlan delete="delete"/> +# </nc:ethernet-switching> +# </nc:family> +# </nc:unit> +# <nc:native-vlan-id delete="delete"/> +# </nc:interface> +# <nc:interface> +# <nc:name>ge-0/0/3</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>v101</nc:members> +# </nc:vlan> +# </nc:ethernet-switching> +# </nc:family> +# </nc:unit> +# </nc:interface> +# <nc:interface> +# <nc:name>ge-0/0/4</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>vlan30</nc:members> +# </nc:vlan> +# </nc:ethernet-switching> +# </nc:family> +# </nc:unit> +# <nc:native-vlan-id>50</nc:native-vlan-id> +# </nc:interface> +# </nc:interfaces> +# 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; -# } -# } -# } +# unit 0 { +# family ethernet-switching { +# interface-mode access; +# vlan { +# members v101; +# } +# } +# } # } # ge-0/0/4 { -# description interface-trunk; -# native-vlan-id 50; -# unit 0 { -# family ethernet-switching { -# interface-mode trunk; -# vlan { -# members [ vlan30 ]; -# } -# } -# } +# native-vlan-id 50; +# unit 0 { +# family ethernet-switching { +# interface-mode trunk; +# vlan { +# members vlan30; +# } +# } +# } # } -# Using gathered +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } +# } + +# Using deleted + # Before state: -# ------------ +# ------------- # -# user@junos01# show interfaces +# ansible@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 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 vlan100; +# members v101; # } # } # } # } -# ge-0/0/2 { -# description "Configured by Ansible"; -# native-vlan-id 400; -# speed 10m; -# mtu 2048; -# hold-time up 3000 down 3200; +# ge-0/0/4 { +# native-vlan-id 50; # unit 0 { # family ethernet-switching { # interface-mode trunk; # vlan { -# members [ vlan200 vlan300 ]; +# members vlan30; # } # } # } # } -# em1 { -# description TEST; -# } # fxp0 { -# description ANSIBLE; -# speed 1g; -# link-mode automatic; +# enable; # unit 0 { # family inet { -# address 10.8.38.38/24; +# dhcp; # } +# family inet6; # } # } -- name: Gather junos layer 2 interfaces as in given arguments + +- name: "Delete L2 attributes of given interfaces (Note: This won't delete the + interface itself)." junipernetworks.junos.junos_l2_interfaces: - state: gathered -# Task Output (redacted) -# ----------------------- + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + state: deleted + +# 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 -# } -# ] +# 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: +# - <nc:interfaces xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:interface> +# <nc:name>ge-0/0/3</nc:name> +# <nc:unit> +# <nc:name>0</nc:name> +# <nc:family> +# <nc:ethernet-switching> +# <nc:interface-mode delete="delete"/> +# <nc:vlan delete="delete"/> +# </nc:ethernet-switching> +# </nc:family> +# </nc:unit> +# <nc:native-vlan-id delete="delete"/> +# </nc:interface> +# </nc:interfaces> +# 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"; @@ -490,7 +811,31 @@ EXAMPLES = """ # } # } # } + +- 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 # ------------ # @@ -524,36 +869,32 @@ EXAMPLES = """ # </interfaces> # </configuration> # </rpc-reply> -# - 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 (redacted) -# ----------------------- -# "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 -# } -# ] + +- 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: @@ -567,10 +908,11 @@ EXAMPLES = """ - vlan300 native_vlan: '400' state: rendered -# Task Output (redacted) -# ----------------------- -# "rendered": "<nc:interfaces -# xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> + +# Task Output +# ----------- +# +# "rendered": "<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> @@ -602,8 +944,8 @@ EXAMPLES = """ # <nc:native-vlan-id>400</nc:native-vlan-id> # </nc:interface> # </nc:interfaces>" - """ + RETURN = """ before: description: The configuration as structured data prior to module invocation. @@ -624,38 +966,61 @@ commands: returned: always type: list 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'] + 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'] +rendered: + description: The provided configuration in the + task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +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. """ diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_l3_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_l3_interfaces.py index 3e59e0844..3e9fd57b7 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_l3_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_l3_interfaces.py @@ -43,8 +43,11 @@ requirements: - ncclient (>=v0.6.4) 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 +- 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 @@ -111,75 +114,22 @@ options: default: merged """ EXAMPLES = """ -# Using deleted - -# Before state: -# ------------- -# -# admin# show interfaces -# ge-0/0/1 { -# description "L3 interface"; -# unit 0 { -# family inet { -# address 10.200.16.10/24; -# } -# } -# } -# ge-0/0/2 { -# description "non L3 interface"; -# unit 0 { -# family ethernet-switching { -# interface-mode access; -# vlan { -# members 2; -# } -# } -# } -# } - -- name: Delete JUNOS L3 logical interface - junipernetworks.junos.junos_l3_interfaces: - config: - - name: ge-0/0/1 - - name: ge-0/0/2 - state: deleted - -# After state: -# ------------ -# -# admin# show interfaces -# ge-0/0/1 { -# description "deleted L3 interface"; -# } -# ge-0/0/2 { -# description "non L3 interface"; -# unit 0 { -# family ethernet-switching { -# interface-mode access; -# vlan { -# members 2; -# } -# } -# } -# } # Using merged + # Before state # ------------ # # admin# show interfaces -# ge-0/0/1 { -# description "L3 interface"; +# fxp0 { +# enable; # unit 0 { # family inet { -# address 10.200.16.10/24; +# dhcp; # } # } # } -# ge-0/0/2 { -# description "non configured interface"; -# unit 0; -# } -- name: Merge provided configuration with device configuration (default operation is merge) + +- name: Merge provided configuration with device configuration junipernetworks.junos.junos_l3_interfaces: config: - name: ge-0/0/1 @@ -192,15 +142,71 @@ EXAMPLES = """ - address: dhcp state: merged +# Task Output +# ----------- +# +# before: +# - ipv4: +# - address: dhcp +# name: fxp0 +# unit: '0' +# commands: +# - <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:inet> +# <nc:address> +# <nc:name>192.168.1.10/24</nc:name> +# </nc:address> +# </nc:inet> +# </nc:family> +# <nc:family> +# <nc:inet6> +# <nc:address> +# <nc:name>8d8d:8d01::1/64</nc:name> +# </nc:address> +# </nc:inet6> +# </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:inet> +# <nc:dhcp/> +# </nc:inet> +# </nc:family> +# </nc:unit> +# </nc:interface> +# </nc:interfaces> +# 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 { -# description "L3 interface"; # unit 0 { # family inet { -# address 10.200.16.10/24; # address 192.168.1.10/24; # } # family inet6 { @@ -209,14 +215,20 @@ EXAMPLES = """ # } # } # ge-0/0/2 { -# description "L3 interface with dhcp"; # unit 0 { # family inet { # dhcp; # } # } # } - +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# } +# } # Using overridden @@ -225,26 +237,27 @@ EXAMPLES = """ # # admin# show interfaces # ge-0/0/1 { -# description "L3 interface"; # unit 0 { # family inet { -# address 10.200.16.10/24; +# address 192.168.1.10/24; +# } +# family inet6 { +# address 8d8d:8d01::1/64; # } # } # } # ge-0/0/2 { -# description "L3 interface with dhcp"; # unit 0 { # family inet { # dhcp; # } # } # } -# ge-0/0/3 { -# description "another L3 interface"; +# fxp0 { +# enable; # unit 0 { # family inet { -# address 192.168.1.10/24; +# dhcp; # } # } # } @@ -255,42 +268,139 @@ EXAMPLES = """ - name: ge-0/0/1 ipv4: - address: 192.168.1.10/24 - ipv6: - - address: 8d8d:8d01::1/64 - - name: ge-0/0/2 - ipv6: - - address: 2001:db8:3000::/64 + - 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: +# - <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:inet> +# <nc:address delete="delete"/> +# </nc:inet> +# <nc:inet6> +# <nc:address delete="delete"/> +# </nc:inet6> +# </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:inet> +# <nc:dhcp delete="delete"/> +# </nc:inet> +# <nc:inet6> +# <nc:address delete="delete"/> +# </nc:inet6> +# </nc:family> +# </nc:unit> +# </nc:interface> +# <nc:interface> +# <nc:name>fxp0</nc:name> +# <nc:unit> +# <nc:name>0</nc:name> +# <nc:family> +# <nc:inet> +# <nc:dhcp delete="delete"/> +# </nc:inet> +# <nc:inet6> +# <nc:address delete="delete"/> +# </nc:inet6> +# </nc:family> +# </nc:unit> +# </nc:interface> +# <nc:interface> +# <nc:name>ge-0/0/1</nc:name> +# <nc:unit> +# <nc:name>0</nc:name> +# <nc:family> +# <nc:inet> +# <nc:address> +# <nc:name>192.168.1.10/24</nc:name> +# </nc:address> +# </nc:inet> +# </nc:family> +# </nc:unit> +# </nc:interface> +# <nc:interface> +# <nc:name>fxp0</nc:name> +# <nc:unit> +# <nc:name>0</nc:name> +# <nc:family> +# <nc:inet> +# <nc:dhcp/> +# </nc:inet> +# </nc:family> +# </nc:unit> +# </nc:interface> +# </nc:interfaces> +# 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 { -# description "L3 interface"; # unit 0 { # family inet { # address 192.168.1.10/24; # } -# family inet6 { -# address 8d8d:8d01::1/64; -# } +# family inet6; # } # } # ge-0/0/2 { -# description "L3 interface with ipv6"; # unit 0 { -# family inet6 { -# address 2001:db8:3000::/64; -# } +# family inet; +# family inet6; # } # } -# ge-0/0/3 { -# description "overridden L3 interface"; -# unit 0; +# fxp0 { +# enable; +# unit 0 { +# family inet { +# dhcp; +# } +# family inet6; +# } # } - # Using replaced # Before state @@ -298,23 +408,26 @@ EXAMPLES = """ # # admin# show interfaces # ge-0/0/1 { -# description "L3 interface"; # unit 0 { # family inet { -# address 10.200.16.10/24; +# address 192.168.1.10/24; # } +# family inet6; # } # } # ge-0/0/2 { -# description "non configured interface"; -# unit 0; +# unit 0 { +# family inet; +# family inet6; +# } # } -# ge-0/0/3 { -# description "another L3 interface"; +# fxp0 { +# enable; # unit 0 { # family inet { -# address 192.168.1.10/24; +# dhcp; # } +# family inet6; # } # } @@ -331,12 +444,101 @@ EXAMPLES = """ - 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: +# - <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:inet> +# <nc:address delete="delete"/> +# </nc:inet> +# <nc:inet6> +# <nc:address delete="delete"/> +# </nc:inet6> +# </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:inet/> +# <nc:inet6> +# <nc:address delete="delete"/> +# </nc:inet6> +# </nc:family> +# </nc:unit> +# </nc:interface> +# <nc:interface> +# <nc:name>ge-0/0/1</nc:name> +# <nc:unit> +# <nc:name>0</nc:name> +# <nc:family> +# <nc:inet> +# <nc:address> +# <nc:name>192.168.1.10/24</nc:name> +# </nc:address> +# </nc:inet> +# </nc:family> +# <nc:family> +# <nc:inet6> +# <nc:address> +# <nc:name>8d8d:8d01::1/64</nc:name> +# </nc:address> +# </nc:inet6> +# </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:inet> +# <nc:dhcp/> +# </nc:inet> +# </nc:family> +# </nc:unit> +# </nc:interface> +# </nc:interfaces> +# 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 { -# description "L3 interface"; # unit 0 { # family inet { # address 192.168.1.10/24; @@ -347,151 +549,152 @@ EXAMPLES = """ # } # } # ge-0/0/2 { -# description "L3 interface with dhcp"; # unit 0 { # family inet { # dhcp; # } +# family inet6; # } # } -# ge-0/0/3 { -# description "another L3 interface"; +# fxp0 { +# enable; # unit 0 { # family inet { -# address 192.168.1.10/24; +# dhcp; # } +# family inet6; # } # } -# Using gathered + +# Using deleted + # Before state: -# ------------ +# ------------- # -# user@junos01# show interfaces +# admin# 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; -# } +# family inet { +# address 192.168.1.10/24; +# } +# family inet6 { +# address 8d8d:8d01::1/64; # } # } # } # 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 ]; -# } +# family inet { +# dhcp; # } +# family inet6; # } # } -# ge-1/0/0 { +# fxp0 { +# enable; # unit 0 { # family inet { -# address 192.168.100.1/24; -# address 10.200.16.20/24; +# dhcp; # } # family inet6; # } # } -# ge-2/0/0 { + +- 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: +# - <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:inet> +# <nc:address delete="delete"/> +# </nc:inet> +# <nc:inet6> +# <nc:address delete="delete"/> +# </nc:inet6> +# </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:inet> +# <nc:dhcp delete="delete"/> +# </nc:inet> +# <nc:inet6> +# <nc:address delete="delete"/> +# </nc:inet6> +# </nc:family> +# </nc:unit> +# </nc:interface> +# </nc:interfaces> +# 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 { -# address 192.168.100.2/24; -# address 10.200.16.21/24; -# } +# family inet; # family inet6; # } # } -# ge-3/0/0 { +# ge-0/0/2 { # unit 0 { -# family inet { -# address 192.168.100.3/24; -# address 10.200.16.22/24; -# } +# family inet; # family inet6; # } # } -# em1 { -# description TEST; -# } # fxp0 { -# description ANSIBLE; -# speed 1g; -# link-mode automatic; +# enable; # unit 0 { # family inet { -# address 10.8.38.38/24; +# dhcp; # } +# family inet6; # } # } -- name: Gather junos layer3 interfaces as in given arguments - junipernetworks.junos.junos_l3_interfaces: - state: gathered -# Task Output (redacted) -# ----------------------- -# -# "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" -# } -# ] -# After state: + +# Using gathered + +# Before state: # ------------ # # user@junos01# show interfaces @@ -566,7 +769,37 @@ EXAMPLES = """ # } # } # } + +- 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 # ------------ # @@ -611,40 +844,29 @@ EXAMPLES = """ # </interfaces> # </configuration> # </rpc-reply> + # - 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 (redacted) -# ----------------------- -# "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" -# } -# ] + +# 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: @@ -653,17 +875,17 @@ EXAMPLES = """ - 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 (redacted) -# ----------------------- -# "rendered": "<nc:interfaces -# xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> + +# Task Output +# ----------- +# +# "rendered": "<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> @@ -697,8 +919,8 @@ EXAMPLES = """ # </nc:unit> # </nc:interface> # </nc:interfaces>" - """ + RETURN = """ before: description: The configuration as structured data prior to module invocation. @@ -736,6 +958,29 @@ commands: </nc:family> </nc:unit> </nc:interfaces>', '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: + - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +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. """ diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_lacp.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_lacp.py index b2636f285..686404018 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_lacp.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_lacp.py @@ -231,7 +231,6 @@ EXAMPLES = """ # "link_protection": "revertive", # "system_priority": 63 # } - """ RETURN = """ before: diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_lacp_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_lacp_interfaces.py index 0c05a0c54..5a2301367 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_lacp_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_lacp_interfaces.py @@ -163,16 +163,16 @@ EXAMPLES = """ - 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 + - 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: @@ -261,8 +261,8 @@ EXAMPLES = """ - name: Replace device LACP interfaces configuration with provided configuration junipernetworks.junos.junos_lacp_interfaces: config: - - name: ae0 - period: slow + - name: ae0 + period: slow state: replaced # After state: @@ -345,14 +345,14 @@ EXAMPLES = """ - 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 + - 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: @@ -447,9 +447,9 @@ EXAMPLES = """ - 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 + - name: ae0 + - name: ge-0/0/3 + - name: ge-0/0/2 state: deleted # After state: @@ -841,17 +841,17 @@ EXAMPLES = """ - 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: 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: ge-0/0/1 + port_priority: 100 + force_up: true state: rendered # Task Output (redacted) # ----------------------- @@ -880,7 +880,6 @@ EXAMPLES = """ # </nc:ether-options> # </nc:interface> # </nc:interfaces>" - """ RETURN = """ diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_lag_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_lag_interfaces.py index 81efca836..67c4ffb7e 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_lag_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_lag_interfaces.py @@ -143,8 +143,8 @@ EXAMPLES = """ - 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 + - name: ae0 + - name: ae1 state: deleted # After state: @@ -173,12 +173,12 @@ EXAMPLES = """ - 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 + - name: ae0 + members: + - member: ge-0/0/1 + link_type: primary + - member: ge-0/0/2 + link_type: backup state: merged # After state: @@ -231,13 +231,13 @@ EXAMPLES = """ - 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 + - name: ae0 + members: + - member: ge-0/0/2 + - name: ae1 + members: + - member: ge-0/0/1 + mode: passive state: overridden # After state: @@ -285,10 +285,10 @@ EXAMPLES = """ - name: Replace device LAG configuration with provided configuration junipernetworks.junos.junos_lag_interfaces: config: - - name: ae0 - members: - - member: ge-0/0/1 - mode: active + - name: ae0 + members: + - member: ge-0/0/1 + mode: active state: replaced # After state: @@ -701,20 +701,20 @@ EXAMPLES = """ - 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 + - 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": "<nc:interfaces @@ -771,7 +771,6 @@ EXAMPLES = """ # </nc:ether-options> # </nc:interface> # </nc:interfaces>" - """ RETURN = """ before: diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_lldp_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_lldp_interfaces.py index b3d1b61ed..dd5c7fe4c 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_lldp_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_lldp_interfaces.py @@ -89,9 +89,9 @@ EXAMPLES = """ - 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 + - name: ge-0/0/1 + - name: ge-0/0/2 + enabled: false state: merged # After state: @@ -118,10 +118,10 @@ EXAMPLES = """ - 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 + - name: ge-0/0/2 + disable: false + - name: ge-0/0/3 + enabled: false state: replaced # After state: @@ -149,8 +149,8 @@ EXAMPLES = """ - name: Override provided configuration with device configuration junipernetworks.junos.junos_lldp_interfaces: config: - - name: ge-0/0/2 - enabled: false + - name: ge-0/0/2 + enabled: false state: overridden # After state: @@ -176,8 +176,8 @@ EXAMPLES = """ - 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 + - name: ge-0/0/1 + - name: ge-0/0/3 state: deleted # After state: @@ -191,7 +191,7 @@ EXAMPLES = """ # Before state: # ------------ # -#ansible@cm123456tr21# show protocols lldp +# ansible@cm123456tr21# show protocols lldp # interface ge-0/0/1; # interface ge-0/0/2 { # disable; @@ -214,7 +214,7 @@ EXAMPLES = """ # After state: # ------------ # -#ansible@cm123456tr21# show protocols lldp +# ansible@cm123456tr21# show protocols lldp # interface ge-0/0/1; # interface ge-0/0/2 { # disable; diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_logging.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_logging.py index c2713a855..8f736d054 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_logging.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_logging.py @@ -175,19 +175,19 @@ EXAMPLES = """ junipernetworks.junos.junos_logging: dest: file aggregate: - - name: test-1 - facility: pfe - level: critical - - name: test-2 - facility: kernel - level: emergency + - name: test-1 + facility: pfe + level: critical + - name: test-2 + facility: kernel + level: emergency active: true - name: Delete file logging using aggregate junipernetworks.junos.junos_logging: aggregate: - - {dest: file, name: test-1, facility: pfe, level: critical} - - {dest: file, name: test-2, facility: kernel, level: emergency} + - {dest: file, name: test-1, facility: pfe, level: critical} + - {dest: file, name: test-2, facility: kernel, level: emergency} state: absent """ diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_ospf_interfaces.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_ospf_interfaces.py index fdfaf2640..c2cef436f 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_ospf_interfaces.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_ospf_interfaces.py @@ -102,11 +102,12 @@ options: md5: description: - Specify md5 based authentication. - type: dict + type: list + elements: dict suboptions: key_id: description: Specify md5 key-id - type: str + type: int key_value: description: Specify key value type: str @@ -189,7 +190,7 @@ options: node_link_protection: description: - Protect interface from both link and node faults. - type: str + type: bool dead_interval: description: - Dead interval (seconds). @@ -244,14 +245,14 @@ EXAMPLES = """ - 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 + - 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 @@ -279,16 +280,16 @@ EXAMPLES = """ # } - 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 + 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 # ----------- @@ -436,14 +437,14 @@ EXAMPLES = """ - 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 + - name: 'ge-0/0/2.0' + address_family: + - afi: 'ipv4' + processes: + area: + area_id: '0.0.0.2' + priority: 3 + metric: 5 state: rendered # diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_ospfv2.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_ospfv2.py index 9d951cf79..c8ac99c97 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_ospfv2.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_ospfv2.py @@ -36,10 +36,11 @@ DOCUMENTATION = """ module: junos_ospfv2 short_description: OSPFv2 resource module description: -- This module manages global OSPFv2 configuration on devices running Juniper JUNOS. +- 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) @@ -72,7 +73,31 @@ options: 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. @@ -99,7 +124,26 @@ options: 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 @@ -165,6 +209,15 @@ options: 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). @@ -203,11 +256,14 @@ options: 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. + 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 @@ -234,44 +290,588 @@ EXAMPLES = """ # # admin# show protocols ospf -- name: Merge Junos OSPFv2 config +- name: Merge provided OSPFv2 configuration into running config. junipernetworks.junos.junos_ospfv2: config: - - reference_bandwidth: 10g - areas: - - area_id: 0.0.0.100 - area_range: 10.200.16.0/24 - 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 + - 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: +# - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:ospf><nc:reference-bandwidth>10g</nc:reference-bandwidth><nc:no-rfc-1583/> +# <nc:area><nc:name>0.0.0.100</nc:name><nc:area-range><nc:name>10.200.17.0/24</nc:name><nc:exact/> +# <nc:restrict/><nc:override-metric>2000</nc:override-metric></nc:area-range><nc:area-range> +# <nc:name>10.200.15.0/24</nc:name><nc:exact/><nc:restrict/><nc:override-metric>2000</nc:override-metric> +# </nc:area-range><nc:interface><nc:name>so-0/0/0.0</nc:name><nc:priority>3</nc:priority> +# <nc:metric>5</nc:metric><nc:passive/><nc:bandwidth-based-metrics><nc:bandwidth><nc:name>1g</nc:name> +# <nc:metric>5</nc:metric></nc:bandwidth><nc:bandwidth><nc:name>10g</nc:name><nc:metric>40</nc:metric> +# </nc:bandwidth></nc:bandwidth-based-metrics><nc:dead-interval>4</nc:dead-interval> +# <nc:hello-interval>2</nc:hello-interval><nc:poll-interval>2</nc:poll-interval> +# <nc:retransmit-interval>2</nc:retransmit-interval></nc:interface><nc:stub> +# <nc:default-metric>100</nc:default-metric></nc:stub></nc:area></nc:ospf></nc:protocols> +# +# 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: +# - <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:ospf><nc:ospf> +# <nc:reference-bandwidth>10g</nc:reference-bandwidth><nc:no-rfc-1583/><nc:area> +# <nc:name>0.0.0.100</nc:name><nc:area-range><nc:name>10.200.17.0/24</nc:name><nc:exact/> +# <nc:restrict/></nc:area-range><nc:area-range><nc:name>10.200.16.0/24</nc:name><nc:exact/> +# <nc:restrict/><nc:override-metric>1000</nc:override-metric></nc:area-range><nc:interface> +# <nc:name>so-0/0/0.0</nc:name><nc:priority>3</nc:priority><nc:metric>5</nc:metric><nc:passive/> +# <nc:bandwidth-based-metrics><nc:bandwidth><nc:name>1g</nc:name><nc:metric>5</nc:metric> +# </nc:bandwidth><nc:bandwidth><nc:name>10g</nc:name><nc:metric>40</nc:metric></nc:bandwidth> +# </nc:bandwidth-based-metrics><nc:dead-interval>4</nc:dead-interval><nc:hello-interval>2</nc:hello-interval> +# <nc:poll-interval>2</nc:poll-interval><nc:retransmit-interval>2</nc:retransmit-interval></nc:interface> +# <nc:stub><nc:default-metric>100</nc:default-metric></nc:stub></nc:area></nc:ospf></nc:protocols> +# +# 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: +# - <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:ospf><nc:ospf> +# <nc:reference-bandwidth>10g</nc:reference-bandwidth><nc:area><nc:name>0.0.0.110</nc:name> +# <nc:area-range><nc:name>20.200.17.0/24</nc:name><nc:exact/><nc:restrict/> +# <nc:override-metric>2000</nc:override-metric></nc:area-range><nc:area-range> +# <nc:name>20.200.15.0/24</nc:name><nc:exact/><nc:restrict/><nc:override-metric>2000</nc:override-metric> +# </nc:area-range><nc:interface><nc:name>so-0/0/0.0</nc:name><nc:priority>3</nc:priority> +# <nc:metric>5</nc:metric><nc:passive/><nc:bandwidth-based-metrics><nc:bandwidth><nc:name>1g</nc:name> +# <nc:metric>5</nc:metric></nc:bandwidth><nc:bandwidth><nc:name>10g</nc:name><nc:metric>40</nc:metric> +# </nc:bandwidth></nc:bandwidth-based-metrics></nc:interface><nc:stub> +# <nc:default-metric>200</nc:default-metric></nc:stub></nc:area></nc:ospf></nc:protocols> +# +# 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: +# - <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> +# +# 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.16.0/24; +# 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 { @@ -287,17 +887,221 @@ EXAMPLES = """ # } # } +- 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 +# ------------ +# <?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"> +# <version>18.4R1-S2.4</version> +# <protocols> +# <ospf> +# <reference-bandwidth>10g</reference-bandwidth> +# <no-rfc-1583/> +# <area> +# <name>0.0.0.100</name> +# <stub> +# <default-metric>100</default-metric> +# </stub> +# <area-range> +# <name>10.200.16.0/24</name> +# <exact/> +# <override-metric>10000</override-metric> +# </area-range> +# <area-range> +# <name>10.200.11.0/24</name> +# <restrict/> +# <exact/> +# </area-range> +# <interface> +# <name>so-0/0/0.0</name> +# <passive> +# </passive> +# <bandwidth-based-metrics> +# <bandwidth> +# <name>1g</name> +# <metric>5</metric> +# </bandwidth> +# <bandwidth> +# <name>10g</name> +# <metric>40</metric> +# </bandwidth> +# </bandwidth-based-metrics> +# <metric>5</metric> +# <priority>3</priority> +# <retransmit-interval>2</retransmit-interval> +# <hello-interval>2</hello-interval> +# <dead-interval>4</dead-interval> +# <poll-interval>2</poll-interval> +# </interface> +# </area> +# </ospf> +# </protocols> +# <routing-options> +# <static> +# <route> +# <name>172.16.17.0/24</name> +# <discard /> +# </route> +# </static> +# <router-id>10.200.16.75</router-id> +# <autonomous-system> +# <as-number>65432</as-number> +# </autonomous-system> +# </routing-options> +# </configuration> +# </rpc-reply> + + +- 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: "<nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:ospf><nc:reference-bandwidth>10g</nc:reference-bandwidth><nc:no-rfc-1583/><nc:area><nc:name>0.0.0.100</nc:name> +# <nc:area-range><nc:name>10.200.17.0/24</nc:name><nc:exact/><nc:restrict/><nc:override-metric>2000</nc:override-metric> +# </nc:area-range><nc:area-range><nc:name>10.200.15.0/24</nc:name><nc:exact/><nc:restrict/> +# <nc:override-metric>2000</nc:override-metric></nc:area-range><nc:interface><nc:name>so-0/0/0.0</nc:name> +# <nc:priority>3</nc:priority><nc:metric>5</nc:metric><nc:passive/><nc:bandwidth-based-metrics><nc:bandwidth> +# <nc:name>1g</nc:name><nc:metric>5</nc:metric></nc:bandwidth><nc:bandwidth><nc:name>10g</nc:name> +# <nc:metric>40</nc:metric></nc:bandwidth></nc:bandwidth-based-metrics><nc:dead-interval>4</nc:dead-interval> +# <nc:hello-interval>2</nc:hello-interval><nc:poll-interval>2</nc:poll-interval> +# <nc:retransmit-interval>2</nc:retransmit-interval></nc:interface><nc:stub> +# <nc:default-metric>100</nc:default-metric></nc:stub></nc:area></nc:ospf></nc:protocols>" """ RETURN = """ before: - description: The configuration prior to the model invocation. + 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 model invocation. + description: The resulting configuration module invocation. returned: when changed type: dict sample: > @@ -307,7 +1111,29 @@ commands: description: The set of commands pushed to the remote device. returned: always type: list - sample: ['command 1', 'command 2', 'command 3'] + 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'] +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +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. """ diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_ospfv3.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_ospfv3.py index 0d49c625b..9a6a275dc 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_ospfv3.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_ospfv3.py @@ -205,7 +205,7 @@ options: 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. + 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 @@ -235,57 +235,148 @@ EXAMPLES = """ - name: Merge Junos OSPFv3 config junipernetworks.junos.junos_ospfv3: config: - - areas: - - area_id: 0.0.0.100 - stub: - default_metric: 200 - set: true - interfaces: - - name: so-0/0/0.0 - priority: 3 - metric: 5 + - 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: +# - <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><nc:name>so-0/0/0.0</nc:name> +# <nc:priority>3</nc:priority><nc:metric>5</nc:metric></nc:interface><nc:interface> +# <nc:name>so-0/0/1.0</nc:name><nc:priority>2</nc:priority><nc:metric>6</nc:metric> +# </nc:interface><nc:stub><nc:default-metric>200</nc:default-metric></nc:stub></nc:area></nc:ospf3></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:routing-options> +# +# 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 # ----------- # -# adimn# 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; +# } # } +# # Using replaced # # Before state # ------------ # -# adimn# show protocols ospf3 +# 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 Junos OSPFv3 config + +- name: Replace existing Junos OSPFv3 config with provided config junipernetworks.junos.junos_ospfv3: - config: - - areas: - - area_id: 0.0.0.100 - interfaces: - - name: so-0/0/0.0 - state: replaced + 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: +# - <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 delete="delete"> +# <nc:name>so-0/0/0.0</nc:name></nc:interface></nc:area></nc:ospf3><nc:ospf3> +# <nc:area><nc:name>0.0.0.100</nc:name><nc:interface><nc:name>so-0/0/0.0</nc:name> +# </nc:interface></nc:area></nc:ospf3></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> +# +# 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 @@ -293,27 +384,80 @@ EXAMPLES = """ # # 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 Junos OSPFv3 config + +- name: Override runnig OSPFv3 config with provided config junipernetworks.junos.junos_ospfv3: - config: - - 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 + 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: +# - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:ospf3 delete="delete"/><nc:ospf3><nc:area><nc:name>0.0.0.100</nc:name> +# <nc:interface><nc:name>so-0/0/0.0</nc:name><nc:priority>3</nc:priority><nc:flood-reduction/> +# <nc:metric>5</nc:metric><nc:passive/></nc:interface> +# <nc:stub><nc:default-metric>200</nc:default-metric></nc:stub></nc:area> +# <nc:area><nc:name>0.0.0.200</nc:name><nc:interface><nc:name>ge-1/1/0.0</nc:name> +# </nc:interface><nc:interface><nc:name>ge-2/2/0.0</nc:name></nc:interface></nc:area> +# </nc:ospf3></nc:protocols> +# - <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:router-id delete="delete"/><nc:router-id>10.200.16.75</nc:router-id></nc:routing-options> +# +# 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 # ----------- @@ -332,285 +476,213 @@ EXAMPLES = """ # interface ge-1/1/0.0; # interface ge-2/2/0.0; # } -# # Using deleted # # Before state # ------------ # -# adimn# show protocols ospf3 +# 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 Junos OSPFv3 config +- name: Delete OSPFv3 running config. junipernetworks.junos.junos_ospfv3: config: - - areas: - - area_id: 0.0.0.100 - interfaces: - - name: so-0/0/0.0 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: +# - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:ospf3 delete="delete"/></nc:protocols> +# - <nc:routing-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# <nc:router-id delete="delete"/></nc:routing-options> +# +# after: [] +# +# # After state # ----------- # # admin# show protocols ospf3 + # Using gathered # # Before state # ------------ # -# adimn# show protocols ospf3 +# 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; -# } +# interface so-0/0/1.0 { +# metric 6; +# priority 2; +# } -- name: Gather Junos OSPFv3 config +- name: Gather Junos OSPFv3 running-configuration junipernetworks.junos.junos_ospfv3: config: state: gathered # # -# ------------------------- -# Module Execution Result -# ------------------------- -# -# "gathered": { -# "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" -# } -# ] -# } -# ], -# } -# -# Using rendered -# +# Task Output: +# ------------ # -- name: Render the commands for provided configuration - junipernetworks.junos.junos_ospfv3: - config: - - 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 +# 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 -# -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# -# "rendered": " -# <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> -# <nc:name>so-0/0/0.0</nc:name> -# <nc:priority>3</nc:priority> -# <nc:flood-reduction/> -# <nc:metric>5</nc:metric> -# <nc:passive/> -# </nc:interface> -# <nc:stub> -# <nc:default-metric>200</nc:default-metric> -# </nc:stub> -# </nc:area> -# <nc:area> -# <nc:name>0.0.0.200</nc:name> -# <nc:interface> -# <nc:name>ge-1/1/0.0</nc:name> -# </nc:interface> -# <nc:interface> -# <nc:name>ge-2/2/0.0</nc:name> -# </nc:interface> -# </nc:area> -# </nc:ospf3> -# </nc:protocols>" -# # Using parsed # parsed.cfg # ------------ -# <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/18.4R1/junos"> -# <data> -# <configuration xmlns="http://xml.juniper.net/xnm/1.1/xnm" -# junos:commit-seconds="1601355317" junos:commit-localtime="2020-09-29 04:55:17 UTC" junos:commit-user="rohit"> -# <version>18.4R1-S2.4</version> -# <interfaces> -# <interface> -# <name>ge-0/0/0</name> -# <description>Configured by Ansi-Team</description> -# </interface> -# <interface> -# <name>gr-0/0/0</name> -# <description>Configured Manually</description> -# </interface> -# <interface> -# <name>fxp0</name> -# <unit> -# <name>0</name> -# <family> -# <inet> -# <dhcp> -# </dhcp> -# </inet> -# </family> -# </unit> -# </interface> -# </interfaces> -# <protocols> -# <ospf3> -# <area> -# <name>0.0.0.100</name> -# <stub> -# <default-metric>200</default-metric> -# </stub> -# <interface> -# <name>so-0/0/0.0</name> -# <passive> -# </passive> -# <metric>5</metric> -# <priority>3</priority> -# <flood-reduction/> -# </interface> -# </area> -# <area> -# <name>0.0.0.200</name> -# <interface> -# <name>ge-1/1/0.0</name> -# </interface> -# <interface> -# <name>ge-2/2/0.0</name> -# </interface> -# </area> -# </ospf3> -# </protocols> -# <routing-options> -# <router-id>10.200.16.75</router-id> -# </routing-options> -# </configuration> -# <database-status-information> -# <database-status> -# <user>rohit</user> -# <terminal>pts/0</terminal> -# <pid>38210</pid> -# <start-time junos:seconds="1601354977">2020-09-29 04:49:37 UTC</start-time> -# <idle-time junos:seconds="546">00:09:06</idle-time> -# <edit-path>[edit]</edit-path> -# </database-status> -# </database-status-information> -# </data> +# <?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"> +# <protocols> +# <ospf3> +# <area> +# <name>0.0.0.100</name> +# <stub> +# <default-metric>200</default-metric> +# </stub> +# <interface> +# <name>so-0/0/0.0</name> +# <passive></passive> +# <metric>5</metric> +# <priority>3</priority> +# <flood-reduction/> +# </interface> +# </area> +# <area> +# <name>0.0.0.200</name> +# <interface> +# <name>ge-1/1/0.0</name> +# </interface> +# <interface> +# <name>ge-2/2/0.0</name> +# </interface> +# </area> +# </ospf3> +# </protocols> +# <routing-options> +# <router-id>10.200.16.75</router-id> +# </routing-options> +# </configuration> # </rpc-reply> -- name: Parsed the device configuration to get output commands + +- 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 # -# ------------------------- -# Module Execution Result -# ------------------------- -# -# -# "parsed": [ -# { -# "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" -# } -# ] -# } -# ], -# } -# ] +- 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: "<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> +# <nc:name>so-0/0/0.0</nc:name><nc:priority>3</nc:priority> +# <nc:metric>5</nc:metric></nc:interface><nc:interface><nc:name>so-0/0/1.0</nc:name> +# <nc:priority>2</nc:priority><nc:metric>6</nc:metric></nc:interface><nc:stub> +# <nc:default-metric>200</nc:default-metric></nc:stub></nc:area></nc:ospf3></nc:protocols>" """ RETURN = """ before: - description: The configuration prior to the model invocation. + 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 model invocation. + description: The resulting configuration module invocation. returned: when changed type: dict sample: > @@ -620,40 +692,28 @@ commands: description: The set of commands pushed to the remote device. returned: always type: list - sample: ['<nc:protocols - xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> - <nc:ospf3 delete=\"delete\"/> - <nc:ospf3> - <nc:area> - <nc:name>0.0.0.100</nc:name> - <nc:interface> - <nc:name>so-0/0/0.0</nc:name> - <nc:priority>3</nc:priority> - <nc:flood-reduction/> - <nc:metric>5</nc:metric> - <nc:passive/> - </nc:interface> - <nc:stub> - <nc:default-metric>200</nc:default-metric> - </nc:stub> - </nc:area> - <nc:area> - <nc:name>0.0.0.200</nc:name> - <nc:interface> - <nc:name>ge-1/1/0.0</nc:name> - </nc:interface> - <nc:interface> - <nc:name>ge-2/2/0.0</nc:name> - </nc:interface> - </nc:area> - </nc:ospf3> -</nc:protocols>", - " -<nc:routing-options - xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> - <nc:router-id delete=\"delete\"/> - <nc:router-id>10.200.16.75</nc:router-id> -</nc:routing-options>', 'xml 2', 'xml 3'] + 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'] +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +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. """ diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_package.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_package.py index 0cffb4ddb..cfd9db297 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_package.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_package.py @@ -44,27 +44,33 @@ options: 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: yes + 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: no + 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: yes + 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: no + default: false force_host: description: - The I(force_host) argument controls the way software package or bundle is added @@ -93,6 +99,64 @@ options: 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) @@ -117,7 +181,7 @@ EXAMPLES = """ - name: install local package on remote device without rebooting junipernetworks.junos.junos_package: src: junos-vsrx-12.1X46-D10.2-domestic.tgz - reboot: no + reboot: false - name: install local package on remote device with jumpost junipernetworks.junos.junos_package: @@ -128,6 +192,7 @@ from ansible.module_utils.basic import AnsibleModule from ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos import ( get_device, + junos_argument_spec, ) @@ -143,6 +208,7 @@ 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"] @@ -155,6 +221,7 @@ def install_package(module, device): package, progress=progress_log, no_copy=no_copy, + unlink=unlink, validate=validate, force_host=force_host, issu=issu, @@ -175,6 +242,7 @@ def main(): 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), @@ -183,11 +251,16 @@ def main(): 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. " diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_ping.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_ping.py index 4c373474c..67fc9a1f1 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_ping.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_ping.py @@ -107,8 +107,8 @@ EXAMPLES = """ - 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 + df_bit: true + rapid: true """ RETURN = """ diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_prefix_lists.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_prefix_lists.py index 40b101f44..a6e0a32f3 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_prefix_lists.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_prefix_lists.py @@ -117,45 +117,35 @@ EXAMPLES = """ - 172.16.7.32 - 172.16.9.32 state: merged -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# "before": [] -# "commands": [ -# "<nc:policy-options xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> -# "<nc:prefix-list><nc:name>Internal</nc:name><nc:prefix-list-item><nc:name>172.16.1.32</nc:name>" -# "</nc:prefix-list-item><nc:prefix-list-item><nc:name>172.16.3.32</nc:name>" -# "</nc:prefix-list-item></nc:prefix-list><nc:prefix-list><nc:name>Test1</nc:name>" -# "<nc:dynamic-db/></nc:prefix-list><nc:prefix-list><nc:name>Test2</nc:name>" -# "<nc:prefix-list-item><nc:name>172.16.2.32</nc:name></nc:prefix-list-item>" -# "<nc:prefix-list-item><nc:name>172.16.7.32</nc:name></nc:prefix-list-item>" -# "<nc:prefix-list-item><nc:name>172.16.9.32</nc:name></nc:prefix-list-item>" -# "</nc:prefix-list></nc:policy-options>" -# ] -# -# "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" -# } -# ] + +# Task Output +# ------------- +# +# before: [] +# commands: +# - <nc:policy-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# - "<nc:prefix-list><nc:name>Internal</nc:name><nc:prefix-list-item><nc:name>172.16.1.32</nc:name>" +# - "</nc:prefix-list-item><nc:prefix-list-item><nc:name>172.16.3.32</nc:name>" +# - "</nc:prefix-list-item></nc:prefix-list><nc:prefix-list><nc:name>Test1</nc:name>" +# - "<nc:dynamic-db/></nc:prefix-list><nc:prefix-list><nc:name>Test2</nc:name>" +# - "<nc:prefix-list-item><nc:name>172.16.2.32</nc:name></nc:prefix-list-item>" +# - "<nc:prefix-list-item><nc:name>172.16.7.32</nc:name></nc:prefix-list-item>" +# - "<nc:prefix-list-item><nc:name>172.16.9.32</nc:name></nc:prefix-list-item>" +# - "</nc:prefix-list></nc:policy-options>" +# 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 # ----------- # @@ -172,7 +162,8 @@ EXAMPLES = """ # 172.16.7.32/32; # 172.16.9.32/32; # } -# + + # Using gathered # # Before state @@ -195,36 +186,28 @@ EXAMPLES = """ - name: Gather Junos prefix-lists junipernetworks.junos.junos_prefix_lists: state: gathered -# -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# "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" -# } -# ] -# + + +# 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 # ------------ # @@ -241,70 +224,54 @@ EXAMPLES = """ # 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 -# ------------------------- -# Module Execution Result -# ------------------------- -# -# "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": [ -# "<nc:policy-options xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> -# "<nc:prefix-list delete=\"delete\"><nc:name>Test2</nc:name></nc:prefix-list>" -# "<nc:prefix-list><nc:name>Test2</nc:name><nc:prefix-list-item><nc:name>172.16.4.32</nc:name>" -# "</nc:prefix-list-item><nc:prefix-list-item><nc:name>172.16.8.32</nc:name>" -# "</nc:prefix-list-item><nc:prefix-list-item><nc:name>172.16.9.32</nc:name>" -# "</nc:prefix-list-item></nc:prefix-list></nc:policy-options>" -# ] -# -# "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" -# } -# ] + 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: +# - <nc:policy-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# - <nc:prefix-list delete="delete"><nc:name>Test2</nc:name></nc:prefix-list> +# - "<nc:prefix-list><nc:name>Test2</nc:name><nc:prefix-list-item><nc:name>172.16.4.32</nc:name>" +# - "</nc:prefix-list-item><nc:prefix-list-item><nc:name>172.16.8.32</nc:name>" +# - "</nc:prefix-list-item><nc:prefix-list-item><nc:name>172.16.9.32</nc:name>" +# - "</nc:prefix-list-item></nc:prefix-list></nc:policy-options>" +# 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 # ----------- # @@ -321,8 +288,10 @@ EXAMPLES = """ # 172.16.8.32/32; # 172.16.9.32/32; # } + + # Using overridden -# + # Before state # ------------ # @@ -339,62 +308,50 @@ EXAMPLES = """ # 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 - -# ------------------------- -# Module Execution Result -# ------------------------- -# -# "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": [ -# "<nc:policy-options xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> -# "<nc:prefix-list delete=\"delete\"><nc:name>Internal</nc:name>" -# "</nc:prefix-list><nc:prefix-list delete=\"delete\"><nc:name>Test1</nc:name>" -# "</nc:prefix-list><nc:prefix-list delete=\"delete\"><nc:name>Test2</nc:name>" -# "</nc:prefix-list><nc:prefix-list><nc:name>Test2</nc:name><nc:prefix-list-item>" -# "<nc:name>172.16.4.32/28</nc:name></nc:prefix-list-item><nc:prefix-list-item>" -# "<nc:name>172.16.8.32/28</nc:name></nc:prefix-list-item><nc:prefix-list-item>" -# "<nc:name>172.16.9.32/28</nc:name></nc:prefix-list-item></nc:prefix-list></nc:policy-options>" -# ] -# -# "after": [ -# { -# "address_prefixes": [ -# "172.16.4.32/28", -# "172.16.8.32/28", -# "172.16.9.32/28" -# ], -# "name": "Test2" -# } -# ] + 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: +# - <nc:policy-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# - <nc:prefix-list delete="delete"><nc:name>Internal</nc:name> +# - </nc:prefix-list><nc:prefix-list delete="delete"><nc:name>Test1</nc:name> +# - </nc:prefix-list><nc:prefix-list delete="delete"><nc:name>Test2</nc:name> +# - "</nc:prefix-list><nc:prefix-list><nc:name>Test2</nc:name><nc:prefix-list-item>" +# - "<nc:name>172.16.4.32/28</nc:name></nc:prefix-list-item><nc:prefix-list-item>" +# - "<nc:name>172.16.8.32/28</nc:name></nc:prefix-list-item><nc:prefix-list-item>" +# - "<nc:name>172.16.9.32/28</nc:name></nc:prefix-list-item></nc:prefix-list></nc:policy-options>" +# after: +# - address_prefixes: +# - 172.16.4.32/28 +# - 172.16.8.32/28 +# - 172.16.9.32/28 +# name: Test2 + # After state # ----------- # @@ -404,8 +361,11 @@ EXAMPLES = """ # 172.16.8.32/28; # 172.16.9.32/28; # } + + # Using deleted -# + + # Before state # ------------ # @@ -423,52 +383,41 @@ EXAMPLES = """ # 172.16.9.32/32; # } + - name: Delete provided prefix-lists junipernetworks.junos.junos_prefix_lists: - config: - - name: "Test1" - - name: "Test2" - state: deleted -# ------------------------ -# Module Execution Results -# ------------------------ -# -# "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": [ -# "<nc:policy-options xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> -# "<nc:prefix-list delete=\"delete\"><nc:name>Test1</nc:name></nc:prefix-list>" -# "<nc:prefix-list delete=\"delete\"><nc:name>Test2</nc:name></nc:prefix-list></nc:policy-options>" -# ] -# -# "after": [ -# { -# "address_prefixes": [ -# "172.16.1.32/32", -# "172.16.3.32/32" -# ], -# "name": "Internal" -# } -# ] + 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: +# - <nc:policy-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# - <nc:prefix-list delete="delete"><nc:name>Test1</nc:name></nc:prefix-list> +# - <nc:prefix-list delete="delete"><nc:name>Test2</nc:name></nc:prefix-list></nc:policy-options> +# after: +# - address_prefixes: +# - 172.16.1.32/32 +# - 172.16.3.32/32 +# name: Internal + + # After state # ----------- # @@ -478,8 +427,11 @@ EXAMPLES = """ # 172.16.3.32/32; # } # + + # Using deleted without specifying config -# + + # Before state # ------------ # @@ -497,40 +449,33 @@ EXAMPLES = """ # 172.16.9.32/32; # } + - name: Delete complete Junos prefix-lists configuration junipernetworks.junos.junos_prefix_lists: - state: deleted + 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: +# - <nc:policy-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# - <nc:prefix-list delete="delete"/></nc:policy-options> +# after: [] + -# ------------------------ -# Module Execution Results -# ------------------------ -# -# "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": ["<nc:policy-options xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> -# "<nc:prefix-list delete=\"delete\"/></nc:policy-options>" -# ] -# -# "after": [] # After state # ----------- # @@ -538,8 +483,10 @@ EXAMPLES = """ # # [edit] -# + # Using parsed + + # parsed.cfg # ------------ # <?xml version="1.0" encoding="UTF-8"?> @@ -563,34 +510,28 @@ EXAMPLES = """ # </policy-options> # </configuration> # </rpc-reply> + + - name: Parse running prefix-lists configuration junipernetworks.junos.junos_prefix_lists: running_config: "{{ lookup('file', './parsed.cfg') }}" state: parsed -# -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# -# "parsed": [ -# { -# "name": "64510" -# }, -# { -# "address_prefixes": [ -# "172.16.1.16/28", -# "172.16.1.32/28" -# ], -# "dynamic_db": true, -# "name": "64500" -# } -# ] -# -# + + +# 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: @@ -606,43 +547,78 @@ EXAMPLES = """ - 172.16.7.32 - 172.16.9.32 state: rendered -# -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# -# "rendered": "<nc:policy-options xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> -# "<nc:prefix-list><nc:name>Internal</nc:name><nc:prefix-list-item><nc:name>172.16.1.32</nc:name>" -# "</nc:prefix-list-item><nc:prefix-list-item><nc:name>172.16.3.32</nc:name></nc:prefix-list-item>" -# "</nc:prefix-list><nc:prefix-list><nc:name>Test1</nc:name><nc:dynamic-db/></nc:prefix-list>" -# "<nc:prefix-list><nc:name>Test2</nc:name><nc:prefix-list-item><nc:name>172.16.2.32</nc:name>" -# "</nc:prefix-list-item><nc:prefix-list-item><nc:name>172.16.7.32</nc:name></nc:prefix-list-item>" -# "<nc:prefix-list-item><nc:name>172.16.9.32</nc:name></nc:prefix-list-item>" -# "</nc:prefix-list></nc:policy-options>" + + +# Task Output +# ------------- +# rendered: +# - <nc:policy-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +# - "<nc:prefix-list><nc:name>Internal</nc:name><nc:prefix-list-item><nc:name>172.16.1.32</nc:name>" +# - "</nc:prefix-list-item><nc:prefix-list-item><nc:name>172.16.3.32</nc:name>" +# - "</nc:prefix-list-item></nc:prefix-list><nc:prefix-list><nc:name>Test1</nc:name>" +# - "<nc:dynamic-db/></nc:prefix-list><nc:prefix-list><nc:name>Test2</nc:name>" +# - "<nc:prefix-list-item><nc:name>172.16.2.32</nc:name></nc:prefix-list-item>" +# - "<nc:prefix-list-item><nc:name>172.16.7.32</nc:name></nc:prefix-list-item>" +# - "<nc:prefix-list-item><nc:name>172.16.9.32</nc:name></nc:prefix-list-item>" +# - "</nc:prefix-list></nc:policy-options>" """ -RETURN = """ +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. - type: list 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. - type: list commands: description: The set of commands pushed to the remote device. returned: always type: list - sample: ['<nc:policy-options xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"> - "<nc:prefix-list delete=\"delete\"/></nc:policy-options>"', 'xml 2', 'command 3'] + sample: + - <nc:policy-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> + - "<nc:prefix-list><nc:name>Internal</nc:name><nc:prefix-list-item><nc:name>172.16.1.32</nc:name>" + - "</nc:prefix-list-item><nc:prefix-list-item><nc:name>172.16.3.32</nc:name>" + - "</nc:prefix-list-item></nc:prefix-list><nc:prefix-list><nc:name>Test1</nc:name>" + - "<nc:dynamic-db/></nc:prefix-list><nc:prefix-list><nc:name>Test2</nc:name>" + - "<nc:prefix-list-item><nc:name>172.16.2.32</nc:name></nc:prefix-list-item>" + - "<nc:prefix-list-item><nc:name>172.16.7.32</nc:name></nc:prefix-list-item>" + - "<nc:prefix-list-item><nc:name>172.16.9.32</nc:name></nc:prefix-list-item>" + - "</nc:prefix-list></nc:policy-options>" +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - <nc:policy-options xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> + - "<nc:prefix-list><nc:name>Internal</nc:name><nc:prefix-list-item><nc:name>172.16.1.32</nc:name>" + - "</nc:prefix-list-item><nc:prefix-list-item><nc:name>172.16.3.32</nc:name>" + - "</nc:prefix-list-item></nc:prefix-list><nc:prefix-list><nc:name>Test1</nc:name>" + - "<nc:dynamic-db/></nc:prefix-list><nc:prefix-list><nc:name>Test2</nc:name>" + - "<nc:prefix-list-item><nc:name>172.16.2.32</nc:name></nc:prefix-list-item>" + - "<nc:prefix-list-item><nc:name>172.16.7.32</nc:name></nc:prefix-list-item>" + - "<nc:prefix-list-item><nc:name>172.16.9.32</nc:name></nc:prefix-list-item>" + - "</nc:prefix-list></nc:policy-options>" +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. """ diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_routing_instances.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_routing_instances.py index 1b7c1c995..eec4720b8 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_routing_instances.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_routing_instances.py @@ -312,21 +312,21 @@ EXAMPLES = """ - 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 + 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 # ----------- @@ -368,25 +368,25 @@ EXAMPLES = """ - 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 + 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 # ----------- @@ -432,9 +432,9 @@ EXAMPLES = """ - name: Delete provided junos routing-instamce junipernetworks.junos.junos_routing_instances: - config: - - name: "test" - state: deleted + config: + - name: "test" + state: deleted # After state # ----------- @@ -470,8 +470,8 @@ EXAMPLES = """ - name: Delete complete Junos routing-instances config junipernetworks.junos.junos_routing_instances: - config: - state: deleted + config: + state: deleted # After state # ----------- diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_scp.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_scp.py index 34657ae8d..605450053 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_scp.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_scp.py @@ -19,6 +19,10 @@ description: 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: @@ -56,6 +60,64 @@ options: 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) @@ -104,6 +166,7 @@ from ansible.module_utils.basic import AnsibleModule from ansible_collections.junipernetworks.junos.plugins.module_utils.network.junos.junos import ( get_device, + junos_argument_spec, ) @@ -138,11 +201,15 @@ def main(): 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. " diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_security_policies.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_security_policies.py index bf8c4f6ee..8d8f50f02 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_security_policies.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_security_policies.py @@ -2545,18 +2545,18 @@ EXAMPLES = """ - 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 + 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 # # ------------------------- @@ -2581,8 +2581,6 @@ EXAMPLES = """ # </nc:global> # </nc:policies> # </nc:security>" - - """ RETURN = """ before: diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_security_zones.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_security_zones.py index 36032cbca..384e92a21 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_security_zones.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_security_zones.py @@ -291,7 +291,8 @@ options: connection to remote host is not required. type: str """ -EXAMPLES = """# Using merged +EXAMPLES = """ +# Using merged # # Before state # ------------ @@ -308,72 +309,72 @@ EXAMPLES = """# Using merged description: test description host_inbound_traffic: protocols: - - name: all - - name: bgp - except: true + - name: all + - name: bgp + except: true system_services: - - name: all - - except: true - name: dhcp + - 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 + - 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: - - 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 + - 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 # # ------------------------- @@ -732,16 +733,16 @@ EXAMPLES = """# Using merged description: test description host_inbound_traffic: protocols: - - name: all - - name: bgp - except: true + - 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 + - name: all + - except: true + name: dhcp + interfaces: + - ge-0/0/1.0 + - ge-0/0/2.0 screen: test_screen state: replaced # @@ -1047,13 +1048,13 @@ EXAMPLES = """# Using merged description: test description host_inbound_traffic: protocols: - - name: all - - name: bgp - except: true + - name: all + - name: bgp + except: true system_services: - - name: all - - except: true - name: dhcp + - name: all + - except: true + name: dhcp interfaces: - ge-0/0/1.0 - ge-0/0/2.0 @@ -1580,72 +1581,72 @@ EXAMPLES = """# Using merged description: test description host_inbound_traffic: protocols: - - name: all - - name: bgp - except: true + - name: all + - name: bgp + except: true system_services: - - name: all - - except: true - name: dhcp + - 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 + - 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: - - 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 + - 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 # # ------------------------- diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_snmp_server.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_snmp_server.py index 491298327..0e2b286ec 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_snmp_server.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_snmp_server.py @@ -887,15 +887,15 @@ EXAMPLES = """ 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" + - 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: @@ -1022,16 +1022,16 @@ EXAMPLES = """ config: contact: "ansiblesupport11@redhat.com" customization: - ether_stats_ifd_only: True + 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 + use_default_ip_address: true + use_mac_address: true + filter_duplicates: true filter_interfaces: - set: True - all_internal_interfaces: True + set: true + all_internal_interfaces: true interfaces: - "eth1" - "eth2" @@ -1172,20 +1172,20 @@ EXAMPLES = """ config: contact: "ansiblesupport11@redhat.com" customization: - ether_stats_ifd_only: True + 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 + use_default_ip_address: true + use_mac_address: true + filter_duplicates: true filter_interfaces: - set: True - all_internal_interfaces: True + set: true + all_internal_interfaces: true interfaces: - "eth1" - "eth2" - state: overridden + state: overridden # # ------------------------- # Module Execution Result diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_static_routes.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_static_routes.py index 7efe112a7..f89c66783 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_static_routes.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_static_routes.py @@ -127,27 +127,50 @@ EXAMPLES = """ # 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; -# route 10.200.16.75/24 next-hop 10.200.16.2; # } - name: Delete provided configuration (default operation is merge) junipernetworks.junos.junos_static_routes: config: - - address_families: - - afi: ipv4 - routes: - - dest: 10.200.16.75/24 - next_hop: - - forward_router_address: 10.200.16.2 + - 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: +# - '<nc:routing-options +# xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:static><nc:route +# delete="delete"><nc:name>192.168.16.0/24</nc:name></nc:route></nc:static></nc:routing-options>' +# - '<nc:routing-instances xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"/>' +# 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; -# route 192.168.16.0/24 next-hop 172.16.1.2; # } # Using merged @@ -158,21 +181,44 @@ EXAMPLES = """ # 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: Merge provided configuration with device configuration (default operation is merge) junipernetworks.junos.junos_static_routes: config: - - address_families: - - afi: ipv4 - routes: - - dest: 10.200.16.75/24 - next_hop: - - forward_router_address: 10.200.16.2 + - 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: +# - '<nc:routing-options +# xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:static><nc:route><nc:name>192.168.16.0/24</nc:name> +# <nc:next-hop>172.16.1.2</nc:next-hop></nc:route></nc:static></nc:routing-options>' +# - '<nc:routing-instances xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"/>' +# 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: # ------------ # @@ -180,7 +226,6 @@ EXAMPLES = """ # 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; -# route 10.200.16.75/24 next-hop 10.200.16.2; # } # Using overridden @@ -191,27 +236,53 @@ EXAMPLES = """ # 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.0.1; +# route 192.168.16.0/24 next-hop 172.16.1.2; # } -- name: Override provided configuration with device configuration (default operation +- name: Override running configuration with provided configuration (default operation is merge) junipernetworks.junos.junos_static_routes: config: - - address_families: - - afi: ipv4 - routes: - - dest: 10.200.16.75/24 - next_hop: - - forward_router_address: 10.200.16.2 + - 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: +# - >- +# <nc:routing-options +# xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:static><nc:route +# delete="delete"><nc:name>192.168.47.0/24</nc:name></nc:route><nc:route +# delete="delete"><nc:name>192.168.16.0/24</nc:name></nc:route></nc:static><nc:static><nc:route><nc:name>192.168.16.0/24</nc:name><nc:next-hop>172.16.0.1</nc:next-hop></nc:route></nc:static></nc:routing-options> +# - '<nc:routing-instances xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"/>' +# 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 10.200.16.75/24 next-hop 10.200.16.2; +# route 192.168.16.0/24 next-hop 172.16.0.1; # } # Using replaced @@ -229,14 +300,43 @@ EXAMPLES = """ 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 + - 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: +# - >- +# <nc:routing-options +# xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:static><nc:route +# delete="delete"><nc:name>192.168.47.0/24</nc:name></nc:route></nc:static><nc:static><nc:route><nc:name>192.168.47.0/24</nc:name><nc:next-hop>10.200.16.2</nc:next-hop></nc:route></nc:static></nc:routing-options> +# - '<nc:routing-instances xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"/>' +# 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: # ------------ # @@ -246,7 +346,92 @@ EXAMPLES = """ # 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: +# - '<nc:routing-options +# xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><nc:static><nc:route><nc:name>192.168.16.0/24</nc:name> +# <nc:next-hop>172.16.1.2</nc:next-hop></nc:route></nc:static></nc:routing-options>' + +# Using parsed + +# parsed.cfg +# ------------ +# <?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"> +# <version>18.4R1-S2.4</version> +# <routing-options> +# <static> +# <route> +# <name>192.168.16.0/24</name> +# <next-hop>172.16.1.2</next-hop> +# <next-hop>172.16.1.3</next-hop> +# </route> +# <route> +# <name>192.168.47.0/24</name> +# <next-hop>10.200.16.2</next-hop> +# </route> +# </static> +# </routing-options> +# </configuration> +# </rpc-reply> + +- 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: @@ -268,6 +453,26 @@ commands: 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: + - <nc:protocols xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> +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. """ diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_system.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_system.py index c70ded66f..011a842f5 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_system.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_system.py @@ -76,9 +76,9 @@ EXAMPLES = """ hostname: junos01 domain_name: test.example.com domain-search: - - ansible.com - - redhat.com - - juniper.net + - ansible.com + - redhat.com + - juniper.net - name: remove configuration junipernetworks.junos.junos_system: @@ -87,8 +87,8 @@ EXAMPLES = """ - name: configure name servers junipernetworks.junos.junos_system: name_servers: - - 8.8.8.8 - - 8.8.4.4 + - 8.8.8.8 + - 8.8.4.4 """ RETURN = """ diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_user.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_user.py index 0e9ee8ad9..018dd88f8 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_user.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_user.py @@ -124,7 +124,7 @@ options: absolute. It will remove any previously configured users on the device with the exception of the current defined set of aggregate. type: bool - default: no + default: false state: description: - The C(state) argument configures the state of the user definitions as it relates @@ -140,7 +140,7 @@ options: description: - Specifies whether or not the configuration is active or deactivated type: bool - default: yes + default: true requirements: - ncclient (>=v0.5.2) notes: @@ -167,8 +167,8 @@ EXAMPLES = """ - name: remove all user accounts except ansible junipernetworks.junos.junos_user: aggregate: - - name: ansible - purge: yes + - name: ansible + purge: true - name: set user password junipernetworks.junos.junos_user: @@ -180,16 +180,15 @@ EXAMPLES = """ - 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: 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} + - {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. diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_vlans.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_vlans.py index 32f974df6..e1c834d89 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_vlans.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_vlans.py @@ -107,11 +107,11 @@ EXAMPLES = """ - 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 + - name: vlan1 + vlan_id: 1 + - name: vlan2 + vlan_id: 2 + l3_interface: irb.12 state: merged # # ------------------------- @@ -165,12 +165,12 @@ EXAMPLES = """ - 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: vlan1 + vlan_id: 11 + l3_interface: irb.10 - - name: vlan2 - vlan_id: 2 + - name: vlan2 + vlan_id: 2 state: replaced # ------------------------- # Module Execution Result @@ -234,9 +234,9 @@ EXAMPLES = """ - name: Override Junos running-config with provided config junipernetworks.junos.junos_vlans: config: - - name: vlan3 - vlan_id: 3 - l3_interface: irb.13 + - name: vlan3 + vlan_id: 3 + l3_interface: irb.13 state: overridden # ------------------------- # Module Execution Result @@ -288,7 +288,7 @@ EXAMPLES = """ - name: Delete specific vlan junipernetworks.junos.junos_vlans: config: - - name: vlan3 + - name: vlan3 state: deleted # ------------------------- # Module Execution Result @@ -340,12 +340,12 @@ EXAMPLES = """ - name: Render xml for provided facts. junipernetworks.junos.junos_vlans: config: - - name: vlan1 - vlan_id: 1 + - name: vlan1 + vlan_id: 1 - - name: vlan2 - vlan_id: 2 - l3_interface: irb.12 + - name: vlan2 + vlan_id: 2 + l3_interface: irb.12 state: rendered # # ------------------------- diff --git a/ansible_collections/junipernetworks/junos/plugins/modules/junos_vrf.py b/ansible_collections/junipernetworks/junos/plugins/modules/junos_vrf.py index e2332d1c5..3da30d81c 100644 --- a/ansible_collections/junipernetworks/junos/plugins/modules/junos_vrf.py +++ b/ansible_collections/junipernetworks/junos/plugins/modules/junos_vrf.py @@ -151,8 +151,8 @@ EXAMPLES = """ name: test-1 description: test-vrf-1 interfaces: - - ge-0/0/3 - - ge-0/0/2 + - ge-0/0/3 + - ge-0/0/2 rd: 192.0.2.1:10 target: target:65514:113 state: present @@ -162,8 +162,8 @@ EXAMPLES = """ name: test-1 description: test-vrf-1 interfaces: - - ge-0/0/3 - - ge-0/0/2 + - ge-0/0/3 + - ge-0/0/2 rd: 192.0.2.1:10 target: target:65514:113 state: absent @@ -173,8 +173,8 @@ EXAMPLES = """ name: test-1 description: test-vrf-1 interfaces: - - ge-0/0/3 - - ge-0/0/2 + - ge-0/0/3 + - ge-0/0/2 rd: 192.0.2.1:10 target: target:65514:113 active: false @@ -184,8 +184,8 @@ EXAMPLES = """ name: test-1 description: test-vrf-1 interfaces: - - ge-0/0/3 - - ge-0/0/2 + - ge-0/0/3 + - ge-0/0/2 rd: 192.0.2.1:10 target: target:65514:113 active: true @@ -193,19 +193,19 @@ EXAMPLES = """ - 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 + - 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 """ diff --git a/ansible_collections/junipernetworks/junos/plugins/terminal/junos.py b/ansible_collections/junipernetworks/junos/plugins/terminal/junos.py index 574e80cc2..2a364f1b7 100644 --- a/ansible_collections/junipernetworks/junos/plugins/terminal/junos.py +++ b/ansible_collections/junipernetworks/junos/plugins/terminal/junos.py @@ -34,7 +34,6 @@ display = Display() class TerminalModule(TerminalBase): - terminal_stdout_re = [ re.compile( to_bytes(r"({primary:node\d+})?[\r\n]?[\w@+\-\.:\/\[\]]+[>#%] ?$"), |