From 99f84ffef0c59b655a785877403d25cbe0ee07f3 Mon Sep 17 00:00:00 2001 From: Brij Tarkhala Date: Fri, 25 Apr 2025 14:53:08 +0530 Subject: [PATCH 1/4] Add functional tests for junipernetworks.junos modules --- tests/junipernetworks.junos/ansible.cfg | 8 ++ tests/junipernetworks.junos/inventory | 9 ++ .../pb.juniper_junos_acl_interfaces.yml | 126 ++++++++++++++++++ .../pb.juniper_junos_acls.yml | 64 +++++++++ .../pb.juniper_junos_banner.yml | 76 +++++++++++ .../pb.juniper_junos_command.yml | 68 ++++++++++ .../pb.juniper_junos_config.yml | 67 ++++++++++ .../pb.juniper_junos_facts.yml | 44 ++++++ .../pb.juniper_junos_hostname.yml | 57 ++++++++ .../pb.juniper_junos_interfaces.yml | 64 +++++++++ .../pb.juniper_junos_l2_interfaces.yml | 84 ++++++++++++ .../pb.juniper_junos_l3_interfaces.yml | 73 ++++++++++ .../pb.juniper_junos_lacp.yml | 56 ++++++++ .../pb.juniper_junos_lacp_interfaces.yml | 82 ++++++++++++ .../pb.juniper_junos_lldp_global.yml | 54 ++++++++ .../pb.juniper_junos_lldp_interfaces.yml | 63 +++++++++ .../pb.juniper_junos_netconf.yml | 29 ++++ .../pb.juniper_junos_user.yml | 46 +++++++ 18 files changed, 1070 insertions(+) create mode 100644 tests/junipernetworks.junos/ansible.cfg create mode 100644 tests/junipernetworks.junos/inventory create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_acl_interfaces.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_acls.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_banner.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_command.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_config.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_facts.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_hostname.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_interfaces.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_l2_interfaces.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_l3_interfaces.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_lacp.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_lacp_interfaces.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_lldp_global.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_lldp_interfaces.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_netconf.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_user.yml diff --git a/tests/junipernetworks.junos/ansible.cfg b/tests/junipernetworks.junos/ansible.cfg new file mode 100644 index 00000000..95986e7d --- /dev/null +++ b/tests/junipernetworks.junos/ansible.cfg @@ -0,0 +1,8 @@ +[defaults] +hash_behaviour=merge +inventory = inventory +host_key_checking = False +log_path = ./ansible.log + +[persistent_connection] +command_timeout = 300 diff --git a/tests/junipernetworks.junos/inventory b/tests/junipernetworks.junos/inventory new file mode 100644 index 00000000..a952be66 --- /dev/null +++ b/tests/junipernetworks.junos/inventory @@ -0,0 +1,9 @@ +[junos] +netconf_connection_testcases ansible_host=x.x.x.x + +[all:vars] +ansible_python_interpreter= +ansible_connection=netconf +ansible_network_os=junipernetworks.junos.junos +ansible_user=xxxx +ansible_password=xxxx \ No newline at end of file diff --git a/tests/junipernetworks.junos/pb.juniper_junos_acl_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_acl_interfaces.yml new file mode 100644 index 00000000..cd2dd6a4 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_acl_interfaces.yml @@ -0,0 +1,126 @@ + +- name: Functional Test - junos_acl_interfaces module + hosts: junos + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + vars: + interface_name: "ge-1/0/0" + inbound_acl_name: "inbound_acl" + outbound_acl_name: "outbound_acl" + + tasks: + + - name: Setup - Ensure initial ACL config is absent (clean slate) + junos_acl_interfaces: + config: + - name: "{{ interface_name }}" + access_groups: + - afi: ipv4 + acls: + - name: "{{ inbound_acl_name }}" + direction: in + - name: "{{ outbound_acl_name }}" + direction: out + state: deleted + register: cleanup_result + + - name: Assert cleanup before test + assert: + that: + - cleanup_result.changed in [true, false] + + - name: Pre-config - Create inbound and outbound ACL filters + junipernetworks.junos.junos_config: + lines: + - set firewall family inet filter {{ inbound_acl_name }} term 1 from source-address 10.0.0.0/8 + - set firewall family inet filter {{ inbound_acl_name }} term 1 then accept + - set firewall family inet filter {{ outbound_acl_name }} term 1 from destination-address 192.168.0.0/16 + - set firewall family inet filter {{ outbound_acl_name }} term 1 then accept + comment: "Test ACL filters for junos_acl_interfaces FT" + + + - name: Test - Merge ACL config into interface + junos_acl_interfaces: + config: + - name: "{{ interface_name }}" + access_groups: + - afi: ipv4 + acls: + - name: "{{ inbound_acl_name }}" + direction: in + - name: "{{ outbound_acl_name }}" + direction: out + state: merged + register: merge_result + + - name: Assert merge operation + assert: + that: + - merge_result.changed == true + - merge_result.after is defined + - merge_result.commands | length > 0 + + + - name: Test - Replace ACL config with only input filter + junos_acl_interfaces: + config: + - name: "{{ interface_name }}" + access_groups: + - afi: ipv4 + acls: + - name: "{{ inbound_acl_name }}" + direction: in + state: overridden + register: replace_result + + - name: Assert override operation + assert: + that: + - replace_result.changed == true + - outbound_acl_name not in (replace_result.after | to_json) + + + - name: Test - Override ACL config with both directions + junos_acl_interfaces: + config: + - name: "{{ interface_name }}" + access_groups: + - afi: ipv4 + acls: + - name: "{{ inbound_acl_name }}" + direction: in + - name: "{{ outbound_acl_name }}" + direction: out + state: overridden + register: override_result + + - name: Assert override operation + assert: + that: + - override_result.changed == true + + + - name: Test - Delete ACL config + junos_acl_interfaces: + config: + - name: "{{ interface_name }}" + access_groups: + - afi: ipv4 + acls: + - name: "{{ inbound_acl_name }}" + direction: in + - name: "{{ outbound_acl_name }}" + direction: out + state: deleted + register: delete_result + + - name: Assert delete operation + assert: + that: + - delete_result.changed == true + - delete_result.after is defined + + diff --git a/tests/junipernetworks.junos/pb.juniper_junos_acls.yml b/tests/junipernetworks.junos/pb.juniper_junos_acls.yml new file mode 100644 index 00000000..06f95576 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_acls.yml @@ -0,0 +1,64 @@ +- name: Functional Test - junos_acls module + hosts: junos + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + vars: + acl_name: "allow_ssh_acl" + term_name: "ssh_rule" + + tasks: + + - name: Pre-clean - Delete test ACL if it exists + junos_acls: + config: + - afi: ipv4 + acls: + - name: "{{ acl_name }}" + state: deleted + register: pre_cleanup + + - name: Assert pre-clean success + assert: + that: + - pre_cleanup.changed in [true, false] + + + - name: Apply ACL with state merged + junos_acls: + config: + - afi: ipv4 + acls: + - name: "{{ acl_name }}" + aces: + - name: "{{ term_name }}" + source: + port_protocol: + eq: ssh + protocol: tcp + state: merged + register: merge_result + + - name: Assert merged config applied + assert: + that: + - merge_result.changed == true + - merge_result.after is defined + - merge_result.commands | length > 0 + + + - name: Post-clean - Remove ACL + junos_acls: + config: + - afi: ipv4 + acls: + - name: "{{ acl_name }}" + state: deleted + register: post_cleanup + + - name: Assert ACL was cleaned up + assert: + that: + - post_cleanup.changed == true diff --git a/tests/junipernetworks.junos/pb.juniper_junos_banner.yml b/tests/junipernetworks.junos/pb.juniper_junos_banner.yml new file mode 100644 index 00000000..ab8085bd --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_banner.yml @@ -0,0 +1,76 @@ +- name: Functional Test - junos_banner module + hosts: junos + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + vars: + login_banner_text: | + this is my login banner + used for testing purposes + + tasks: + - name: Pre-clean - Remove login banner if exists + junos_banner: + banner: login + state: absent + register: preclean_result + + - name: Assert pre-clean successful + assert: + that: + - preclean_result.changed in [true, false] + + - name: Apply login banner with state present + junos_banner: + banner: login + text: "{{ login_banner_text }}" + state: present + register: present_result + + - name: Assert login banner applied + assert: + that: + - present_result.changed == true + + - name: Deactivate the login banner + junipernetworks.junos.junos_banner: + banner: login + text: | + this is my login banner + used for testing purposes + state: present + active: false + register: deactivate_result + + - name: Assert login banner deactivated + assert: + that: + - deactivate_result.changed == true + + - name: Reactivate the login banner + junos_banner: + banner: login + state: present + active: true + text: | + this is my login banner + used for testing purpose + register: reactivate_result + + - name: Assert login banner reactivated + assert: + that: + - reactivate_result.changed == true + + - name: Post-clean - Remove login banner + junos_banner: + banner: login + state: absent + register: postclean_result + + - name: Assert login banner removed + assert: + that: + - postclean_result.changed == true diff --git a/tests/junipernetworks.junos/pb.juniper_junos_command.yml b/tests/junipernetworks.junos/pb.juniper_junos_command.yml new file mode 100644 index 00000000..e384dfd5 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_command.yml @@ -0,0 +1,68 @@ + + +- name: Functional Test - junos_command module + hosts: junos + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + - name: Run show version + junipernetworks.junos.junos_command: + commands: show version + register: version_output + + - name: Assert show version output is returned + assert: + that: + - version_output.stdout is defined + - "'Junos' in version_output.stdout[0]" + + - name: Run show version with wait_for condition (positive match) + junipernetworks.junos.junos_command: + commands: show version + wait_for: + - result[0] contains Hostname + register: show_version_wait_positive + + - name: Assert wait_for with positive match passed + assert: + that: + - show_version_wait_positive.stdout is defined + - show_version_wait_positive.failed_conditions is not defined + + - name: Run multiple commands + junipernetworks.junos.junos_command: + commands: + - show version + - show interfaces terse + register: multi_output + + - name: Assert multiple commands worked + assert: + that: + - multi_output.stdout | length == 2 + - "'Interface' in multi_output.stdout[1]" + + - name: Run show version with json output + junipernetworks.junos.junos_command: + commands: show version + display: json + register: json_output + + - name: Assert json output is returned + assert: + that: + - json_output.stdout is defined + + - name: Run RPC get-software-information + junipernetworks.junos.junos_command: + rpcs: get-software-information + register: rpc_output + + - name: Assert RPC output + assert: + that: + - rpc_output.stdout is defined + - rpc_output.stdout[0] is string diff --git a/tests/junipernetworks.junos/pb.juniper_junos_config.yml b/tests/junipernetworks.junos/pb.juniper_junos_config.yml new file mode 100644 index 00000000..b8a8dc6a --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_config.yml @@ -0,0 +1,67 @@ +- name: Functional Test - junos_config module + hosts: junos + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + + - name: Pre-clean - Remove existing test interface description + junos_config: + lines: + - delete interfaces ge-0/0/1 unit 0 description + comment: "Clean up test interface config" + + - name: Assert pre-clean successful + assert: + that: + - "'delete interfaces' in apply_result.commands[0] or apply_result.changed in [true, false]" + + - name: Apply test config - set interface description + junipernetworks.junos.junos_config: + lines: + - set interfaces ge-0/0/1 unit 0 description "FT Test interface" + comment: "Apply test config" + register: apply_result + + - name: Assert interface config applied + assert: + that: + - apply_result.changed == true + + - name: Confirm commit test with timer + junos_config: + lines: + - set system host-name ft-test-host + confirm: 3 + comment: "Test commit confirmation" + # Intentionally allowing commit to rollback to test confirm + + - name: Rollback config to rollback 0 + junos_config: + rollback: 0 + + - name: Backup config to custom path + junos_config: + lines: + - set system services ssh + backup: true + backup_options: + filename: ssh_backup.cfg + dir_path: ./backup + register: backup_result + + - name: Assert backup created + assert: + that: + - backup_result.backup_path is defined + + + - name: Post-clean - delete test configuration + junos_config: + lines: + - delete interfaces ge-0/0/1 unit 0 description + - delete system host-name + - delete system services ssh + comment: "Post-clean" diff --git a/tests/junipernetworks.junos/pb.juniper_junos_facts.yml b/tests/junipernetworks.junos/pb.juniper_junos_facts.yml new file mode 100644 index 00000000..1c6702d8 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_facts.yml @@ -0,0 +1,44 @@ +- name: Functional Test - junos_facts module + hosts: junos + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + - name: Collect default set of facts (min) + junipernetworks.junos.junos_facts: + register: default_facts + + - name: Assert default facts gathered + assert: + that: + - default_facts.ansible_facts is defined + - default_facts.ansible_facts.ansible_net_model is defined + - default_facts.ansible_facts.ansible_net_hostname is defined + + - name: Collect full facts including config and interfaces + junipernetworks.junos.junos_facts: + gather_subset: + - all + register: full_facts + + - name: Assert full facts gathered + assert: + that: + - full_facts.ansible_facts.ansible_net_interfaces is defined + - full_facts.ansible_facts.ansible_net_config is defined + + - name: Collect hardware and config with text format + junipernetworks.junos.junos_facts: + gather_subset: + - hardware + - config + config_format: text + register: hw_config_facts + + - name: Assert hardware and config facts gathered + assert: + that: + - hw_config_facts.ansible_facts.ansible_net_config is defined + - "'system' in hw_config_facts.ansible_facts.ansible_net_config" diff --git a/tests/junipernetworks.junos/pb.juniper_junos_hostname.yml b/tests/junipernetworks.junos/pb.juniper_junos_hostname.yml new file mode 100644 index 00000000..6d03b3fe --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_hostname.yml @@ -0,0 +1,57 @@ +- name: Functional Test - junos_hostname module + hosts: junos + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + vars: + test_hostname: "ft-host-20250424084647" + + tasks: + + - name: Pre-clean - Delete existing hostname + junipernetworks.junos.junos_hostname: + config: {} + state: deleted + register: delete_result + + - name: Assert pre-clean success + assert: + that: + - delete_result.changed == true or delete_result.changed == false + + - name: Apply hostname config with state merged + junipernetworks.junos.junos_hostname: + config: + hostname: "{{ test_hostname }}" + state: merged + register: merged_result + + - name: Assert hostname was set + assert: + that: + - merged_result.changed == true + - merged_result.after.hostname == test_hostname + + - name: Gather hostname config + junipernetworks.junos.junos_hostname: + state: gathered + register: gather_result + + - name: Assert gathered hostname is correct + assert: + that: + - gather_result.changed == false + - gather_result.gathered.hostname == test_hostname + + - name: Delete test hostname (post-clean) + junipernetworks.junos.junos_hostname: + config: {} + state: deleted + register: cleanup_result + + - name: Assert hostname deleted + assert: + that: + - cleanup_result.changed == true diff --git a/tests/junipernetworks.junos/pb.juniper_junos_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_interfaces.yml new file mode 100644 index 00000000..fe4c520b --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_interfaces.yml @@ -0,0 +1,64 @@ +- name: Functional Test - junos_interfaces module + hosts: junos + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + - name: Pre-clean - Delete test configuration if present + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/1 + units: + - name: 0 + state: deleted + ignore_errors: true + + - name: Apply test config with state merged + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/1 + description: "FT updated interface" + enabled: true + mtu: 1800 + units: + - name: 0 + description: "FT logical unit" + state: merged + register: merge_result + + - name: Gather current interface config + junipernetworks.junos.junos_interfaces: + state: gathered + register: gathered_result + + - name: Assert merged interface config applied + assert: + that: + - merge_result.changed is defined + - gathered_result.gathered is defined + - gathered_result.gathered | selectattr("name", "equalto", "ge-0/0/1") | list | length > 0 + + - name: Render config offline (no connection to device) + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/1 + description: Render test + state: rendered + register: render_result + + - name: Assert rendered config returned + assert: + that: + - render_result.rendered is defined + - render_result.rendered | length > 0 + + - name: Post-clean - Delete test configuration + junipernetworks.junos.junos_interfaces: + config: + - name: ge-0/0/1 + units: + - name: 0 + state: deleted + ignore_errors: true diff --git a/tests/junipernetworks.junos/pb.juniper_junos_l2_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_l2_interfaces.yml new file mode 100644 index 00000000..582a7f8e --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_l2_interfaces.yml @@ -0,0 +1,84 @@ +- name: Functional Test - junos_l2_interfaces module + hosts: junos + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + - name: Pre-define required VLANs + junipernetworks.junos.junos_vlans: + config: + - name: v101 + vlan_id: 101 + - name: vlan30 + vlan_id: 30 + - name: vlan50 + vlan_id: 50 + state: merged + + - name: Pre-clean - Delete existing L2 config + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/3 + - name: ge-0/0/4 + state: deleted + ignore_errors: true + + - name: Apply L2 config - merge access and trunk modes + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/3 + access: + vlan: v101 + - name: ge-0/0/4 + trunk: + allowed_vlans: [ vlan30 ] + native_vlan: "50" + state: merged + register: merge_result + + - name: Assert L2 config merged + assert: + that: + - merge_result is defined + - merge_result.changed is defined + - merge_result.changed | bool == true + + - name: Gather current L2 interface config + junipernetworks.junos.junos_l2_interfaces: + state: gathered + register: gathered_result + + - name: Assert L2 config gathered + assert: + that: + - gathered_result.gathered | selectattr("name", "equalto", "ge-0/0/3") | list | length > 0 + - gathered_result.gathered | selectattr("name", "equalto", "ge-0/0/4") | list | length > 0 + + - name: Render L2 config offline + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/3 + access: + vlan: v101 + - name: ge-0/0/4 + trunk: + allowed_vlans: [ vlan30 ] + native_vlan: 50 + state: rendered + register: render_result + + - name: Assert rendered L2 config + assert: + that: + - render_result.rendered is defined + - render_result.rendered | length > 0 + + - name: Post-clean - Delete L2 config + junipernetworks.junos.junos_l2_interfaces: + config: + - name: ge-0/0/3 + - name: ge-0/0/4 + state: deleted + ignore_errors: true diff --git a/tests/junipernetworks.junos/pb.juniper_junos_l3_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_l3_interfaces.yml new file mode 100644 index 00000000..36c5888c --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_l3_interfaces.yml @@ -0,0 +1,73 @@ +- name: Functional Test - junos_l3_interfaces module + hosts: junos + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + + - name: Pre-clean - Delete L3 logical interfaces if present + junos_l3_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + state: deleted + ignore_errors: true + + - name: Apply L3 configuration (merge) + junos_l3_interfaces: + config: + - name: ge-0/0/1 + ipv4: + - address: 192.168.1.10/24 + ipv6: + - address: 2001:db8::1/64 + - name: ge-0/0/2 + ipv4: + - address: dhcp + state: merged + register: merge_result + + - name: Assert L3 config applied + assert: + that: + - merge_result.changed is defined + - merge_result.after | selectattr("name", "equalto", "ge-0/0/1") | list | length > 0 + - merge_result.after | selectattr("name", "equalto", "ge-0/0/2") | list | length > 0 + + - name: Gather L3 interfaces + junos_l3_interfaces: + state: gathered + register: gathered_result + + - name: Assert L3 interfaces gathered + assert: + that: + - gathered_result.gathered | selectattr("name", "equalto", "ge-0/0/1") | list | length > 0 + - gathered_result.gathered | selectattr("name", "equalto", "ge-0/0/2") | list | length > 0 + + - name: Render L3 config (offline) + junos_l3_interfaces: + config: + - name: ge-0/0/1 + ipv4: + - address: 192.168.1.10/24 + ipv6: + - address: 2001:db8::1/64 + state: rendered + register: render_result + + - name: Assert rendered config is present + assert: + that: + - render_result.rendered is defined + - render_result.rendered | length > 0 + + - name: Post-clean - Delete test L3 configuration + junos_l3_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + state: deleted + ignore_errors: true diff --git a/tests/junipernetworks.junos/pb.juniper_junos_lacp.yml b/tests/junipernetworks.junos/pb.juniper_junos_lacp.yml new file mode 100644 index 00000000..c654288c --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_lacp.yml @@ -0,0 +1,56 @@ +- name: Functional Test - junos_lacp module + hosts: junos + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + + - name: Pre-clean - Delete existing global LACP config + junos_lacp: + state: deleted + ignore_errors: true + + - name: Merge global LACP attributes + junos_lacp: + config: + system_priority: 63 + # link_protection: revertive + state: merged + register: merge_result + + - name: Assert LACP config merged + assert: + that: + - merge_result.changed is defined + + - name: Gather global LACP config + junos_lacp: + state: gathered + register: gather_result + + - name: Assert gathered global LACP config + assert: + that: + - gather_result.gathered.system_priority == 63 + - "'link_protection' not in gather_result.gathered or gather_result.gathered.link_protection == 'revertive'" + + - name: Render LACP config (offline) + junos_lacp: + config: + system_priority: 63 + link_protection: revertive + state: rendered + register: render_result + + - name: Assert rendered config is returned + assert: + that: + - render_result.rendered is defined + - render_result.rendered | length > 0 + + - name: Post-clean - Delete global LACP config + junos_lacp: + state: deleted + ignore_errors: true diff --git a/tests/junipernetworks.junos/pb.juniper_junos_lacp_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_lacp_interfaces.yml new file mode 100644 index 00000000..5ec05849 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_lacp_interfaces.yml @@ -0,0 +1,82 @@ +--- +- name: Functional Test - junos_lacp_interfaces module + hosts: netconf_connection_testcases + gather_facts: false + connection: ansible.netcommon.netconf + + tasks: + + - name: Pre-clean - Delete LACP interfaces attributes of given interfaces + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + - name: ge-0/0/2 + - name: ge-0/0/3 + state: deleted + + - name: Merge provided configuration with device configuration + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + - name: ge-0/0/3 + port_priority: 100 + force_up: true + state: merged + + - name: Replace device LACP interfaces configuration with provided configuration + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + period: slow + state: replaced + + - name: Overrides all device LACP interfaces configuration with provided configuration + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + system: + priority: 300 + mac: + address: 00:00:00:00:00:03 + - name: ge-0/0/2 + port_priority: 200 + force_up: false + state: overridden + + - name: Gather junos lacp interfaces facts + junipernetworks.junos.junos_lacp_interfaces: + state: gathered + register: gather_result + + - name: Extract interface names from gathered result + set_fact: + gathered_names: "{{ gather_result.gathered | map(attribute='name') | list }}" + + - name: Assert gathered includes ae0 and ge-0/0/2 + ansible.builtin.assert: + that: + - "'ae0' in gathered_names" + - "'ge-0/0/2' in gathered_names" + fail_msg: "Expected interfaces ae0 and ge-0/0/2 not found in gathered result" + success_msg: "Successfully found ae0 and ge-0/0/2 in gathered result" + + - name: Render platform specific xml from task input using rendered state + junipernetworks.junos.junos_lacp_interfaces: + config: + - name: ae0 + period: fast + sync_reset: enable + system: + priority: 100 + mac: + address: 00:00:00:00:00:02 + - name: ge-0/0/3 + port_priority: 100 + force_up: true + state: rendered diff --git a/tests/junipernetworks.junos/pb.juniper_junos_lldp_global.yml b/tests/junipernetworks.junos/pb.juniper_junos_lldp_global.yml new file mode 100644 index 00000000..b0ddc6bc --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_lldp_global.yml @@ -0,0 +1,54 @@ +- name: Functional Test - junos_lldp_global module + hosts: netconf_connection_testcases + connection: ansible.netcommon.netconf + gather_facts: false + tasks: + + - name: Merge LLDP global configuration + junipernetworks.junos.junos_lldp_global: + config: + interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + state: merged + + - name: Replace LLDP global configuration + junipernetworks.junos.junos_lldp_global: + config: + address: 20.2.2.2 + hold_multiplier: 5 + enabled: false + state: replaced + + - name: Gather LLDP global configuration + junipernetworks.junos.junos_lldp_global: + state: gathered + register: gather_result + + - name: Assert LLDP address is correctly configured + ansible.builtin.assert: + that: + - gather_result.gathered.address == "20.2.2.2" + - gather_result.gathered.hold_multiplier == 5 + - gather_result.gathered.enabled == false + success_msg: "LLDP global settings gathered correctly" + fail_msg: "LLDP global settings did not match expected values" + + - name: Render LLDP global configuration to XML + junipernetworks.junos.junos_lldp_global: + config: + interval: 10000 + address: 10.1.1.1 + transmit_delay: 400 + hold_multiplier: 10 + state: rendered + register: render_result + + - name: Debug rendered LLDP XML + ansible.builtin.debug: + var: render_result.rendered + + - name: Delete LLDP global configuration + junipernetworks.junos.junos_lldp_global: + state: deleted diff --git a/tests/junipernetworks.junos/pb.juniper_junos_lldp_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_lldp_interfaces.yml new file mode 100644 index 00000000..f80c784f --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_lldp_interfaces.yml @@ -0,0 +1,63 @@ +- name: Functional Test - junos_lldp_interfaces module + hosts: netconf_connection_testcases + connection: ansible.netcommon.netconf + gather_facts: false + tasks: + + - name: Pre-clean LLDP interface config + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + - name: ge-0/0/3 + state: deleted + ignore_errors: true + + - name: Merge LLDP interface configuration + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + enabled: false + state: merged + + - name: Replace LLDP interface configuration + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/2 + enabled: true + - name: ge-0/0/3 + enabled: false + state: replaced + + - name: Override LLDP interface configuration + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/3 + enabled: false + state: overridden + + - name: Gather current LLDP interface configuration + junipernetworks.junos.junos_lldp_interfaces: + state: gathered + register: lldp_interface_gather + + - name: Assert ge-0/0/3 is in gathered LLDP interfaces and disabled + ansible.builtin.assert: + that: + - lldp_interface_gather.gathered | selectattr("name", "equalto", "ge-0/0/3") | selectattr("enabled", "equalto", false) | list | length > 0 + fail_msg: "ge-0/0/3 with enabled: false not found in gathered result" + success_msg: "ge-0/0/3 is correctly disabled in LLDP interfaces" + + - name: Render LLDP interface configuration for offline validation + junipernetworks.junos.junos_lldp_interfaces: + config: + - name: ge-0/0/1 + - name: ge-0/0/2 + enabled: false + state: rendered + register: rendered_lldp + + - name: Debug rendered XML + ansible.builtin.debug: + var: rendered_lldp.rendered diff --git a/tests/junipernetworks.junos/pb.juniper_junos_netconf.yml b/tests/junipernetworks.junos/pb.juniper_junos_netconf.yml new file mode 100644 index 00000000..79e44271 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_netconf.yml @@ -0,0 +1,29 @@ +# NOTE: This module requires 'network_cli' connection type. +# Run this playbook using: +# ansible-playbook -i inventory pb.juniper_junos_netconf.yml -e ansible_connection=network_cli + +- name: Functional Test - junos_netconf module + hosts: netconf_connection_testcases + gather_facts: false + connection: network_cli + + tasks: + + - name: Enable NETCONF service on port 830 + junipernetworks.junos.junos_netconf: + netconf_port: 830 + state: present + register: enable_result + + - name: Debug NETCONF enable command + ansible.builtin.debug: + var: enable_result.commands + + - name: Disable NETCONF service + junipernetworks.junos.junos_netconf: + state: absent + register: disable_result + + - name: Debug NETCONF disable command + ansible.builtin.debug: + var: disable_result.commands diff --git a/tests/junipernetworks.junos/pb.juniper_junos_user.yml b/tests/junipernetworks.junos/pb.juniper_junos_user.yml new file mode 100644 index 00000000..5ef05200 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_user.yml @@ -0,0 +1,46 @@ +--- +- name: Functional Test - junos_user module + hosts: netconf_connection_testcases + gather_facts: false + connection: ansible.netcommon.netconf + + tasks: + - name: Ensure test user is absent before test + junipernetworks.junos.junos_user: + name: ansible_test_user + state: absent + ignore_errors: true + + - name: Create a new user account with optional SSH key + junipernetworks.junos.junos_user: + name: ansible_test_user + role: super-user + sshkey: "{{ user_ssh_key | default(omit) }}" + full_name: "Ansible Test User" + state: present + # Note: Provide SSH key using: + # ansible-playbook pb.juniper_junos_user.yml -e "user_ssh_key={{ lookup('file', '~/.ssh/id_rsa.pub') }}" + + - name: Set user password (SHA-512 hashed) + junipernetworks.junos.junos_user: + name: ansible_test_user + role: super-user + encrypted_password: "{{ 'testpass123' | password_hash('sha512') }}" + state: present + + - name: Create a list of additional users + junipernetworks.junos.junos_user: + aggregate: + - { name: test_user1, full_name: "Operator User", role: operator, state: present } + - { name: test_user2, full_name: "ReadOnly User", role: read-only, state: present } + + - name: Delete additional users + junipernetworks.junos.junos_user: + aggregate: + - { name: test_user1, full_name: "Operator User", role: operator, state: absent } + - { name: test_user2, full_name: "ReadOnly User", role: read-only, state: absent } + + - name: Remove the test user account + junipernetworks.junos.junos_user: + name: ansible_test_user + state: absent From 612a8865c8719ed6f3840b5ea9d47e0330a7e9d3 Mon Sep 17 00:00:00 2001 From: Brij Tarkhala Date: Tue, 6 May 2025 01:42:46 +0530 Subject: [PATCH 2/4] Add commit-ready functional tests under tests/junipernetworks.junos --- tests/junipernetworks.junos/README.md | 97 ++++++++ tests/junipernetworks.junos/ansible.cfg | 1 + tests/junipernetworks.junos/inventory | 16 +- .../parsed_bgp_address_family.cfg | 104 +++++++++ .../parsed_configs/parsed_bgp_global.cfg | 16 ++ .../parsed_configs/parsed_junos_vlans.cfg | 16 ++ .../parsed_configs/parsed_logging_global.cfg | 34 +++ .../parsed_configs/parsed_ntp_global.cfg | 60 +++++ .../parsed_configs/parsed_ospf_interfaces.cfg | 18 ++ .../parsed_configs/parsed_ospfv2.cfg | 53 +++++ .../parsed_configs/parsed_ospfv3.cfg | 34 +++ .../parsed_routing_instances.cfg | 25 ++ .../parsed_configs/parsed_routing_options.cfg | 9 + .../parsed_security_policies.cfg | 32 +++ .../parsed_security_policies_global.cfg | 41 ++++ .../parsed_configs/parsed_security_zones.cfg | 24 ++ .../parsed_configs/parsed_snmp.cfg | 24 ++ .../parsed_configs/parsed_static_routes.cfg | 18 ++ .../pb.juniper_junos_acl_interfaces.yml | 2 +- .../pb.juniper_junos_acls.yml | 2 +- .../pb.juniper_junos_banner.yml | 14 +- .../pb.juniper_junos_bgp_address_family.yml | 151 ++++++++++++ .../pb.juniper_junos_bgp_global.yml | 124 ++++++++++ .../pb.juniper_junos_command.yml | 2 +- .../pb.juniper_junos_config.yml | 6 +- .../pb.juniper_junos_facts.yml | 2 +- .../pb.juniper_junos_hostname.yml | 2 +- .../pb.juniper_junos_interfaces.yml | 2 +- .../pb.juniper_junos_l2_interfaces.yml | 4 +- .../pb.juniper_junos_l3_interfaces.yml | 2 +- .../pb.juniper_junos_lacp.yml | 5 +- .../pb.juniper_junos_lacp_interfaces.yml | 37 ++- .../pb.juniper_junos_lag_interfaces.yml | 45 ++++ .../pb.juniper_junos_lldp_global.yml | 33 ++- .../pb.juniper_junos_lldp_interfaces.yml | 4 +- .../pb.juniper_junos_logging_global.yml | 195 ++++++++++++++++ .../pb.juniper_junos_netconf.yml | 27 +-- .../pb.juniper_junos_ntp_global.yml | 217 ++++++++++++++++++ .../pb.juniper_junos_ospf_interfaces.yml | 141 ++++++++++++ .../pb.juniper_junos_ospfv2.yml | 181 +++++++++++++++ .../pb.juniper_junos_ospfv3.yml | 88 +++++++ .../pb.juniper_junos_package.yml | 63 +++++ .../pb.juniper_junos_ping.yml | 67 ++++++ .../pb.juniper_junos_prefix_lists.yml | 118 ++++++++++ .../pb.juniper_junos_routing_instances.yml | 146 ++++++++++++ .../pb.juniper_junos_routing_options.yml | 105 +++++++++ .../pb.juniper_junos_rpc.yml | 48 ++++ .../pb.juniper_junos_security_policies.yml | 27 +++ ...juniper_junos_security_policies_global.yml | 37 +++ .../pb.juniper_junos_security_zones.yml | 41 ++++ .../pb.juniper_junos_snmp_server.yml | 130 +++++++++++ .../pb.juniper_junos_static_routes.yml | 33 +++ .../pb.juniper_junos_system.yml | 73 ++++++ .../pb.juniper_junos_vlans.yml | 49 ++++ .../pb.juniper_junos_vrf.yml | 69 ++++++ tests/junipernetworks.junos/run_all_tests.sh | 27 +++ 56 files changed, 2868 insertions(+), 73 deletions(-) create mode 100644 tests/junipernetworks.junos/README.md create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_bgp_address_family.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_bgp_global.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_junos_vlans.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_logging_global.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_ntp_global.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_ospf_interfaces.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_ospfv2.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_ospfv3.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_routing_instances.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_routing_options.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_security_policies.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_security_policies_global.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_security_zones.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_snmp.cfg create mode 100644 tests/junipernetworks.junos/parsed_configs/parsed_static_routes.cfg create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_bgp_address_family.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_bgp_global.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_lag_interfaces.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_logging_global.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_ntp_global.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_ospf_interfaces.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_ospfv2.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_ospfv3.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_package.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_ping.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_prefix_lists.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_routing_instances.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_routing_options.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_rpc.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_security_policies.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_security_policies_global.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_security_zones.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_snmp_server.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_static_routes.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_system.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_vlans.yml create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_vrf.yml create mode 100755 tests/junipernetworks.junos/run_all_tests.sh diff --git a/tests/junipernetworks.junos/README.md b/tests/junipernetworks.junos/README.md new file mode 100644 index 00000000..bdc6e87a --- /dev/null +++ b/tests/junipernetworks.junos/README.md @@ -0,0 +1,97 @@ +Functional Tests for Juniper Ansible Collection (junipernetworks.junos) + +This directory contains a complete suite of functional tests for the modules in the junipernetworks.junos Ansible collection. + +These playbooks verify behavior for each supported module using real Junos devices or virtual environments, following official module documentation examples. This ensures compatibility, schema adherence, and correctness across configuration states like merged, replaced, overridden, deleted, rendered, gathered, and parsed. + +๐Ÿ”ง Directory Structure + +All functional test playbooks are located under: + +tests/junipernetworks.junos/ + +Each playbook corresponds to one Ansible module, for example: + +pb.juniper_junos_system.yml + +pb.juniper_junos_lag_interfaces.yml + +pb.juniper_junos_bgp_global.yml + +etc. + +Any required configuration files (e.g., parsed_configs/*.cfg) are also included. + +๐Ÿงช Steps to Execute Functional Test Playbooks + +1. Clone the Repository + +git clone https://github.com/Juniper/ansible-junos-stdlib.git +cd ansible-junos-stdlib/tests/junipernetworks.junos + +2. Ensure ansible.cfg is configured correctly + +[defaults] +hash_behaviour = merge +inventory = inventory +host_key_checking = False +log_path = ./ansible.log + +[persistent_connection] +command_timeout = 300 + +3. Inventory Setup (inventory) + +The inventory file defines three connection types: + +a. NETCONF (default) + +[netconf_connection_testcases] +junos_device ansible_host=xx.xx.xx.xx + +b. Local connection + +[local_connection_testcases] +localhost ansible_connection=local ansible_network_os=none + +c. Network CLI + +[network_cli_testcases] +junos_netconf_device ansible_host=xx.xx.xx.xx ansible_connection=network_cli ansible_network_os=junipernetworks.junos.junos ansible_user=xx ansible_password=xx + +Global variables: + +[all:vars] +ansible_python_interpreter=/path/to/venv/bin/python +ansible_connection=netconf +ansible_network_os=junipernetworks.junos.junos +ansible_user=xx +ansible_password=xx + + +4. Run a Functional Test + +ansible-playbook pb.juniper_junos_l3_interfaces.yml + +You can use -v or -vvv for verbose output and troubleshooting. + +5. Run All Tests Automatically + +To run all 38 functional tests in sequence, use the provided script: + +./run_all_tests.sh + + +This script will: + +Execute every test playbook under junipernetworks.junos/ + +Log results to ansible.log + +Ensure a complete functional regression pass + +Make sure the script is executable: + +chmod +x run_all_tests.sh + + diff --git a/tests/junipernetworks.junos/ansible.cfg b/tests/junipernetworks.junos/ansible.cfg index 95986e7d..27b4e8e3 100644 --- a/tests/junipernetworks.junos/ansible.cfg +++ b/tests/junipernetworks.junos/ansible.cfg @@ -4,5 +4,6 @@ inventory = inventory host_key_checking = False log_path = ./ansible.log + [persistent_connection] command_timeout = 300 diff --git a/tests/junipernetworks.junos/inventory b/tests/junipernetworks.junos/inventory index a952be66..a5fccefd 100644 --- a/tests/junipernetworks.junos/inventory +++ b/tests/junipernetworks.junos/inventory @@ -1,9 +1,15 @@ -[junos] -netconf_connection_testcases ansible_host=x.x.x.x +[netconf_connection_testcases] +junos_device ansible_host=xx.xx.xx.xx + +[local_connection_testcases] +localhost ansible_connection=local ansible_network_os=none + +[network_cli_testcases] +junos_netconf_device ansible_host=xx.xx.xx.xx ansible_connection=network_cli ansible_network_os=junipernetworks.junos.junos ansible_user=xx ansible_password=xx [all:vars] -ansible_python_interpreter= +ansible_python_interpreter=/path/to/venv/bin/python ansible_connection=netconf ansible_network_os=junipernetworks.junos.junos -ansible_user=xxxx -ansible_password=xxxx \ No newline at end of file +ansible_user=xx +ansible_password=xx diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_bgp_address_family.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_bgp_address_family.cfg new file mode 100644 index 00000000..027160f5 --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_bgp_address_family.cfg @@ -0,0 +1,104 @@ + + + + + + + + + + 20 + + 98 + + 2001 + + + + + + 2 + + + + + + + + + + + 4 + + + + + + + + + 9.9.9.9 + + + + + + + + + + + + + + 20 + + 99 + + + + + + + + + + + + 3 + + + + + 20 + + 99 + + 2000 + + + + + + + 23000 + 32000 + + + 20 + 32000 + + + + 2 + + + from-fib + + + + + + + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_bgp_global.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_bgp_global.cfg new file mode 100644 index 00000000..7a8f93f4 --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_bgp_global.cfg @@ -0,0 +1,16 @@ + + + + + external-peers + external + 192.0.2.1 + + bgp-keychain + + 65100 + + 65000 + + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_junos_vlans.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_junos_vlans.cfg new file mode 100644 index 00000000..d4d690cb --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_junos_vlans.cfg @@ -0,0 +1,16 @@ + + + + + + vlan1 + 1 + + + vlan2 + 2 + irb.12 + + + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_logging_global.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_logging_global.cfg new file mode 100644 index 00000000..04a189d4 --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_logging_global.cfg @@ -0,0 +1,34 @@ + + + + + + + messages + + any + + + + authorization + + + + + interactive-commands + + interactive-commands + + + + + * + + any + + + + + + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_ntp_global.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_ntp_global.cfg new file mode 100644 index 00000000..4bca659d --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_ntp_global.cfg @@ -0,0 +1,60 @@ + + + + 78.46.194.186 + +
172.16.255.255
+ 50 + 200 + 3 + rt1 +
+ +
192.16.255.255
+ 50 + 200 + 3 + rt2 +
+ + 2 + 224.0.0.1 + + 78.44.194.186 + + + 172.44.194.186 + 10000 + + 3 + + + 48.46.194.186 + 34 + + 2 + rt1 + + + 48.45.194.186 + 34 + + 2 + + + 172.45.194.186 + rt1 + + + 171.45.194.186 + rt2 + + + 300 + accept + + 3000 + 2000 +
+
+
diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_ospf_interfaces.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_ospf_interfaces.cfg new file mode 100644 index 00000000..847c78dc --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_ospf_interfaces.cfg @@ -0,0 +1,18 @@ + + + + + 0.0.0.0 + + ge-0/0/0.0 + 5 + 10 + + + ge-0/0/1.0 + + + + + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_ospfv2.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_ospfv2.cfg new file mode 100644 index 00000000..5dff43df --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_ospfv2.cfg @@ -0,0 +1,53 @@ + + + + + + 10g + + + 0.0.0.100 + + 100 + + + 10.200.16.0/24 + + 10000 + + + 10.200.11.0/24 + + + + + so-0/0/0.0 + + + + 1g + 5 + + + 10g + 40 + + + 5 + 3 + 2 + 2 + 4 + 2 + + + + + + 10.200.16.75 + + 65432 + + + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_ospfv3.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_ospfv3.cfg new file mode 100644 index 00000000..55292b7d --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_ospfv3.cfg @@ -0,0 +1,34 @@ + + + + + + + 0.0.0.100 + + 200 + + + so-0/0/0.0 + + 5 + 3 + + + + + 0.0.0.200 + + ge-1/1/0.0 + + + ge-2/2/0.0 + + + + + + 10.200.16.75 + + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_routing_instances.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_routing_instances.cfg new file mode 100644 index 00000000..0acea602 --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_routing_instances.cfg @@ -0,0 +1,25 @@ + + + + test + vrf + 10.58.255.1:37 + test-policy + test-policy + test-policy-1 + sp-0/0/0.0 + gr-0/0/0.0 + + + + forwardinst + forwarding + Configured by Ansible Content Team + + + vtest1 + virtual-router + ge-0/0/0.0 + + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_routing_options.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_routing_options.cfg new file mode 100644 index 00000000..e3e4d4ad --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_routing_options.cfg @@ -0,0 +1,9 @@ + + + + + 2 + + 2.2.2.2 + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_security_policies.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_security_policies.cfg new file mode 100644 index 00000000..50fbe124 --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_security_policies.cfg @@ -0,0 +1,32 @@ + + + + + + + test_glob_1 + + any-ipv6 + any-ipv6 + any + + + + + + + test_glob_2 + + any-ipv6 + any-ipv6 + any + + + + + + + + + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_security_policies_global.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_security_policies_global.cfg new file mode 100644 index 00000000..af26beca --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_security_policies_global.cfg @@ -0,0 +1,41 @@ + + + + + + + + + 10k + 3 + + /[A-Z]*/gm + + + all + + + + + + + + + + enable + + + + + + + + 10 + 10 + + + + + + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_security_zones.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_security_zones.cfg new file mode 100644 index 00000000..640e69c2 --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_security_zones.cfg @@ -0,0 +1,24 @@ + + + + + + + trust + Trusted zone + + ge-0/0/1.0 + + + ssh + + + ping + + + + + + + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_snmp.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_snmp.cfg new file mode 100644 index 00000000..3ba55e02 --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_snmp.cfg @@ -0,0 +1,24 @@ + + + + + + + cl1 + 192.16.1.0/24 + 192.16.2.0/24 + 11.11.11.11/32 + + + cl2 + 192.16.4.0/24 + + + clv1 + clv2 + + + + + + diff --git a/tests/junipernetworks.junos/parsed_configs/parsed_static_routes.cfg b/tests/junipernetworks.junos/parsed_configs/parsed_static_routes.cfg new file mode 100644 index 00000000..9b0f576e --- /dev/null +++ b/tests/junipernetworks.junos/parsed_configs/parsed_static_routes.cfg @@ -0,0 +1,18 @@ + + + + + + + 192.168.16.0/24 + 172.16.1.2 + 172.16.1.3 + + + 192.168.47.0/24 + 10.200.16.2 + + + + + diff --git a/tests/junipernetworks.junos/pb.juniper_junos_acl_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_acl_interfaces.yml index cd2dd6a4..f051f1aa 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_acl_interfaces.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_acl_interfaces.yml @@ -1,6 +1,6 @@ - name: Functional Test - junos_acl_interfaces module - hosts: junos + hosts: junos_device gather_facts: false connection: netconf collections: diff --git a/tests/junipernetworks.junos/pb.juniper_junos_acls.yml b/tests/junipernetworks.junos/pb.juniper_junos_acls.yml index 06f95576..0ee9e576 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_acls.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_acls.yml @@ -1,5 +1,5 @@ - name: Functional Test - junos_acls module - hosts: junos + hosts: junos_device gather_facts: false connection: netconf collections: diff --git a/tests/junipernetworks.junos/pb.juniper_junos_banner.yml b/tests/junipernetworks.junos/pb.juniper_junos_banner.yml index ab8085bd..7799536b 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_banner.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_banner.yml @@ -1,5 +1,5 @@ - name: Functional Test - junos_banner module - hosts: junos + hosts: junos_device gather_facts: false connection: netconf collections: @@ -12,7 +12,7 @@ tasks: - name: Pre-clean - Remove login banner if exists - junos_banner: + junipernetworks.junos.junos_banner: banner: login state: absent register: preclean_result @@ -23,7 +23,7 @@ - preclean_result.changed in [true, false] - name: Apply login banner with state present - junos_banner: + junipernetworks.junos.junos_banner: banner: login text: "{{ login_banner_text }}" state: present @@ -37,9 +37,7 @@ - name: Deactivate the login banner junipernetworks.junos.junos_banner: banner: login - text: | - this is my login banner - used for testing purposes + text: "{{ login_banner_text }}" state: present active: false register: deactivate_result @@ -50,7 +48,7 @@ - deactivate_result.changed == true - name: Reactivate the login banner - junos_banner: + junipernetworks.junos.junos_banner: banner: login state: present active: true @@ -65,7 +63,7 @@ - reactivate_result.changed == true - name: Post-clean - Remove login banner - junos_banner: + junipernetworks.junos.junos_banner: banner: login state: absent register: postclean_result diff --git a/tests/junipernetworks.junos/pb.juniper_junos_bgp_address_family.yml b/tests/junipernetworks.junos/pb.juniper_junos_bgp_address_family.yml new file mode 100644 index 00000000..b7eb1b9c --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_bgp_address_family.yml @@ -0,0 +1,151 @@ +- name: Functional Test - junos_bgp_address_family + hosts: junos_device + gather_facts: no + connection: ansible.netcommon.netconf + collections: + - junipernetworks.junos + + tasks: + - name: MERGED - Full BGP address family config + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'evpn' + af_type: + - type: 'signaling' + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + - afi: 'inet' + af_type: + - type: 'flow' + legacy_redirect_ip_action: + send: true + receive: true + loops: 4 + no_install: true + output_queue_priority_expedited: true + secondary_independent_resolution: true + + - type: 'unicast' + extended_nexthop: true + extended_nexthop_color: true + local_ipv4_address: '9.9.9.9' + + - type: 'labeled-unicast' + entropy_label: + no_next_hop_validation: true + explicit_null: + connected_only: true + per_prefix_label: true + per_group_label: true + prefix_limit: + maximum: 20 + limit_threshold: 99 + forever: true + resolve_vpn: true + rib: 'inet.3' + route_refresh_priority_expedited: true + route_refresh_priority_priority: 3 + + - type: 'any' + accepted_prefix_limit: + maximum: 20 + limit_threshold: 99 + idle_timeout_value: 2000 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + delay_route_advertisements: + max_delay_route_age: 20 + max_delay_routing_uptime: 32000 + min_delay_inbound_convergence: 32000 + min_delay_routing_uptime: 23000 + graceful_restart_forwarding_state_bit: 'from-fib' + state: merged + + - name: REPLACED - Replace BGP config with simplified evpn + 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 + + - name: OVERRIDDEN - Override with same evpn 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 + + - name: DELETED - Delete AFI inet only + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'inet' + state: deleted + + - name: DELETED - Delete all address-family configuration + junipernetworks.junos.junos_bgp_address_family: + config: {} + state: deleted + + - name: GATHERED - Gather current BGP AF config + junipernetworks.junos.junos_bgp_address_family: + config: {} + state: gathered + register: gathered_output + + - name: Assert BGP config gathered + assert: + that: + - gathered_output.gathered is defined + + - name: RENDERED - Render BGP config + junipernetworks.junos.junos_bgp_address_family: + config: + address_family: + - afi: 'evpn' + af_type: + - type: 'signaling' + accepted_prefix_limit: + maximum: 20 + limit_threshold: 98 + idle_timeout_value: 2001 + damping: true + defer_initial_multipath_build: + maximum_delay: 2 + state: rendered + + - name: PARSED - Parse provided BGP config + junipernetworks.junos.junos_bgp_address_family: + running_config: "{{ lookup('file', './parsed_configs/parsed_bgp_address_family.cfg') }}" + state: parsed diff --git a/tests/junipernetworks.junos/pb.juniper_junos_bgp_global.yml b/tests/junipernetworks.junos/pb.juniper_junos_bgp_global.yml new file mode 100644 index 00000000..2aa9a467 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_bgp_global.yml @@ -0,0 +1,124 @@ +- name: Functional Test - junos_bgp_global + hosts: junos_device + connection: netconf + gather_facts: false + + tasks: + + - name: MERGED - Merge provided bgp config + 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 + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + egress_te_sid_stats: true + hold_time: 5 + holddown_all_stale_labels: true + include_mp_next_hop: true + log_updown: true + no_advertise_peer_as: true + no_aggregator_id: true + no_client_reflect: true + out_delay: 10 + precision_timers: true + preference: 2 + state: merged + + - name: REPLACED - Replace bgp config + junipernetworks.junos.junos_bgp_global: + config: + advertise_inactive: true + 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 + + - name: OVERRIDDEN - Override running config + junipernetworks.junos.junos_bgp_global: + config: + advertise_inactive: true + 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 + + - name: GATHERED - Gather bgp global facts + junipernetworks.junos.junos_bgp_global: + config: + state: gathered + + - name: RENDERED - Render configuration into XML + 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 + bgp_error_tolerance: + malformed_route_limit: 20000000 + bmp: + monitor: true + damping: true + description: "This is configured with Junos_bgp resource module" + egress_te_sid_stats: true + hold_time: 5 + holddown_all_stale_labels: true + include_mp_next_hop: true + log_updown: true + no_advertise_peer_as: true + no_aggregator_id: true + no_client_reflect: true + out_delay: 10 + precision_timers: true + preference: 2 + state: rendered + + - name: PARSED - Parse the device config into facts + junipernetworks.junos.junos_bgp_global: + running_config: "{{ lookup('file', './parsed_configs/parsed_bgp_global.cfg') }}" + state: parsed + + - name: DELETED - Delete the bgp config + junipernetworks.junos.junos_bgp_global: + config: + state: deleted + + - name: PURGED - Purge the bgp config + junipernetworks.junos.junos_bgp_global: + config: + state: purged diff --git a/tests/junipernetworks.junos/pb.juniper_junos_command.yml b/tests/junipernetworks.junos/pb.juniper_junos_command.yml index e384dfd5..14e7271c 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_command.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_command.yml @@ -1,7 +1,7 @@ - name: Functional Test - junos_command module - hosts: junos + hosts: junos_device gather_facts: false connection: netconf collections: diff --git a/tests/junipernetworks.junos/pb.juniper_junos_config.yml b/tests/junipernetworks.junos/pb.juniper_junos_config.yml index b8a8dc6a..43a61133 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_config.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_config.yml @@ -1,5 +1,5 @@ - name: Functional Test - junos_config module - hosts: junos + hosts: junos_device gather_facts: false connection: netconf collections: @@ -12,11 +12,12 @@ lines: - delete interfaces ge-0/0/1 unit 0 description comment: "Clean up test interface config" + register: preclean_result - name: Assert pre-clean successful assert: that: - - "'delete interfaces' in apply_result.commands[0] or apply_result.changed in [true, false]" + - preclean_result.changed in [true, false] - name: Apply test config - set interface description junipernetworks.junos.junos_config: @@ -56,7 +57,6 @@ assert: that: - backup_result.backup_path is defined - - name: Post-clean - delete test configuration junos_config: diff --git a/tests/junipernetworks.junos/pb.juniper_junos_facts.yml b/tests/junipernetworks.junos/pb.juniper_junos_facts.yml index 1c6702d8..a40a534a 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_facts.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_facts.yml @@ -1,5 +1,5 @@ - name: Functional Test - junos_facts module - hosts: junos + hosts: junos_device gather_facts: false connection: netconf collections: diff --git a/tests/junipernetworks.junos/pb.juniper_junos_hostname.yml b/tests/junipernetworks.junos/pb.juniper_junos_hostname.yml index 6d03b3fe..afe3c26f 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_hostname.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_hostname.yml @@ -1,5 +1,5 @@ - name: Functional Test - junos_hostname module - hosts: junos + hosts: junos_device gather_facts: false connection: netconf collections: diff --git a/tests/junipernetworks.junos/pb.juniper_junos_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_interfaces.yml index fe4c520b..8aa9b620 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_interfaces.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_interfaces.yml @@ -1,5 +1,5 @@ - name: Functional Test - junos_interfaces module - hosts: junos + hosts: junos_device gather_facts: false connection: netconf collections: diff --git a/tests/junipernetworks.junos/pb.juniper_junos_l2_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_l2_interfaces.yml index 582a7f8e..78d9c90c 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_l2_interfaces.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_l2_interfaces.yml @@ -1,5 +1,7 @@ +# Note: This functional test requires switching to be enabled on interfaces. + - name: Functional Test - junos_l2_interfaces module - hosts: junos + hosts: junos_device gather_facts: false connection: netconf collections: diff --git a/tests/junipernetworks.junos/pb.juniper_junos_l3_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_l3_interfaces.yml index 36c5888c..f83b6d2e 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_l3_interfaces.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_l3_interfaces.yml @@ -1,5 +1,5 @@ - name: Functional Test - junos_l3_interfaces module - hosts: junos + hosts: junos_device gather_facts: false connection: netconf collections: diff --git a/tests/junipernetworks.junos/pb.juniper_junos_lacp.yml b/tests/junipernetworks.junos/pb.juniper_junos_lacp.yml index c654288c..51717b28 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_lacp.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_lacp.yml @@ -1,5 +1,5 @@ - name: Functional Test - junos_lacp module - hosts: junos + hosts: junos_device gather_facts: false connection: netconf collections: @@ -34,8 +34,7 @@ assert: that: - gather_result.gathered.system_priority == 63 - - "'link_protection' not in gather_result.gathered or gather_result.gathered.link_protection == 'revertive'" - + - name: Render LACP config (offline) junos_lacp: config: diff --git a/tests/junipernetworks.junos/pb.juniper_junos_lacp_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_lacp_interfaces.yml index 5ec05849..126abf23 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_lacp_interfaces.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_lacp_interfaces.yml @@ -2,19 +2,18 @@ - name: Functional Test - junos_lacp_interfaces module hosts: netconf_connection_testcases gather_facts: false - connection: ansible.netcommon.netconf + connection: netconf tasks: - - name: Pre-clean - Delete LACP interfaces attributes of given interfaces + - name: Pre-clean - Delete LACP attributes on ae0 junipernetworks.junos.junos_lacp_interfaces: config: - name: ae0 - - name: ge-0/0/2 - - name: ge-0/0/3 state: deleted + ignore_errors: true - - name: Merge provided configuration with device configuration + - name: Merge LACP configuration onto ae0 junipernetworks.junos.junos_lacp_interfaces: config: - name: ae0 @@ -24,19 +23,16 @@ priority: 100 mac: address: 00:00:00:00:00:02 - - name: ge-0/0/3 - port_priority: 100 - force_up: true state: merged - - name: Replace device LACP interfaces configuration with provided configuration + - name: Replace LACP configuration on ae0 junipernetworks.junos.junos_lacp_interfaces: config: - name: ae0 period: slow state: replaced - - name: Overrides all device LACP interfaces configuration with provided configuration + - name: Override all LACP configuration on ae0 junipernetworks.junos.junos_lacp_interfaces: config: - name: ae0 @@ -44,29 +40,25 @@ priority: 300 mac: address: 00:00:00:00:00:03 - - name: ge-0/0/2 - port_priority: 200 - force_up: false state: overridden - - name: Gather junos lacp interfaces facts + - name: Gather LACP interfaces junipernetworks.junos.junos_lacp_interfaces: state: gathered register: gather_result - - name: Extract interface names from gathered result + - name: Extract gathered interface names set_fact: - gathered_names: "{{ gather_result.gathered | map(attribute='name') | list }}" + gathered_names: "{{ gather_result.gathered | map(attribute='name') | list }}" - - name: Assert gathered includes ae0 and ge-0/0/2 + - name: Assert ae0 is present in gathered result ansible.builtin.assert: that: - "'ae0' in gathered_names" - - "'ge-0/0/2' in gathered_names" - fail_msg: "Expected interfaces ae0 and ge-0/0/2 not found in gathered result" - success_msg: "Successfully found ae0 and ge-0/0/2 in gathered result" + fail_msg: "Expected interface ae0 not found in gathered result" + success_msg: "Successfully found ae0 in gathered result" - - name: Render platform specific xml from task input using rendered state + - name: Render platform-specific XML from input config junipernetworks.junos.junos_lacp_interfaces: config: - name: ae0 @@ -76,7 +68,4 @@ priority: 100 mac: address: 00:00:00:00:00:02 - - name: ge-0/0/3 - port_priority: 100 - force_up: true state: rendered diff --git a/tests/junipernetworks.junos/pb.juniper_junos_lag_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_lag_interfaces.yml new file mode 100644 index 00000000..05ef71cf --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_lag_interfaces.yml @@ -0,0 +1,45 @@ +- name: Functional Test - junos_lag_interfaces + hosts: junos_device + connection: ansible.netcommon.netconf + gather_facts: false + collections: + - junipernetworks.junos + + tasks: + + - name: GATHERED - Retrieve existing LAG configuration + junipernetworks.junos.junos_lag_interfaces: + state: gathered + register: result_gathered + + - name: Assert gathered LAG config is returned + assert: + that: + - result_gathered.gathered is defined + - result_gathered.gathered | type_debug == 'list' + + - name: RENDERED - Generate platform-specific XML config + junipernetworks.junos.junos_lag_interfaces: + state: rendered + 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 + register: result_rendered + + - name: Assert rendered LAG config is valid + assert: + that: + - result_rendered.rendered is defined + - result_rendered.rendered | length > 0 diff --git a/tests/junipernetworks.junos/pb.juniper_junos_lldp_global.yml b/tests/junipernetworks.junos/pb.juniper_junos_lldp_global.yml index b0ddc6bc..9d72de12 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_lldp_global.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_lldp_global.yml @@ -2,6 +2,9 @@ hosts: netconf_connection_testcases connection: ansible.netcommon.netconf gather_facts: false + collections: + - junipernetworks.junos + tasks: - name: Merge LLDP global configuration @@ -12,6 +15,12 @@ transmit_delay: 400 hold_multiplier: 10 state: merged + register: merge_result + + - name: Assert LLDP global merge applied + assert: + that: + - merge_result.changed == true - name: Replace LLDP global configuration junipernetworks.junos.junos_lldp_global: @@ -20,6 +29,12 @@ hold_multiplier: 5 enabled: false state: replaced + register: replace_result + + - name: Assert LLDP global replace applied + assert: + that: + - replace_result.changed == true - name: Gather LLDP global configuration junipernetworks.junos.junos_lldp_global: @@ -27,13 +42,11 @@ register: gather_result - name: Assert LLDP address is correctly configured - ansible.builtin.assert: + assert: that: - gather_result.gathered.address == "20.2.2.2" - gather_result.gathered.hold_multiplier == 5 - gather_result.gathered.enabled == false - success_msg: "LLDP global settings gathered correctly" - fail_msg: "LLDP global settings did not match expected values" - name: Render LLDP global configuration to XML junipernetworks.junos.junos_lldp_global: @@ -45,10 +58,18 @@ state: rendered register: render_result - - name: Debug rendered LLDP XML - ansible.builtin.debug: - var: render_result.rendered + - name: Assert rendered LLDP config is valid + assert: + that: + - render_result.rendered is defined + - render_result.rendered | length > 0 - name: Delete LLDP global configuration junipernetworks.junos.junos_lldp_global: state: deleted + register: delete_result + + - name: Assert LLDP global config deleted + assert: + that: + - delete_result.changed == true diff --git a/tests/junipernetworks.junos/pb.juniper_junos_lldp_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_lldp_interfaces.yml index f80c784f..8b36ea22 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_lldp_interfaces.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_lldp_interfaces.yml @@ -58,6 +58,4 @@ state: rendered register: rendered_lldp - - name: Debug rendered XML - ansible.builtin.debug: - var: rendered_lldp.rendered + diff --git a/tests/junipernetworks.junos/pb.juniper_junos_logging_global.yml b/tests/junipernetworks.junos/pb.juniper_junos_logging_global.yml new file mode 100644 index 00000000..76b47f18 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_logging_global.yml @@ -0,0 +1,195 @@ +- name: Functional Test - junos_logging_global + hosts: junos_device + gather_facts: no + connection: ansible.netcommon.netconf + + vars: + routing_instance_name: inst11 + logging_source_address: "{{ source_address }}" + logging_host_address: "{{ host_address }}" + + tasks: + + - name: Ensure routing instance exists + junipernetworks.junos.junos_config: + lines: + - "set routing-instances {{ routing_instance_name }} instance-type virtual-router" + comment: "Pre-create routing instance required for syslog" + update: merge + + - name: MERGED - Full logging configuration + junipernetworks.junos.junos_logging_global: + config: + allow_duplicates: true + archive: + set: true + no_binary_data: true + files: 10 + file_size: 65578 + no_world_readable: true + console: + any: + level: "info" + authorization: + level: "any" + change_log: + level: "critical" + ftp: + level: "none" + files: + - name: "file101" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + - name: "file103" + archive: + set: true + no_binary_data: true + files: 10 + file_size: 65578 + no_world_readable: true + explicit_priority: true + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + hosts: + - name: host111 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "{{ routing_instance_name }}" + source_address: "{{ logging_host_address }}" + routing_instance: "{{ routing_instance_name }}" + log_rotate_frequency: 45 + source_address: "{{ logging_source_address }}" + time_format: + millisecond: true + year: true + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: merged + + - name: REPLACED - Replace logging configuration + junipernetworks.junos.junos_logging_global: + config: + files: + - name: "file104" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + hosts: + - name: host222 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "{{ routing_instance_name }}" + source_address: "{{ logging_host_address }}" + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: replaced + + - name: OVERRIDDEN - Override entire logging config + junipernetworks.junos.junos_logging_global: + config: + files: + - name: "file104" + allow_duplicates: true + - name: "file102" + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + hosts: + - name: host222 + exclude_hostname: true + allow_duplicates: true + any: + level: "any" + structured_data: + set: true + brief: true + facility_override: "ftp" + log_prefix: "field" + match: "^set*" + match_strings: + - "^delete" + - "^prompt" + port: 1231 + routing_instance: "{{ routing_instance_name }}" + source_address: "{{ logging_host_address }}" + users: + - name: "user1" + allow_duplicates: true + - name: "user2" + allow_duplicates: true + any: + level: "any" + user: + level: info + state: overridden + + - name: GATHERED - Gather current logging config + junipernetworks.junos.junos_logging_global: + state: gathered + register: gathered_output + + - name: RENDERED - Render config into XML + junipernetworks.junos.junos_logging_global: + config: "{{ gathered_output.gathered }}" + state: rendered + + - name: PARSED - Load from parsed.cfg + junipernetworks.junos.junos_logging_global: + running_config: "{{ lookup('file', './parsed_configs/parsed_logging_global.cfg') }}" + state: parsed + + - name: DELETED - Delete all logging config + junipernetworks.junos.junos_logging_global: + config: {} + state: deleted diff --git a/tests/junipernetworks.junos/pb.juniper_junos_netconf.yml b/tests/junipernetworks.junos/pb.juniper_junos_netconf.yml index 79e44271..862dab57 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_netconf.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_netconf.yml @@ -1,29 +1,30 @@ -# NOTE: This module requires 'network_cli' connection type. -# Run this playbook using: -# ansible-playbook -i inventory pb.juniper_junos_netconf.yml -e ansible_connection=network_cli - - name: Functional Test - junos_netconf module - hosts: netconf_connection_testcases + hosts: network_cli_testcases gather_facts: false - connection: network_cli + connection: network_cli + collections: + - junipernetworks.junos tasks: - - name: Enable NETCONF service on port 830 junipernetworks.junos.junos_netconf: netconf_port: 830 state: present register: enable_result - - name: Debug NETCONF enable command - ansible.builtin.debug: - var: enable_result.commands + - name: Assert NETCONF service was enabled + assert: + that: + - enable_result.changed is defined + - enable_result.commands | length > 0 - name: Disable NETCONF service junipernetworks.junos.junos_netconf: state: absent register: disable_result - - name: Debug NETCONF disable command - ansible.builtin.debug: - var: disable_result.commands + - name: Assert NETCONF service was disabled + assert: + that: + - disable_result.changed is defined + - disable_result.commands | length > 0 diff --git a/tests/junipernetworks.junos/pb.juniper_junos_ntp_global.yml b/tests/junipernetworks.junos/pb.juniper_junos_ntp_global.yml new file mode 100644 index 00000000..6593c1c0 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_ntp_global.yml @@ -0,0 +1,217 @@ +- name: Functional Test - junos_ntp_global module + hosts: junos_device + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + + - name: Pre-clean - Delete existing NTP global config + junipernetworks.junos.junos_ntp_global: + config: {} + state: deleted + register: preclean_result + - name: Pre-create required routing instances + junipernetworks.junos.junos_routing_instances: + config: + - name: "rt1" + type: "virtual-router" + - name: "rt2" + type: "virtual-router" + state: merged + + - name: Apply NTP global config using merged + junipernetworks.junos.junos_ntp_global: + config: + boot_server: '78.46.194.186' + broadcasts: + - address: '172.16.255.255' + key: '50' + ttl: 200 + version: 3 + routing_instance_name: 'rt1' + - address: '192.16.255.255' + key: '50' + ttl: 200 + version: 3 + routing_instance_name: 'rt2' + broadcast_client: true + interval_range: 2 + multicast_client: "224.0.0.1" + peers: + - peer: "78.44.194.186" + - peer: "172.44.194.186" + key_id: 10000 + prefer: true + version: 3 + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: 'rt1' + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + source_addresses: + - source_address: "172.45.194.186" + routing_instance: 'rt1' + - source_address: "171.45.194.186" + routing_instance: 'rt2' + threshold: + value: 300 + action: "accept" + trusted_keys: + - key_id: 3000 + - key_id: 2000 + state: merged + register: merged_result + + - name: Assert merged result + assert: + that: + - merged_result.changed == true + + - name: Gather NTP global config + junipernetworks.junos.junos_ntp_global: + state: gathered + register: gathered_result + + - name: Assert gathered result + assert: + that: + - gathered_result.gathered is defined + + - name: Replace running NTP global config + junipernetworks.junos.junos_ntp_global: + config: + authentication_keys: + - id: 2 + algorithm: 'md5' + key: 'asdfghd' + - id: 5 + algorithm: 'sha1' + key: 'aasdad' + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: 'rt1' + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + state: replaced + register: replaced_result + + - name: Assert replaced result + assert: + that: + - replaced_result.changed == true + + - name: Override running NTP global config + junipernetworks.junos.junos_ntp_global: + config: + authentication_keys: + - id: 2 + algorithm: 'md5' + key: 'asdfghd' + - id: 5 + algorithm: 'sha1' + key: 'aasdad' + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: 'rt1' + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + state: overridden + register: overridden_result + + - name: Assert overridden result + assert: + that: + - overridden_result.changed == true + + - name: Delete NTP global configuration + junipernetworks.junos.junos_ntp_global: + config: {} + state: deleted + register: deleted_result + + - name: Assert deleted result + assert: + that: + - deleted_result.changed == true + + - name: Render NTP global configuration + junipernetworks.junos.junos_ntp_global: + config: + boot_server: '78.46.194.186' + broadcasts: + - address: '172.16.255.255' + key: '50' + ttl: 200 + version: 3 + routing_instance_name: 'rt1' + - address: '192.16.255.255' + key: '50' + ttl: 200 + version: 3 + routing_instance_name: 'rt2' + broadcast_client: true + interval_range: 2 + multicast_client: "224.0.0.1" + peers: + - peer: "78.44.194.186" + - peer: "172.44.194.186" + key_id: 10000 + prefer: true + version: 3 + servers: + - server: "48.46.194.186" + key_id: 34 + prefer: true + version: 2 + routing_instance: 'rt1' + - server: "48.45.194.186" + key_id: 34 + prefer: true + version: 2 + source_addresses: + - source_address: "172.45.194.186" + routing_instance: 'rt1' + - source_address: "171.45.194.186" + routing_instance: 'rt2' + threshold: + value: 300 + action: "accept" + trusted_keys: + - key_id: 3000 + - key_id: 2000 + state: rendered + register: rendered_result + + - name: Assert rendered result + assert: + that: + - rendered_result.rendered is defined + + - name: Parse NTP global config + junipernetworks.junos.junos_ntp_global: + running_config: "{{ lookup('file', 'parsed_configs/parsed_ntp_global.cfg') }}" + state: parsed + register: parsed_result + + - name: Assert parsed result + assert: + that: + - parsed_result is defined + - parsed_result.parsed is defined \ No newline at end of file diff --git a/tests/junipernetworks.junos/pb.juniper_junos_ospf_interfaces.yml b/tests/junipernetworks.junos/pb.juniper_junos_ospf_interfaces.yml new file mode 100644 index 00000000..82d667a9 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_ospf_interfaces.yml @@ -0,0 +1,141 @@ +- name: Functional Test - junos_ospf_interfaces module + hosts: junos_device + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + - name: Pre-clean - Delete existing OSPF interface config + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: "ge-0/0/2.0" + state: deleted + register: deleted_result + + - name: Assert deleted result + assert: + that: + - deleted_result is succeeded + + - name: Apply OSPF interface config using merged + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: "ge-0/0/2.0" + address_family: + - afi: "ipv4" + processes: + area: + area_id: "0.0.0.2" + metric: 5 + priority: 3 + state: merged + register: merged_result + + - name: Assert merged result + assert: + that: + - merged_result.changed == true + + - name: Replace OSPF interface 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" + metric: 6 + priority: 6 + state: replaced + register: replaced_result + + - name: Assert replaced result + assert: + that: + - replaced_result.changed == true + + - name: Override OSPF interface config + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: so-0/0/0.0 + router_id: 10.200.16.75 + address_family: + - afi: ipv4 + processes: + area: + area_id: 0.0.0.110 + bandwidth_based_metrics: + - bandwidth: 1g + metric: 5 + - bandwidth: 10g + metric: 40 + metric: 5 + priority: 3 + passive: true + - name: ge-0/0/2.0 + router_id: 10.200.16.75 + address_family: + - afi: ipv4 + processes: + area: + area_id: 0.0.0.3 + metric: 7 + priority: 4 + state: overridden + register: overridden_result + + + - name: Assert overridden result + assert: + that: + - overridden_result.changed == true + + - name: Delete specific OSPF interface config + junipernetworks.junos.junos_ospf_interfaces: + config: + - name: "ge-0/0/1.0" + state: deleted + register: deleted_specific_result + + - name: Gather OSPF interfaces config + junipernetworks.junos.junos_ospf_interfaces: + state: gathered + register: gathered_result + + - name: Assert gathered result + assert: + that: + - gathered_result.gathered is defined + + - name: Render 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" + metric: 5 + priority: 3 + state: rendered + register: rendered_result + + - name: Assert rendered output + assert: + that: + - rendered_result.rendered is defined + + + - name: Parse OSPF interfaces running config + junipernetworks.junos.junos_ospf_interfaces: + running_config: "{{ lookup('file', 'parsed_configs/parsed_ospf_interfaces.cfg') }}" + state: parsed + register: parsed_result + + - name: Assert parsed output + assert: + that: + - parsed_result.parsed is defined diff --git a/tests/junipernetworks.junos/pb.juniper_junos_ospfv2.yml b/tests/junipernetworks.junos/pb.juniper_junos_ospfv2.yml new file mode 100644 index 00000000..d3b8c810 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_ospfv2.yml @@ -0,0 +1,181 @@ +- name: Functional Test - junos_ospfv2 module + hosts: junos_device + gather_facts: false + connection: ansible.netcommon.netconf + + tasks: + + - name: DELETE - Reset before MERGED + junipernetworks.junos.junos_ospfv2: + config: [] + state: deleted + + - name: MERGED - Configure OSPFv2 instance + junipernetworks.junos.junos_ospfv2: + config: + - reference_bandwidth: 10g + areas: + - area_id: 0.0.0.100 + area_ranges: + - address: 10.200.17.0/24 + exact: true + restrict: true + override_metric: 2000 + - address: 10.200.15.0/24 + exact: true + restrict: true + override_metric: 2000 + stub: + default_metric: 100 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: false + passive: true + bandwidth_based_metrics: + - bandwidth: 1g + metric: 5 + - bandwidth: 10g + metric: 40 + timers: + dead_interval: 4 + hello_interval: 2 + poll_interval: 2 + retransmit_interval: 2 + rfc1583compatibility: false + state: merged + + - name: DELETE - Reset before REPLACED + junipernetworks.junos.junos_ospfv2: + config: [] + state: deleted + + - name: REPLACED - Replace OSPFv2 instance + 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: replaced + + - name: DELETE - Reset before OVERRIDDEN + junipernetworks.junos.junos_ospfv2: + config: [] + state: deleted + + - name: OVERRIDDEN - Override OSPFv2 instance + 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 + + - name: RENDERED - Render OSPFv2 config + junipernetworks.junos.junos_ospfv2: + config: + - reference_bandwidth: 10g + areas: + - area_id: 0.0.0.100 + area_ranges: + - address: 10.200.17.0/24 + exact: true + restrict: true + override_metric: 2000 + - address: 10.200.15.0/24 + exact: true + restrict: true + override_metric: 2000 + stub: + default_metric: 100 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: false + passive: true + bandwidth_based_metrics: + - bandwidth: 1g + metric: 5 + - bandwidth: 10g + metric: 40 + timers: + dead_interval: 4 + hello_interval: 2 + poll_interval: 2 + retransmit_interval: 2 + state: rendered + + - name: GATHERED - Get current OSPFv2 config + junipernetworks.junos.junos_ospfv2: + config: [] + state: gathered + register: ospf_gather + + - name: Show GATHERED + ansible.builtin.debug: + var: ospf_gather.gathered + + - name: PARSED - Parsed ospfv2 config from XML + junipernetworks.junos.junos_ospfv2: + running_config: "{{ lookup('file', './parsed_configs/parsed_ospfv2.cfg') }}" + state: parsed + register: ospf_parsed + + - name: Show PARSED + ansible.builtin.debug: + var: ospf_parsed.parsed diff --git a/tests/junipernetworks.junos/pb.juniper_junos_ospfv3.yml b/tests/junipernetworks.junos/pb.juniper_junos_ospfv3.yml new file mode 100644 index 00000000..20ed913f --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_ospfv3.yml @@ -0,0 +1,88 @@ +- name: Functional Test - junos_ospfv3 module + hosts: junos_device + gather_facts: false + connection: ansible.netcommon.netconf + + tasks: + - name: DELETE - Reset before test + junipernetworks.junos.junos_ospfv3: + config: [] + state: deleted + + - name: MERGED - Merge Junos OSPFv3 config + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - metric: 5 + name: so-0/0/0.0 + priority: 3 + - metric: 6 + name: so-0/0/1.0 + priority: 2 + stub: + default_metric: 200 + set: true + state: merged + + - name: REPLACED - Replace Junos OSPFv3 config + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + interfaces: + - name: so-0/0/0.0 + state: replaced + + - name: OVERRIDDEN - Override Junos OSPFv3 config + junipernetworks.junos.junos_ospfv3: + config: + - router_id: 10.200.16.75 + areas: + - area_id: 0.0.0.100 + stub: + default_metric: 200 + set: true + interfaces: + - name: so-0/0/0.0 + priority: 3 + metric: 5 + flood_reduction: true + passive: true + - area_id: 0.0.0.200 + interfaces: + - name: ge-1/1/0.0 + - name: ge-2/2/0.0 + state: overridden + + - name: GATHERED - Get current OSPFv3 configuration + junipernetworks.junos.junos_ospfv3: + config: [] + state: gathered + register: gathered_ospfv3 + + - name: PARSED - Parse structured config from XML file + junipernetworks.junos.junos_ospfv3: + running_config: "{{ lookup('file', './parsed_configs/parsed_ospfv3.cfg') }}" + state: parsed + + - name: RENDERED - Render OSPFv3 config into XML + 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 diff --git a/tests/junipernetworks.junos/pb.juniper_junos_package.yml b/tests/junipernetworks.junos/pb.juniper_junos_package.yml new file mode 100644 index 00000000..9c508742 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_package.yml @@ -0,0 +1,63 @@ +- name: Functional Test - junos_package module + hosts: localhost + gather_facts: false + collections: + - junipernetworks.junos + + tasks: + + - name: Install local package on remote device + junipernetworks.junos.junos_package: + src: "{{ package_src }}" + reboot: true + provider: + host: xx.xx.xx.xx + username: xx + password: xx + port: 830 + transport: netconf + register: result_install + + - name: Wait for device to come back online after reboot (TCP check) + wait_for: + host: xx.xx.xx.xx + port: 830 + delay: 30 + timeout: 300 + + - name: Wait until NETCONF service is ready (SSH banner check) + wait_for: + host: xx.xx.xx.xx + port: 830 + search_regex: "SSH" + timeout: 300 + delay: 10 + sleep: 5 + register: wait_result + until: wait_result is succeeded + retries: 10 + delay: 10 + + - name: Assert install task ran + assert: + that: + - result_install is defined + + - name: Install local package without reboot + junipernetworks.junos.junos_package: + src: /tmp/junos-vsrx-12.1X46-D10.2-domestic.tgz + reboot: false + provider: + host: xx.xx.xx.xx + username: xxx + password: xxx + port: 830 + transport: netconf + register: result_noreboot + + - name: Assert no-reboot task ran + assert: + that: + - result_noreboot is defined + + diff --git a/tests/junipernetworks.junos/pb.juniper_junos_ping.yml b/tests/junipernetworks.junos/pb.juniper_junos_ping.yml new file mode 100644 index 00000000..315571b8 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_ping.yml @@ -0,0 +1,67 @@ +- name: Functional Test - junos_ping module + hosts: network_cli_testcases + gather_facts: false + connection: network_cli + collections: + - junipernetworks.junos + + tasks: + + - name: Test reachability to target + junipernetworks.junos.junos_ping: + dest: xx.xx.xx.xx + register: ping_default + + - name: Assert default ping worked + assert: + that: + - ping_default.packet_loss is defined + + - name: Test reachability to target using source and size set + junipernetworks.junos.junos_ping: + dest: xx.xx.xx.xx + size: 1024 + ttl: 128 + register: ping_source_ttl + + - name: Assert source TTL ping worked + assert: + that: + - ping_source_ttl.packet_loss is defined + + - name: Test unreachability to target using interval + junipernetworks.junos.junos_ping: + dest: xx.xx.xx.xx + interval: 3 + state: present + register: ping_absent + + - name: "Assert unreachable ping worked (state: absent)" + assert: + that: + - ping_absent.packet_loss is defined + + - name: Test reachability to target setting count and interface + junipernetworks.junos.junos_ping: + dest: xx.xx.xx.xx + interface: fxp0 + count: 20 + size: 512 + register: ping_iface + + - name: Assert ping with count/interface worked + assert: + that: + - ping_iface.packet_loss is defined + + - name: Test reachability to target using do-not-fragment and rapid + junipernetworks.junos.junos_ping: + dest: xx.xx.xx.xx + df_bit: true + rapid: true + register: ping_df_rapid + + - name: Assert ping with DF bit and rapid worked + assert: + that: + - ping_df_rapid.packet_loss is defined diff --git a/tests/junipernetworks.junos/pb.juniper_junos_prefix_lists.yml b/tests/junipernetworks.junos/pb.juniper_junos_prefix_lists.yml new file mode 100644 index 00000000..95fca784 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_prefix_lists.yml @@ -0,0 +1,118 @@ +- name: Functional Test - junos_prefix_lists module + hosts: junos_device + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + - name: Pre-clean - Delete all prefix-lists if present + junos_prefix_lists: + state: deleted + ignore_errors: true + + - name: Apply prefix-lists using merged + junos_prefix_lists: + config: + - name: Internal + address_prefixes: + - 172.16.1.32 + - 172.16.3.32 + - name: Test1 + dynamic_db: true + - name: Test2 + address_prefixes: + - 172.16.2.32 + - 172.16.7.32 + - 172.16.9.32 + state: merged + register: merged_result + + - name: Assert merged result + assert: + that: + - merged_result.changed == true + + - name: Gather prefix-lists + junos_prefix_lists: + state: gathered + register: gathered_result + + - name: Assert gathered prefix-lists + assert: + that: + - gathered_result.gathered is defined + - gathered_result.gathered | length > 0 + + - name: Replace prefix-list Test2 with new prefixes + junos_prefix_lists: + config: + - name: Test2 + address_prefixes: + - 172.16.4.32 + - 172.16.8.32 + - 172.16.9.32 + state: replaced + register: replaced_result + + - name: Assert replaced result + assert: + that: + - replaced_result.changed == true + + - name: Override prefix-lists with only Test2 entries + 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 + register: overridden_result + + - name: Assert overridden result + assert: + that: + - overridden_result.changed == true + + - name: Render prefix-lists offline + junos_prefix_lists: + config: + - name: Internal + address_prefixes: + - 172.16.1.32 + - 172.16.3.32 + - name: Test1 + dynamic_db: true + - name: Test2 + address_prefixes: + - 172.16.2.32 + - 172.16.7.32 + - 172.16.9.32 + state: rendered + register: rendered_result + + - name: Assert rendered output + assert: + that: + - rendered_result.rendered is defined + - rendered_result.rendered | length > 0 + + - name: Post-clean - Delete specific prefix-lists + junos_prefix_lists: + config: + - name: Test1 + - name: Test2 + state: deleted + register: deleted_result + + - name: Assert deleted specific prefix-lists + assert: + that: + - deleted_result.changed == true + + - name: Final clean - Delete all prefix-lists + junos_prefix_lists: + state: deleted + ignore_errors: true diff --git a/tests/junipernetworks.junos/pb.juniper_junos_routing_instances.yml b/tests/junipernetworks.junos/pb.juniper_junos_routing_instances.yml new file mode 100644 index 00000000..710e7f53 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_routing_instances.yml @@ -0,0 +1,146 @@ +- name: Functional Test - junos_routing_instances module + hosts: junos_device + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + + - name: Pre-clean - Create required policy statements + junipernetworks.junos.junos_config: + lines: + - set policy-options policy-statement test-policy term t1 then reject + - set policy-options policy-statement test-policy-1 term t1 then reject + comment: "Pre-create dummy policies needed for routing instances FT" + + - name: Pre-clean - Delete test routing instances + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + - name: "forwardinst" + - name: "vtest1" + state: deleted + + - name: Apply routing instances using merged + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.58.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + - "test-policy-1" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: true + - name: "forwardinst" + type: "forwarding" + description: "Configured by Ansible Content Team" + state: merged + register: merged_result + + - name: Assert merged result + assert: + that: + - merged_result.changed == true + + - name: Gather routing instances + junipernetworks.junos.junos_routing_instances: + state: gathered + register: gathered_result + + - name: Assert gathered result + assert: + that: + - gathered_result.gathered is defined + + - name: Replace routing instance configuration + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + type: "vrf" + route_distinguisher: "10.57.255.1:37" + vrf_imports: + - "test-policy" + vrf_exports: + - "test-policy" + interfaces: + - name: "sp-0/0/0.0" + - name: "gr-0/0/0.0" + connector_id_advertise: false + description: "Configured by Ansible Content Team" + state: replaced + register: replaced_result + + - name: Assert replaced result + assert: + that: + - replaced_result.changed == true + + + + - name: Delete specific routing instance + junipernetworks.junos.junos_routing_instances: + config: + - name: "test" + state: deleted + register: delete_specific_result + + - name: Assert specific routing instance deleted + assert: + that: + - delete_specific_result.changed == true + + - name: Final clean - Delete test routing instances only + junipernetworks.junos.junos_routing_instances: + config: + - name: "forwardinst" + - name: "vtest1" + state: deleted + register: delete_all_result + + - name: Assert all routing instances deleted + assert: + that: + - delete_all_result.changed == true + + - name: Render 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" + state: rendered + register: rendered_result + + - name: Assert rendered configuration + assert: + that: + - rendered_result.rendered is defined + + - name: Parse routing instance running configuration + junipernetworks.junos.junos_routing_instances: + running_config: "{{ lookup('file', 'parsed_configs/parsed_routing_instances.cfg') }}" + state: parsed + register: parsed_result + + - name: Assert parsed result + assert: + that: + - parsed_result.parsed is defined diff --git a/tests/junipernetworks.junos/pb.juniper_junos_routing_options.yml b/tests/junipernetworks.junos/pb.juniper_junos_routing_options.yml new file mode 100644 index 00000000..71e4157b --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_routing_options.yml @@ -0,0 +1,105 @@ +- name: Functional Test - junos_routing_options module + hosts: junos_device + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + + - name: Pre-clean - Delete existing routing options + junipernetworks.junos.junos_routing_options: + config: {} + state: deleted + + - name: Apply routing options using merged + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + state: merged + register: merged_result + + - name: Assert merged result + assert: + that: + - merged_result.changed == true + + - name: Gather routing options + junipernetworks.junos.junos_routing_options: + state: gathered + register: gathered_result + + - name: Assert gathered result + assert: + that: + - gathered_result.gathered is defined + + - name: Replace routing options configuration + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + router_id: "1.1.1.1" + state: replaced + register: replaced_result + + - name: Assert replaced result + assert: + that: + - replaced_result.changed == true + + - name: Override routing options configuration + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + router_id: "2.2.2.2" + state: overridden + register: overridden_result + + - name: Assert overridden result + assert: + that: + - overridden_result.changed == true + + - name: Render routing options configuration + junipernetworks.junos.junos_routing_options: + config: + autonomous_system: + as_number: 2 + asdot_notation: true + loops: 4 + router_id: "12.12.12.12" + state: rendered + register: rendered_result + + - name: Assert rendered configuration + assert: + that: + - rendered_result.rendered is defined + + - name: Parse routing options running configuration + junipernetworks.junos.junos_routing_options: + running_config: "{{ lookup('file', 'parsed_configs/parsed_routing_options.cfg') }}" + state: parsed + register: parsed_result + + - name: Assert parsed result + assert: + that: + - parsed_result.parsed is defined + + - name: Final clean - Delete all routing options + junipernetworks.junos.junos_routing_options: + config: {} + state: deleted + register: delete_result + + - name: Assert routing options deleted + assert: + that: + - delete_result.changed == true diff --git a/tests/junipernetworks.junos/pb.juniper_junos_rpc.yml b/tests/junipernetworks.junos/pb.juniper_junos_rpc.yml new file mode 100644 index 00000000..956f13e8 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_rpc.yml @@ -0,0 +1,48 @@ +- name: Functional Test - junos_rpc module + hosts: netconf_connection_testcases + gather_facts: false + connection: ansible.netcommon.netconf + collections: + - junipernetworks.junos + + tasks: + + - name: Collect interface information using RPC + junipernetworks.junos.junos_rpc: + rpc: get-interface-information + args: + interface-name: em0 + media: true + register: interface_info + + - name: Assert interface information RPC returned XML + assert: + that: + - interface_info.xml is defined + + - name: Get system information using RPC + junipernetworks.junos.junos_rpc: + rpc: get-system-information + register: system_info + + - name: Assert system information RPC returned XML + assert: + that: + - system_info.xml is defined + + - name: Load configuration using RPC (requires file on device) + junipernetworks.junos.junos_rpc: + rpc: load-configuration + attrs: + action: override + format: text + url: /tmp/config.conf + register: config_load + when: false + + - name: Assert load configuration RPC executed + assert: + that: + - config_load.xml is defined + when: false + diff --git a/tests/junipernetworks.junos/pb.juniper_junos_security_policies.yml b/tests/junipernetworks.junos/pb.juniper_junos_security_policies.yml new file mode 100644 index 00000000..bf1b3ca7 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_security_policies.yml @@ -0,0 +1,27 @@ +- name: Functional Test - junos_security_policies (parsed and rendered only) + hosts: junos_device + gather_facts: no + connection: ansible.netcommon.netconf + + tasks: + - name: Render security policy config + junipernetworks.junos.junos_security_policies: + config: + global: + policies: + - name: test_glob_1 + match: + application: + any: true + source_address: + any_ipv6: true + destination_address: + any_ipv6: true + then: + deny: true + state: rendered + + - name: Parse from saved running config + junipernetworks.junos.junos_security_policies: + running_config: "{{ lookup('file', './parsed_configs/parsed_security_policies.cfg') }}" + state: parsed diff --git a/tests/junipernetworks.junos/pb.juniper_junos_security_policies_global.yml b/tests/junipernetworks.junos/pb.juniper_junos_security_policies_global.yml new file mode 100644 index 00000000..ec835f3f --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_security_policies_global.yml @@ -0,0 +1,37 @@ +- name: Functional Test - junos_security_policies_global (parsed, rendered, gathered) + hosts: junos_device + gather_facts: no + connection: netconf + + tasks: + + - name: PARSED - Parse running config from local file + junipernetworks.junos.junos_security_policies_global: + running_config: "{{ lookup('file', './parsed_configs/parsed_security_policies_global.cfg') }}" + state: parsed + + - name: RENDERED - Render the provided config + junipernetworks.junos.junos_security_policies_global: + config: + default_policy: deny-all + policy_rematch: + enable: true + policy_stats: + enable: true + pre_id_default_policy_action: + log: + session_init: true + session_timeout: + icmp: 10 + others: 10 + traceoptions: + file: + files: 4 + match: /[A-Z]*/gm + size: 10k + no_world_readable: true + flag: all + no_remote_trace: true + state: rendered + + diff --git a/tests/junipernetworks.junos/pb.juniper_junos_security_zones.yml b/tests/junipernetworks.junos/pb.juniper_junos_security_zones.yml new file mode 100644 index 00000000..919e8314 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_security_zones.yml @@ -0,0 +1,41 @@ +- name: Functional Test - junos_security_zones module + hosts: junos_device + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + + - name: Render Security Zone config to XML + junipernetworks.junos.junos_security_zones: + config: + zones: + - name: trust + description: "Trusted zone" + interfaces: + - ge-0/0/1.0 + host_inbound_traffic: + system_services: + - name: ssh + - name: ping + state: rendered + register: result_rendered + + - name: Assert rendered output + assert: + that: + - result_rendered.rendered is defined + - result_rendered.changed == false + + - name: Parse Security Zone config from file + junipernetworks.junos.junos_security_zones: + running_config: "{{ lookup('file', 'parsed_configs/parsed_security_zones.cfg') }}" + state: parsed + register: result_parsed + + - name: Assert parsed zone config + assert: + that: + - result_parsed.parsed is defined + - result_parsed.changed == false diff --git a/tests/junipernetworks.junos/pb.juniper_junos_snmp_server.yml b/tests/junipernetworks.junos/pb.juniper_junos_snmp_server.yml new file mode 100644 index 00000000..94543acb --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_snmp_server.yml @@ -0,0 +1,130 @@ +- name: Functional Test - junos_snmp_server (all states) + hosts: netconf_connection_testcases + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + - name: Render SNMP server configuration (dry-run XML) + junipernetworks.junos.junos_snmp_server: + config: + arp: + set: true + host_name_resolution: true + routing_instance_access: + set: true + access_lists: + - clv1 + - clv2 + state: rendered + register: result_rendered + + - name: Assert rendered SNMP config + assert: + that: + - result_rendered.rendered is defined + - result_rendered.changed == false + + - name: Parse SNMP server config from XML + junipernetworks.junos.junos_snmp_server: + running_config: "{{ lookup('file', 'parsed_configs/parsed_snmp.cfg') }}" + state: parsed + register: result_parsed + + - name: Assert parsed SNMP config + assert: + that: + - result_parsed.parsed is defined + - result_parsed.changed == false + + - name: Merge SNMP server configuration (may fail if RI clv1/clv2 don't exist) + junipernetworks.junos.junos_snmp_server: + config: + arp: + set: true + host_name_resolution: true + client_lists: + - name: cl1 + addresses: + - address: "192.16.1.0/24" + - address: "192.16.2.0/24" + - address: "11.11.11.11" + restrict: true + - name: cl2 + addresses: + - address: "192.16.4.0/24" + routing_instance_access: + set: true + access_lists: + - clv1 + - clv2 + state: merged + register: result_merge + ignore_errors: true # Skip if routing instances clv1/clv2 are not present + + - name: Replace SNMP server configuration + junipernetworks.junos.junos_snmp_server: + config: + contact: "ansiblesupport11@redhat.com" + customization: + ether_stats_ifd_only: true + description: "Local SNMP Server" + engine_id: + local: "local1" + use_default_ip_address: true + use_mac_address: true + filter_duplicates: true + filter_interfaces: + set: true + all_internal_interfaces: true + interfaces: + - eth1 + - eth2 + state: replaced + register: result_replaced + + - name: Override SNMP server configuration + junipernetworks.junos.junos_snmp_server: + config: + contact: "ansiblesupport11@redhat.com" + customization: + ether_stats_ifd_only: true + description: "Local SNMP Server" + engine_id: + local: "local1" + use_default_ip_address: true + use_mac_address: true + filter_duplicates: true + filter_interfaces: + set: true + all_internal_interfaces: true + interfaces: + - eth1 + - eth2 + state: overridden + register: result_overridden + + - name: Gather SNMP server configuration from device + junipernetworks.junos.junos_snmp_server: + state: gathered + register: result_gathered + + - name: Assert gathered SNMP config + assert: + that: + - result_gathered.gathered is defined + - result_gathered.changed == false + + - name: Delete SNMP server configuration + junipernetworks.junos.junos_snmp_server: + config: {} + state: deleted + register: result_deleted + + - name: Assert config states + assert: + that: + - result_replaced.changed is defined + - result_overridden.changed is defined + - result_deleted.changed is defined diff --git a/tests/junipernetworks.junos/pb.juniper_junos_static_routes.yml b/tests/junipernetworks.junos/pb.juniper_junos_static_routes.yml new file mode 100644 index 00000000..373e6326 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_static_routes.yml @@ -0,0 +1,33 @@ +- name: Functional Test - junos_static_routes (safe states only) + hosts: netconf_connection_testcases + connection: netconf + gather_facts: no + + tasks: + + - name: 1. Render static route config for 192.168.16.0/24 โ†’ 172.16.1.2 + junipernetworks.junos.junos_static_routes: + config: + - vrf: default + address_families: + - afi: ipv4 + routes: + - dest: 192.168.16.0/24 + next_hop: + - forward_router_address: 172.16.1.2 + state: rendered + register: rendered_output + + - name: Debug rendered config + debug: + var: rendered_output.rendered + + - name: 2. Parse running config from parsed_static_routes.cfg + junipernetworks.junos.junos_static_routes: + running_config: "{{ lookup('file', 'parsed_configs/parsed_static_routes.cfg') }}" + state: parsed + register: parsed_output + + - name: Debug parsed output + debug: + var: parsed_output.parsed diff --git a/tests/junipernetworks.junos/pb.juniper_junos_system.yml b/tests/junipernetworks.junos/pb.juniper_junos_system.yml new file mode 100644 index 00000000..ad001c8f --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_system.yml @@ -0,0 +1,73 @@ +- name: Functional Test - junos_system module + hosts: junos_device + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + + - name: Pre-clean - Remove system configuration + junipernetworks.junos.junos_system: + hostname: junos01 + domain_name: test.example.com + domain_search: + - ansible.com + - redhat.com + - juniper.net + name_servers: + - 8.8.8.8 + - 8.8.4.4 + state: absent + register: preclean_result + + - name: Assert pre-clean result + assert: + that: + - preclean_result is not failed + + - name: Configure hostname, domain name, and domain search + junipernetworks.junos.junos_system: + hostname: junos01 + domain_name: test.example.com + domain_search: + - ansible.com + - redhat.com + - juniper.net + register: configure_hostname_domain + + - name: Assert hostname and domain name configured + assert: + that: + - configure_hostname_domain.changed == true + + - name: Configure name servers + junipernetworks.junos.junos_system: + name_servers: + - 8.8.8.8 + - 8.8.4.4 + register: configure_nameservers + + - name: Assert name servers configured + assert: + that: + - configure_nameservers.changed == true + + - name: Cleanup - Remove system configuration + junipernetworks.junos.junos_system: + hostname: junos01 + domain_name: test.example.com + domain_search: + - ansible.com + - redhat.com + - juniper.net + name_servers: + - 8.8.8.8 + - 8.8.4.4 + state: absent + register: cleanup_result + + - name: Assert final clean-up + assert: + that: + - cleanup_result.changed == true diff --git a/tests/junipernetworks.junos/pb.juniper_junos_vlans.yml b/tests/junipernetworks.junos/pb.juniper_junos_vlans.yml new file mode 100644 index 00000000..6e331a3f --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_vlans.yml @@ -0,0 +1,49 @@ + +- name: Functional Test - junos_vlans (read-only states) + hosts: netconf_connection_testcases + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + + - name: Render VLAN configuration (dry-run XML) + junipernetworks.junos.junos_vlans: + config: + - name: vlan1 + vlan_id: 1 + - name: vlan2 + vlan_id: 2 + l3_interface: irb.12 + state: rendered + register: result_rendered + + - name: Assert rendered VLAN config + assert: + that: + - result_rendered.rendered is defined + - result_rendered.changed == false + + - name: Gather VLAN configuration from device + junipernetworks.junos.junos_vlans: + state: gathered + register: result_gathered + + - name: Assert gathered VLAN config + assert: + that: + - result_gathered.gathered is defined + - result_gathered.changed == false + + - name: Parse VLAN config from XML file + junipernetworks.junos.junos_vlans: + running_config: "{{ lookup('file', 'parsed_configs/parsed_junos_vlans.cfg') }}" + state: parsed + register: result_parsed + + - name: Assert parsed VLAN config + assert: + that: + - result_parsed.parsed is defined + - result_parsed.changed == false diff --git a/tests/junipernetworks.junos/pb.juniper_junos_vrf.yml b/tests/junipernetworks.junos/pb.juniper_junos_vrf.yml new file mode 100644 index 00000000..1af69e1a --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_vrf.yml @@ -0,0 +1,69 @@ +- name: Functional Test - junos_vrf module + hosts: junos_device + gather_facts: false + connection: netconf + collections: + - junipernetworks.junos + + tasks: + - name: Pre-clean conflicting routing-instances + junipernetworks.junos.junos_config: + lines: + - delete routing-instances test-1 + - delete routing-instances test-2 + comment: "Cleanup existing VRFs" + + - name: Preconfigure required interfaces + junipernetworks.junos.junos_config: + lines: + - set interfaces ge-0/0/2.0 family inet address 192.0.2.2/24 + - set interfaces ge-0/0/3.0 family inet address 192.0.2.3/24 + - set interfaces ge-0/0/4.0 family inet address 192.0.2.4/24 + - set interfaces ge-0/0/5.0 family inet address 192.0.2.5/24 + comment: "Ensure full logical units configured" + + - name: Deactivate VRF test-1 + junipernetworks.junos.junos_vrf: + name: test-1 + active: false + rd: 192.0.2.1:10 + target: target:65514:113 + interfaces: + - ge-0/0/3.0 + - ge-0/0/2.0 + description: test-vrf-1 + register: deactivate_result + + - name: Assert VRF test-1 deactivated + assert: + that: deactivate_result.changed == true + + - name: Remove VRF test-1 + junipernetworks.junos.junos_vrf: + name: test-1 + description: test-vrf-1 + interfaces: + - ge-0/0/3.0 + - ge-0/0/2.0 + rd: 192.0.2.1:10 + target: target:65514:113 + state: absent + register: remove_test1 + + - name: Assert VRF test-1 removed + assert: + that: remove_test1.changed == true + + - name: Remove VRF test-2 + junipernetworks.junos.junos_vrf: + name: test-2 + description: test-vrf-2 + interfaces: + - ge-0/0/4.0 + - ge-0/0/5.0 + rd: 192.0.2.2:10 + target: target:65515:114 + state: absent + register: remove_test2 + + diff --git a/tests/junipernetworks.junos/run_all_tests.sh b/tests/junipernetworks.junos/run_all_tests.sh new file mode 100755 index 00000000..70a09558 --- /dev/null +++ b/tests/junipernetworks.junos/run_all_tests.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +echo "Starting execution of all Ansible Junos playbooks..." +echo "-----------------------------------------------------" + +# File to store passed test logs +PASS_LOG="junos_passed_tests.log" +> "$PASS_LOG" # Clear previous contents + +# Loop through all *.yml playbooks +for file in pb.juniper_junos_*.yml; do + echo "Running $file" + ansible-playbook -i inventory "$file" + status=$? + + if [ $status -ne 0 ]; then + echo "โŒ $file failed with status $status" + else + echo "โœ… $file completed successfully" + echo "$file PASSED at $(date)" >> "$PASS_LOG" + fi + + echo "-----------------------------------------------------" +done + +echo "All playbooks processed." +echo "Passed test results saved to $PASS_LOG" From d2f7a2877c0146c30c24458cf51192436aec9d36 Mon Sep 17 00:00:00 2001 From: Brij Tarkhala Date: Tue, 13 May 2025 18:41:19 +0530 Subject: [PATCH 3/4] Add functional tests for Juniper Ansible modules --- tests/pb.juniper_junos_command.yml | 44 ++++++++ tests/pb.juniper_junos_config.yml | 150 ++++++++++++++++++++----- tests/pb.juniper_junos_facts.yml | 45 ++++++++ tests/pb.juniper_junos_file.yml | 33 ++++++ tests/pb.juniper_junos_jsnapy.yml | 92 +++++++++++++++ tests/pb.juniper_junos_ping.yml | 72 +++++++++++- tests/pb.juniper_junos_pmtud.yml | 53 +++++++++ tests/pb.juniper_junos_rpc.yml | 128 ++++++++++++++++++++- tests/pb.juniper_junos_software.yml | 3 + tests/pb.juniper_junos_srx_cluster.yml | 51 ++++++++- tests/pb.juniper_junos_system.yml | 119 +++++++++++++++++++- tests/pb.juniper_junos_table.yml | 2 + 12 files changed, 751 insertions(+), 41 deletions(-) diff --git a/tests/pb.juniper_junos_command.yml b/tests/pb.juniper_junos_command.yml index d51c1725..6c307835 100644 --- a/tests/pb.juniper_junos_command.yml +++ b/tests/pb.juniper_junos_command.yml @@ -140,3 +140,47 @@ - test8.results[0].msg == "The command executed successfully." - test8.results[1].command == "show version" - test8.results[1].msg == "The command executed successfully." + + + - name: TEST 9 - Multi-command text output + juniper.device.command: + commands: + - "show system uptime" + - "show version" + formats: + - "text" + - "text" + register: test9 + + - name: Check TEST 9 - Ensure output for both commands exists + ansible.builtin.assert: + that: + - test9.results[0].stdout is defined + - test9.results[1].stdout is defined + + - name: Ensure output directory exists + ansible.builtin.file: + path: "{{ playbook_dir }}/out" + state: directory + mode: '0755' + delegate_to: localhost + run_once: true + + - name: TEST 10 - Save text output of commands to dest_dir + juniper.device.command: + commands: + - "show version" + - "show interfaces terse" + format: text + dest_dir: "{{ playbook_dir }}/out" + register: test12 + + - name: Check TEST 10 - Command execution status + ansible.builtin.assert: + that: + - test12.results[0].msg == "The command executed successfully." + - test12.results[1].msg == "The command executed successfully." + + + + \ No newline at end of file diff --git a/tests/pb.juniper_junos_config.yml b/tests/pb.juniper_junos_config.yml index a7021f54..b1e550e7 100644 --- a/tests/pb.juniper_junos_config.yml +++ b/tests/pb.juniper_junos_config.yml @@ -4,8 +4,8 @@ gather_facts: false tasks: -################ - - name: Retrieve the committed configuration + + - name: TEST 1 - Retrieve the committed configuration juniper.device.config: retrieve: 'committed' diff: false @@ -19,8 +19,8 @@ ansible.builtin.assert: that: - test1.config -################ - - name: Append .foo to the hostname using private config mode. + + - name: TEST 2 - Append .foo to the hostname using private config mode. juniper.device.config: config_mode: 'private' load: 'merge' @@ -35,8 +35,8 @@ ansible.builtin.assert: that: - test2.diff_lines -################ - - name: Rollback to the previous config. + + - name: TEST 3 - Rollback to the previous config. juniper.device.config: config_mode: 'private' rollback: 1 @@ -48,12 +48,11 @@ ansible.builtin.assert: that: - test3.diff_lines -################# + - name: Save rescue configuration juniper.device.command: commands: "request system configuration rescue save" - formats: - - "xml" + formats: ["xml"] - name: Configure syslog configuration juniper.device.config: @@ -62,20 +61,22 @@ - "set system syslog file TEST any any" comment: "Configured system services" - - name: Rollback to the rescue config. + - name: Rollback to the rescue config juniper.device.config: rollback: 'rescue' register: test4 + - name: Check TEST 4 ansible.builtin.assert: that: - test4.diff_lines + - name: Clean up TEST 4 ansible.builtin.file: path: out state: absent -############### - - name: Configure system services. + + - name: Configure system services juniper.device.config: config_mode: 'private' load: 'merge' @@ -83,7 +84,7 @@ - "set system services netconf ssh" comment: "Configured system services" - - name: Retrieve [edit system services] of current committed config. + - name: TEST 5 - Retrieve [edit system services] of current committed config juniper.device.config: retrieve: 'committed' filter: 'system/services' @@ -97,11 +98,10 @@ - name: Check TEST 5 ansible.builtin.assert: that: - - test5.failed == False + - test5.failed == false - "'system {' in test5.config_lines" -################# - - name: Confirm the previous commit with a commit check (but no commit) + - name: TEST 6 - Confirm the previous commit with a commit check (no commit) juniper.device.config: check: true diff: false @@ -111,11 +111,9 @@ - name: Check TEST 6 ansible.builtin.assert: that: - test6.changed == False + - test6.changed == false -################# - - - name: Confirm the commit with a commit sync + - name: TEST 7 - Confirm the commit with a commit sync juniper.device.config: check: true diff: false @@ -126,11 +124,9 @@ - name: Check TEST 7 ansible.builtin.assert: that: - - test7.changed == False - -################# + - test7.changed == false - - name: Confirm the commit with a commit sync force + - name: TEST 8 - Confirm the commit with a commit sync force juniper.device.config: check: true diff: false @@ -141,20 +137,114 @@ - name: Check TEST 8 ansible.builtin.assert: that: - test8.changed == False -################ - - name: Test commit timeout . + - test8.changed == false + + - name: TEST 2 Repeat - Commit with timeout juniper.device.config: load: 'merge' lines: - "set system host-name {{ inventory_hostname }}.foo" comment: "Append .foo to the hostname" timeout: 300 - register: test2 + register: test2b ignore_errors: true tags: [test2] - - name: Check TEST 2 + - name: Check TEST 2b ansible.builtin.assert: that: - - test2.diff_lines + - test2b.diff_lines + + - name: TEST 9 - Diff between rollback 11 and current + juniper.device.config: + rollback: 11 + diff: true + check: false + commit: false + register: test_rollback_diff + + - name: Check TEST 9 - Rollback diff task executed successfully + ansible.builtin.assert: + that: + - test_rollback_diff.failed is not defined or test_rollback_diff.failed == false + + - name: Ensure output directory exists for TEST 10 + ansible.builtin.file: + path: "{{ playbook_dir }}/output" + state: directory + mode: '0755' + run_once: true + delegate_to: localhost + + - name: TEST 10 - Retrieve using XML filter and save to dest_dir + juniper.device.config: + retrieve: 'committed' + format: 'xml' + commit: false + check: false + diff: false + dest_dir: "{{ playbook_dir }}/output" + filter: "re0" + return_output: true + register: test_xml_filter + + - name: CHECK TEST 10 - Retrieve with XML filter executed successfully + ansible.builtin.assert: + that: + - test_xml_filter.failed is not defined or test_xml_filter.failed == false + + - name: Ensure configs directory exists for TEST 11 + ansible.builtin.file: + path: "{{ playbook_dir }}/configs" + state: directory + mode: '0755' + delegate_to: localhost + run_once: true + + - name: Ensure override config file exists for TEST 11 + ansible.builtin.copy: + content: | + set system host-name test-host + dest: "{{ playbook_dir }}/configs/{{ inventory_hostname }}.conf" + delegate_to: localhost + run_once: true + + - name: Dry-run override config using private mode + juniper.device.config: + config_mode: private + load: set + src: "{{ playbook_dir }}/configs/{{ inventory_hostname }}.conf" + check: true + commit: false + register: test_override + ignore_errors: true + + - name: Skip TEST 11 if exclusive lock prevents config + ansible.builtin.debug: + msg: "Skipping TEST 11 - configure exclusive lock is active" + when: test_override.msg is defined and + ('configure exclusive' in test_override.msg or + 'exclusive' in test_override.msg or + test_override.failed) + + - name: CHECK TEST 11 - Dry-run override was successful + ansible.builtin.assert: + that: + - test_override.failed == false + when: test_override.failed == false + + + + + + + + + + + + + + + + diff --git a/tests/pb.juniper_junos_facts.yml b/tests/pb.juniper_junos_facts.yml index 7d2fb042..127ffbb8 100644 --- a/tests/pb.juniper_junos_facts.yml +++ b/tests/pb.juniper_junos_facts.yml @@ -26,3 +26,48 @@ ansible.builtin.assert: that: - "'= 0 + tags: [test9] + +########################################################################### +## TEST 10 +########################################################################### + - name: Ensure logs directory exists for TEST 10 + ansible.builtin.file: + path: "{{ playbook_dir }}/logs" + state: directory + mode: '0755' + delegate_to: localhost + run_once: true + tags: [test10] + + - name: TEST 10 - Use test_files with logdir and level + juniper.device.jsnapy: + action: snapcheck + dir: "{{ playbook_dir }}/config" + test_files: + - junos_jsnapy/test_loopback.yml + logdir: "{{ playbook_dir }}/logs" + level: INFO + register: test10 + ignore_errors: true + tags: [test10] + + - name: Check TEST 10 + ansible.builtin.assert: + that: + - test10.passPercentage is defined + - test10.total_failed == 0 + tags: [test10] + +############################################################## +## TEST 11 +############################################################## + - name: TEST 11 - Use logdir for check action + juniper.device.jsnapy: + action: check + dir: junos_jsnapy + test_files: "test_loopback.yml" + logdir: "{{ playbook_dir }}/logs" + register: test11 + ignore_errors: true + tags: [test11] + + - name: Check TEST 11 + ansible.builtin.assert: + that: + - test11.passPercentage is defined + - test11.passPercentage >= 0 + - test11.final_result is defined + tags: [test11] + + + + + + + + diff --git a/tests/pb.juniper_junos_ping.yml b/tests/pb.juniper_junos_ping.yml index 84421770..fb5be3ce 100644 --- a/tests/pb.juniper_junos_ping.yml +++ b/tests/pb.juniper_junos_ping.yml @@ -3,6 +3,7 @@ hosts: all gather_facts: false tasks: + - name: "TEST 1 - Ping Host DNS" juniper.device.ping: dest_ip: "{{ ansible_ssh_host }}" @@ -14,7 +15,7 @@ that: - test1.packet_loss == '0' -############ + ################################################ - name: "TEST 2 - Ping Wrong IP" juniper.device.ping: @@ -26,7 +27,8 @@ ansible.builtin.assert: that: - test2.packet_loss == '100' -################# + + ################################################ - name: "TEST 3 - Change nbr packets" juniper.device.ping: @@ -40,7 +42,7 @@ that: - test3.packets_sent == '3' -################# + ################################################ - name: "TEST 4 - Ping with DF-bit set" juniper.device.ping: @@ -56,4 +58,66 @@ that: - test4.packets_received == '3' -################# + ################################################ + + - name: "TEST 5 - Acceptable packet loss" + juniper.device.ping: + dest_ip: 8.8.1.1 + acceptable_percent_loss: 50 + register: test5 + ignore_errors: true + + - name: Check TEST 5 + ansible.builtin.assert: + that: + - test5.packet_loss == '100' + - test5.acceptable_percent_loss == '50' + + ################################################ + + - name: "TEST 6 - TTL and rapid=false" + juniper.device.ping: + dest_ip: "{{ ansible_ssh_host }}" + ttl: 15 + count: 10 + rapid: false + register: test6 + ignore_errors: true + + - name: Check TEST 6 + ansible.builtin.assert: + that: + - test6.ttl == '15' + - test6.rapid == false + + ################################################ + + - name: "TEST 7 - Ping with source IP" + juniper.device.ping: + dest_ip: "{{ ansible_ssh_host }}" + source: "{{ ansible_ssh_host }}" + register: test7 + ignore_errors: true + + - name: Check TEST 7 + ansible.builtin.assert: + that: + - test7.source == test7.source_ip + + ################################################ + + - name: "TEST 8 - Ping from routing-instance" + juniper.device.ping: + dest_ip: "{{ ansible_ssh_host }}" + routing_instance: "default" + register: test8 + ignore_errors: true + + - name: Check TEST 8 + ansible.builtin.assert: + that: + - test8.routing_instance == 'default' + + ################################################ + + diff --git a/tests/pb.juniper_junos_pmtud.yml b/tests/pb.juniper_junos_pmtud.yml index b5684214..ed91eba1 100644 --- a/tests/pb.juniper_junos_pmtud.yml +++ b/tests/pb.juniper_junos_pmtud.yml @@ -25,3 +25,56 @@ ansible.builtin.assert: that: - test1.inet_mtu <= 700 + + + - name: TEST 3 - PMTUD with max_range and max_size + juniper.device.pmtud: + dest_ip: "{{ ansible_ssh_host }}" + max_size: 65496 + max_range: 65536 + register: test3 + ignore_errors: true + + - name: Check TEST 3 + ansible.builtin.assert: + that: + - test3.inet_mtu | int <= 65496 + + - name: "TEST 4 - PMTUD from specific interface" + juniper.device.pmtud: + dest_ip: "{{ ansible_ssh_host }}" + interface: "ge-0/0/1.0" + register: test4 + + - name: Check TEST 4 + ansible.builtin.assert: + that: + - test4.inet_mtu is defined + - test4.inet_mtu | int >= 768 + + - name: "TEST 5 - PMTUD with source IP" + juniper.device.pmtud: + dest_ip: "{{ ansible_ssh_host }}" + source: "{{ ansible_ssh_host }}" + register: test5 + + - name: Check TEST 5 + ansible.builtin.assert: + that: + - test5.inet_mtu is defined + - test5.inet_mtu | int >= 768 + + - name: "TEST 6 - PMTUD with routing instance" + juniper.device.pmtud: + dest_ip: "{{ ansible_ssh_host }}" + routing_instance: "default" + register: test6 + + - name: Check TEST 6 + ansible.builtin.assert: + that: + - test6.inet_mtu is defined + - test6.inet_mtu | int >= 768 + + + diff --git a/tests/pb.juniper_junos_rpc.yml b/tests/pb.juniper_junos_rpc.yml index 12f7a302..7178b202 100644 --- a/tests/pb.juniper_junos_rpc.yml +++ b/tests/pb.juniper_junos_rpc.yml @@ -4,7 +4,7 @@ gather_facts: false tasks: -################# +################ - name: "Execute single RPC get-software-information without any kwargs" juniper.device.rpc: rpcs: @@ -274,3 +274,129 @@ that: - test1.msg == "The RPC executed successfully." tags: [test13] + + ################# + + - name: TEST 14 - RPC with ignore_warning + juniper.device.rpc: + rpcs: + - get-software-information + ignore_warning: true + register: test14 + tags: [test14] + + - name: Check TEST 14 + ansible.builtin.assert: + that: + - test14.msg == "The RPC executed successfully." + tags: [test14] + + ################# + + - name: Ensure logdir exists + ansible.builtin.file: + path: "{{ playbook_dir }}/rpc_logs" + state: directory + mode: "0755" + delegate_to: localhost + run_once: true + tags: [test15] + + - name: TEST 15 - RPC with logdir + juniper.device.rpc: + rpcs: + - get-software-information + logdir: "{{ playbook_dir }}/rpc_logs" + register: test15 + tags: [test15] + + - name: Check TEST 15 log file + ansible.builtin.stat: + path: "{{ playbook_dir }}/rpc_logs/{{ inventory_hostname }}.log" + register: stat_result_log15 + delegate_to: localhost + + - name: Clean up logdir + ansible.builtin.file: + path: "{{ playbook_dir }}/rpc_logs" + state: absent + delegate_to: localhost + run_once: true + tags: [test15] + + ################# + + - name: Ensure output directory exists for TEST 16 + ansible.builtin.file: + path: "{{ playbook_dir }}/rpc_output" + state: directory + mode: '0755' + delegate_to: localhost + run_once: true + tags: [test16] + + - name: TEST 16 - RPC with return_output false and dest_dir + juniper.device.rpc: + rpcs: + - get-software-information + return_output: false + dest_dir: "{{ playbook_dir }}/rpc_output" + register: test16 + tags: [test16] + + - name: Assert TEST 16 has no output returned + ansible.builtin.assert: + that: + - test16.stdout is not defined + tags: [test16] + + - name: Clean up TEST 16 output dir + ansible.builtin.file: + path: "{{ playbook_dir }}/rpc_output" + state: absent + delegate_to: localhost + run_once: true + tags: [test16] + + ################# + + - name: TEST 17 - RPC with attrs (attribute applied without kwargs) + juniper.device.rpc: + rpcs: + - get-config + attrs: + format: text + filter: "" + register: test17 + tags: [test17] + + - name: Check TEST 17 + ansible.builtin.assert: + that: + - test17.stdout is defined + - "' Date: Mon, 2 Jun 2025 20:02:37 +0530 Subject: [PATCH 4/4] Add functional test for junos_scp and update config, SNMP, and user test playbooks --- .../pb.juniper_junos_config.yml | 24 ++++--- .../pb.juniper_junos_scp.yml | 71 +++++++++++++++++++ .../pb.juniper_junos_snmp_server.yml | 34 +++++++-- .../pb.juniper_junos_user.yml | 2 + 4 files changed, 116 insertions(+), 15 deletions(-) create mode 100644 tests/junipernetworks.junos/pb.juniper_junos_scp.yml diff --git a/tests/junipernetworks.junos/pb.juniper_junos_config.yml b/tests/junipernetworks.junos/pb.juniper_junos_config.yml index 43a61133..82ecfb9d 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_config.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_config.yml @@ -8,14 +8,14 @@ tasks: - name: Pre-clean - Remove existing test interface description - junos_config: + junipernetworks.junos.junos_config: lines: - delete interfaces ge-0/0/1 unit 0 description comment: "Clean up test interface config" register: preclean_result - name: Assert pre-clean successful - assert: + ansible.builtin.assert: that: - preclean_result.changed in [true, false] @@ -27,12 +27,12 @@ register: apply_result - name: Assert interface config applied - assert: + ansible.builtin.assert: that: - apply_result.changed == true - name: Confirm commit test with timer - junos_config: + junipernetworks.junos.junos_config: lines: - set system host-name ft-test-host confirm: 3 @@ -40,11 +40,11 @@ # Intentionally allowing commit to rollback to test confirm - name: Rollback config to rollback 0 - junos_config: + junipernetworks.junos.junos_config: rollback: 0 - name: Backup config to custom path - junos_config: + junipernetworks.junos.junos_config: lines: - set system services ssh backup: true @@ -53,15 +53,21 @@ dir_path: ./backup register: backup_result + - name: Debug backup_result + debug: + var: backup_result + + - name: Assert backup created - assert: + ansible.builtin.assert: that: - - backup_result.backup_path is defined + - backup_result.backup_path is defined or backup_result.__backup__ is defined - name: Post-clean - delete test configuration - junos_config: + junipernetworks.junos.junos_config: lines: - delete interfaces ge-0/0/1 unit 0 description - delete system host-name - delete system services ssh comment: "Post-clean" + diff --git a/tests/junipernetworks.junos/pb.juniper_junos_scp.yml b/tests/junipernetworks.junos/pb.juniper_junos_scp.yml new file mode 100644 index 00000000..f6441cf8 --- /dev/null +++ b/tests/junipernetworks.junos/pb.juniper_junos_scp.yml @@ -0,0 +1,71 @@ +- name: Functional Test - junos_scp module + hosts: localhost + connection: local + gather_facts: false + collections: + - junipernetworks.junos + + vars: + scp_src_file: "./files/test.tgz" + scp_dest_dir: "/tmp/" + scp_custom_ssh_config: "/home/user/customsshconfig" + + tasks: + + - name: "Pre-check - Ensure src file exists locally" + ansible.builtin.stat: + path: "{{ scp_src_file }}" + register: file_check + + - name: "Abort if test source file is not found" + ansible.builtin.fail: + msg: "Source file for SCP test not found at {{ scp_src_file }}" + when: not file_check.stat.exists + + - name: "TEST 1 - Upload local file to home directory on remote device" + junipernetworks.junos.junos_scp: + src: "{{ scp_src_file }}" + register: result_upload_home + + - name: "ASSERT 1 - Upload to home succeeded" + ansible.builtin.assert: + that: + - result_upload_home is defined + - result_upload_home.changed is true + + - name: "TEST 2 - Upload local file to /tmp directory on remote device" + junipernetworks.junos.junos_scp: + src: "{{ scp_src_file }}" + dest: "{{ scp_dest_dir }}" + register: result_upload_tmp + + - name: "ASSERT 2 - Upload to /tmp succeeded" + ansible.builtin.assert: + that: + - result_upload_tmp is defined + - result_upload_tmp.changed is true + + - name: "TEST 3 - Download file from remote device" + junipernetworks.junos.junos_scp: + src: "{{ scp_dest_dir }}test.tgz" + remote_src: true + register: result_download + + - name: "ASSERT 3 - Download from device succeeded" + ansible.builtin.assert: + that: + - result_download is defined + - result_download.changed is true + + - name: "TEST 4 - Download using custom SSH config" + junipernetworks.junos.junos_scp: + src: "{{ scp_dest_dir }}test.tgz" + remote_src: true + ssh_config: "{{ scp_custom_ssh_config }}" + register: result_ssh_config + + - name: "ASSERT 4 - Download with custom SSH config succeeded" + ansible.builtin.assert: + that: + - result_ssh_config is defined + - result_ssh_config.changed is true diff --git a/tests/junipernetworks.junos/pb.juniper_junos_snmp_server.yml b/tests/junipernetworks.junos/pb.juniper_junos_snmp_server.yml index 94543acb..a8afd50c 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_snmp_server.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_snmp_server.yml @@ -1,11 +1,20 @@ - name: Functional Test - junos_snmp_server (all states) - hosts: netconf_connection_testcases + hosts: junos_device gather_facts: false connection: netconf collections: - junipernetworks.junos tasks: + - name: Ensure routing instances clv1 and clv2 exist + junipernetworks.junos.junos_routing_instances: + config: + - name: clv1 + type: virtual-router + - name: clv2 + type: virtual-router + state: merged + - name: Render SNMP server configuration (dry-run XML) junipernetworks.junos.junos_snmp_server: config: @@ -38,7 +47,7 @@ - result_parsed.parsed is defined - result_parsed.changed == false - - name: Merge SNMP server configuration (may fail if RI clv1/clv2 don't exist) + - name: Merge SNMP server configuration junipernetworks.junos.junos_snmp_server: config: arp: @@ -61,7 +70,11 @@ - clv2 state: merged register: result_merge - ignore_errors: true # Skip if routing instances clv1/clv2 are not present + + - name: Assert merged SNMP config + assert: + that: + - result_merge.changed is defined - name: Replace SNMP server configuration junipernetworks.junos.junos_snmp_server: @@ -84,6 +97,11 @@ state: replaced register: result_replaced + - name: Assert replaced SNMP config + assert: + that: + - result_replaced.changed is defined + - name: Override SNMP server configuration junipernetworks.junos.junos_snmp_server: config: @@ -105,6 +123,11 @@ state: overridden register: result_overridden + - name: Assert overridden SNMP config + assert: + that: + - result_overridden.changed is defined + - name: Gather SNMP server configuration from device junipernetworks.junos.junos_snmp_server: state: gathered @@ -122,9 +145,8 @@ state: deleted register: result_deleted - - name: Assert config states + - name: Assert deleted SNMP config assert: that: - - result_replaced.changed is defined - - result_overridden.changed is defined - result_deleted.changed is defined + diff --git a/tests/junipernetworks.junos/pb.juniper_junos_user.yml b/tests/junipernetworks.junos/pb.juniper_junos_user.yml index 5ef05200..24622709 100644 --- a/tests/junipernetworks.junos/pb.juniper_junos_user.yml +++ b/tests/junipernetworks.junos/pb.juniper_junos_user.yml @@ -1,3 +1,5 @@ +# Please ensure the 'passlib' library is installed before running this test (pip install passlib). + --- - name: Functional Test - junos_user module hosts: netconf_connection_testcases