diff options
| author | omnom62 <75066712+omnom62@users.noreply.github.com> | 2026-08-22 01:04:18 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-21 10:04:18 -0500 |
| commit | cb738721c15ac01f49f66144dae80eb478331f77 (patch) | |
| tree | 52f870ed414506aaa5cd6efa7ae6513d807e194b /tests | |
| parent | 885b9462480712210ddeea9ca4a4b7a52e9ef587 (diff) | |
| download | rest.vyos-cb738721c15ac01f49f66144dae80eb478331f77.tar.gz rest.vyos-cb738721c15ac01f49f66144dae80eb478331f77.zip | |
T8989: wave 2 modules: interfaces, l3_interfaces, lag_interfaces, lldp_interfaces, ospfv2/3, ospf_interfaces
* T8989: vyos_interfaces
* T8989: vyos_interfaces changelog
* T8989: vyos_interfaces changelog
* T8989: changelog typo
* T8989: vyos_l3_interfaces module
* T8989: vyos_l3_interfaces module SIT and UAT
* T8989: vyos_l3_interfaces doc
* T8989: lag_interfaces
* T8989: lag interfaces
* T8989: lldp_interfaces
* T8989: lldp_interfaces module
* T8989: SIT updated
* T8989: SIT updated
* T8989: SIT updated
* T8989: typo fixes
* T8989: SIT and UAT updates
* T8989: ospf_v3 module
* T8989: ospf_v3 module
* T8989: vyos_ospf_interfaces
* T8989: vyos_ospf_interfaces SIT
* T8989: vyos_ospf_interfaces SIT
* T8989: vyos_ospfv3 SIT and UAT
---------
Co-authored-by: John Estabrook <jestabro@vyos.io>
Diffstat (limited to 'tests')
122 files changed, 4237 insertions, 44 deletions
diff --git a/tests/integration/targets/vyos_banner/tests/httpapi/overridden.yaml b/tests/integration/targets/vyos_banner/tests/httpapi/overridden.yaml new file mode 100644 index 0000000..f80add0 --- /dev/null +++ b/tests/integration/targets/vyos_banner/tests/httpapi/overridden.yaml @@ -0,0 +1,30 @@ +--- +- debug: + msg: START vyos_hostname overridden integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Override hostname configuration + register: result + vyos.rest.vyos_hostname: &id001 + config: + hostname: ansible-overridden-host + state: overridden + + - assert: + that: + - result.changed == true + + - name: Override hostname configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_hostname: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_banner/tests/httpapi/replaced.yaml b/tests/integration/targets/vyos_banner/tests/httpapi/replaced.yaml new file mode 100644 index 0000000..2dddc90 --- /dev/null +++ b/tests/integration/targets/vyos_banner/tests/httpapi/replaced.yaml @@ -0,0 +1,31 @@ +--- +- debug: + msg: START vyos_banner replaced integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Replace pre-login banner + register: result + vyos.rest.vyos_banner: &id001 + config: + banner: pre-login + text: "Replaced by ansible" + state: replaced + + - assert: + that: + - result.changed == true + + - name: Replace pre-login banner (IDEMPOTENT) + register: result + vyos.rest.vyos_banner: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_banner/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_banner/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..233f1ef --- /dev/null +++ b/tests/integration/targets/vyos_banner/tests/httpapi/rtt.yaml @@ -0,0 +1,41 @@ +--- +- debug: + msg: START vyos_hostname round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: RTT - Apply base configuration + vyos.rest.vyos_hostname: + config: + hostname: ansible-rtt-host + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_hostname: + state: gathered + + - name: RTT - Assert gathered matches applied + assert: + that: + - gathered.gathered.hostname == "ansible-rtt-host" + + - name: RTT - Modify configuration + vyos.rest.vyos_hostname: + config: + hostname: ansible-rtt-modified + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_hostname: + state: gathered + + - name: RTT - Assert modification applied correctly + assert: + that: + - gathered2.gathered.hostname == "ansible-rtt-modified" + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_hostname/tests/httpapi/overridden.yaml b/tests/integration/targets/vyos_hostname/tests/httpapi/overridden.yaml new file mode 100644 index 0000000..671ac41 --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/httpapi/overridden.yaml @@ -0,0 +1,32 @@ +--- +- debug: + msg: START vyos_interfaces overridden integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Override interface configuration + register: result + vyos.rest.vyos_interfaces: &id001 + config: + - name: eth0 + description: Ansible overridden interface + mtu: 1400 + state: overridden + + - assert: + that: + - result.changed == true + + - name: Override interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_interfaces: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_hostname/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_hostname/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..74261f8 --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/httpapi/rtt.yaml @@ -0,0 +1,48 @@ +--- +- debug: + msg: START vyos_interfaces round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: RTT - Apply base configuration + vyos.rest.vyos_interfaces: + config: + - name: eth0 + description: Ansible RTT interface + mtu: 1450 + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_interfaces: + state: gathered + + - name: RTT - Assert gathered matches applied + assert: + that: + - gathered.gathered | selectattr('name', 'eq', 'eth0') | list | length == 1 + - gathered.gathered | selectattr('name', 'eq', 'eth0') | map(attribute='description') | first == 'Ansible RTT interface' + - gathered.gathered | selectattr('name', 'eq', 'eth0') | map(attribute='mtu') | first == 1450 + + - name: RTT - Modify configuration + vyos.rest.vyos_interfaces: + config: + - name: eth0 + description: Ansible RTT modified + mtu: 1400 + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_interfaces: + state: gathered + + - name: RTT - Assert modification applied correctly + assert: + that: + - gathered2.gathered | selectattr('name', 'eq', 'eth0') | map(attribute='description') | first == 'Ansible RTT modified' + - gathered2.gathered | selectattr('name', 'eq', 'eth0') | map(attribute='mtu') | first == 1400 + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_prefix_lists/aliases b/tests/integration/targets/vyos_interfaces/aliases index cc0afef..cc0afef 100644 --- a/tests/integration/targets/vyos_prefix_lists/aliases +++ b/tests/integration/targets/vyos_interfaces/aliases diff --git a/tests/integration/targets/vyos_prefix_lists/defaults/main.yaml b/tests/integration/targets/vyos_interfaces/defaults/main.yaml index 164afea..164afea 100644 --- a/tests/integration/targets/vyos_prefix_lists/defaults/main.yaml +++ b/tests/integration/targets/vyos_interfaces/defaults/main.yaml diff --git a/tests/integration/targets/vyos_prefix_lists/tasks/httpapi.yaml b/tests/integration/targets/vyos_interfaces/tasks/httpapi.yaml index 4147e6d..4147e6d 100644 --- a/tests/integration/targets/vyos_prefix_lists/tasks/httpapi.yaml +++ b/tests/integration/targets/vyos_interfaces/tasks/httpapi.yaml diff --git a/tests/integration/targets/vyos_prefix_lists/tasks/main.yaml b/tests/integration/targets/vyos_interfaces/tasks/main.yaml index b1f6193..b1f6193 100644 --- a/tests/integration/targets/vyos_prefix_lists/tasks/main.yaml +++ b/tests/integration/targets/vyos_interfaces/tasks/main.yaml diff --git a/tests/integration/targets/vyos_interfaces/tests/httpapi/_populate_config.yaml b/tests/integration/targets/vyos_interfaces/tests/httpapi/_populate_config.yaml new file mode 100644 index 0000000..9562fce --- /dev/null +++ b/tests/integration/targets/vyos_interfaces/tests/httpapi/_populate_config.yaml @@ -0,0 +1,9 @@ +--- +- name: Populate interface config for testing + vyos.rest.vyos_interfaces: + config: + - name: eth0 + description: Ansible test interface + mtu: 1450 + state: merged + ignore_errors: true diff --git a/tests/integration/targets/vyos_interfaces/tests/httpapi/_remove_config.yaml b/tests/integration/targets/vyos_interfaces/tests/httpapi/_remove_config.yaml new file mode 100644 index 0000000..4014e56 --- /dev/null +++ b/tests/integration/targets/vyos_interfaces/tests/httpapi/_remove_config.yaml @@ -0,0 +1,7 @@ +--- +- name: Remove interface L2 config + vyos.rest.vyos_interfaces: + config: + - name: eth0 + state: deleted + ignore_errors: true diff --git a/tests/integration/targets/vyos_interfaces/tests/httpapi/deleted.yaml b/tests/integration/targets/vyos_interfaces/tests/httpapi/deleted.yaml new file mode 100644 index 0000000..e8dfd06 --- /dev/null +++ b/tests/integration/targets/vyos_interfaces/tests/httpapi/deleted.yaml @@ -0,0 +1,30 @@ +--- +- debug: + msg: START vyos_interfaces deleted integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Delete interface configuration + register: result + vyos.rest.vyos_interfaces: &id001 + config: + - name: eth0 + state: deleted + + - assert: + that: + - result.changed == true + + - name: Delete interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_interfaces: *id001 + + - name: Assert idempotent + assert: + that: + - result.changed == false + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_interfaces/tests/httpapi/gathered.yaml b/tests/integration/targets/vyos_interfaces/tests/httpapi/gathered.yaml new file mode 100644 index 0000000..022e21e --- /dev/null +++ b/tests/integration/targets/vyos_interfaces/tests/httpapi/gathered.yaml @@ -0,0 +1,21 @@ +--- +- debug: + msg: START vyos_interfaces gathered integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Gather interface configuration + register: result + vyos.rest.vyos_interfaces: + state: gathered + + - assert: + that: + - result.changed == false + - result.gathered | selectattr('name', 'eq', 'eth0') | list | length == 1 + - result.gathered | selectattr('name', 'eq', 'eth0') | map(attribute='description') | first == 'Ansible test interface' + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_interfaces/tests/httpapi/merged.yaml b/tests/integration/targets/vyos_interfaces/tests/httpapi/merged.yaml new file mode 100644 index 0000000..b5a82ef --- /dev/null +++ b/tests/integration/targets/vyos_interfaces/tests/httpapi/merged.yaml @@ -0,0 +1,32 @@ +--- +- debug: + msg: START vyos_interfaces merged integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: Merge interface configuration + register: result + vyos.rest.vyos_interfaces: &id001 + config: + - name: eth0 + description: Ansible test interface + mtu: 1450 + state: merged + + - assert: + that: + - result.changed == true + + - name: Merge interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_interfaces: *id001 + + - name: Assert idempotent + assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_interfaces/tests/httpapi/replaced.yaml b/tests/integration/targets/vyos_interfaces/tests/httpapi/replaced.yaml new file mode 100644 index 0000000..430b441 --- /dev/null +++ b/tests/integration/targets/vyos_interfaces/tests/httpapi/replaced.yaml @@ -0,0 +1,33 @@ +--- +- debug: + msg: START vyos_interfaces replaced integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Replace interface configuration + register: result + vyos.rest.vyos_interfaces: &id001 + config: + - name: eth0 + description: Ansible replaced interface + mtu: 1400 + state: replaced + + - assert: + that: + - result.changed == true + + - name: Replace interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_interfaces: *id001 + + - name: Assert idempotent + assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_prefix_lists/vars/main.yaml b/tests/integration/targets/vyos_interfaces/vars/main.yaml index 4303881..4303881 100644 --- a/tests/integration/targets/vyos_prefix_lists/vars/main.yaml +++ b/tests/integration/targets/vyos_interfaces/vars/main.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/aliases b/tests/integration/targets/vyos_l3_interfaces/aliases new file mode 100644 index 0000000..cc0afef --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/aliases @@ -0,0 +1 @@ +network/vyos diff --git a/tests/integration/targets/vyos_l3_interfaces/defaults/main.yaml b/tests/integration/targets/vyos_l3_interfaces/defaults/main.yaml new file mode 100644 index 0000000..164afea --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/tests/integration/targets/vyos_l3_interfaces/tasks/httpapi.yaml b/tests/integration/targets/vyos_l3_interfaces/tasks/httpapi.yaml new file mode 100644 index 0000000..4147e6d --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/tasks/httpapi.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect all httpapi test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/httpapi" + patterns: "{{ testcase }}.yaml" + use_regex: true + register: test_cases + delegate_to: localhost + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + vars: + ansible_connection: ansible.netcommon.httpapi + ansible_network_os: vyos.rest.vyos + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_l3_interfaces/tasks/main.yaml b/tests/integration/targets/vyos_l3_interfaces/tasks/main.yaml new file mode 100644 index 0000000..b1f6193 --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Run httpapi tests + ansible.builtin.include_tasks: httpapi.yaml + tags: + - httpapi diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/_populate_config.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/_populate_config.yaml new file mode 100644 index 0000000..af425ae --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/_populate_config.yaml @@ -0,0 +1,15 @@ +--- +- name: Populate L3 interface config for testing + vyos.rest.vyos_l3_interfaces: + config: + - name: lo + ipv4: + - address: 10.0.0.1/32 + - address: 10.0.0.2/32 + - name: eth0 + vifs: + - vlan_id: 100 + ipv4: + - address: 192.0.2.100/24 + state: merged + ignore_errors: true diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/_remove_config.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/_remove_config.yaml new file mode 100644 index 0000000..44453c3 --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/_remove_config.yaml @@ -0,0 +1,10 @@ +--- +- name: Remove test L3 config + vyos.rest.vyos_l3_interfaces: + config: + - name: lo + - name: eth0 + vifs: + - vlan_id: 100 + state: deleted + ignore_errors: true diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/deleted.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/deleted.yaml new file mode 100644 index 0000000..a583354 --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/deleted.yaml @@ -0,0 +1,33 @@ +--- +- debug: + msg: START vyos_l3_interfaces deleted integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Delete L3 interface configuration + register: result + vyos.rest.vyos_l3_interfaces: &id001 + config: + - name: lo + - name: eth0 + vifs: + - vlan_id: 100 + state: deleted + + - assert: + that: + - result.changed == true + + - name: Delete L3 interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_l3_interfaces: *id001 + + - name: Assert idempotent + assert: + that: + - result.changed == false + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/gathered.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/gathered.yaml new file mode 100644 index 0000000..cfd380a --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/gathered.yaml @@ -0,0 +1,21 @@ +--- +- debug: + msg: START vyos_l3_interfaces gathered integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Gather L3 interface configuration + register: result + vyos.rest.vyos_l3_interfaces: + state: gathered + + - assert: + that: + - result.changed == false + - result.gathered | selectattr('name', 'eq', 'lo') | list | length == 1 + - result.gathered | selectattr('name', 'eq', 'lo') | map(attribute='ipv4') | first | length == 2 + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/merged.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/merged.yaml new file mode 100644 index 0000000..eabd97b --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/merged.yaml @@ -0,0 +1,33 @@ +--- +- debug: + msg: START vyos_l3_interfaces merged integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: Merge L3 interface configuration + register: result + vyos.rest.vyos_l3_interfaces: &id001 + config: + - name: lo + ipv4: + - address: 10.0.0.1/32 + - address: 10.0.0.2/32 + state: merged + + - assert: + that: + - result.changed == true + + - name: Merge L3 interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_l3_interfaces: *id001 + + - name: Assert idempotent + assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/overridden.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/overridden.yaml new file mode 100644 index 0000000..09d72ae --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/overridden.yaml @@ -0,0 +1,35 @@ +--- +- debug: + msg: START vyos_l3_interfaces overridden integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Override L3 interface configuration + register: result + vyos.rest.vyos_l3_interfaces: &id001 + config: + - name: eth0 + ipv4: + - address: dhcp + - name: lo + ipv4: + - address: 10.0.0.1/32 + state: overridden + + - assert: + that: + - result.changed == true + + - name: Override L3 interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_l3_interfaces: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/replaced.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/replaced.yaml new file mode 100644 index 0000000..e193ced --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/replaced.yaml @@ -0,0 +1,33 @@ +--- +- debug: + msg: START vyos_l3_interfaces replaced integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Replace L3 interface configuration + register: result + vyos.rest.vyos_l3_interfaces: &id001 + config: + - name: lo + ipv4: + - address: 10.0.0.1/32 + state: replaced + + - assert: + that: + - result.changed == true + + - name: Replace L3 interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_l3_interfaces: *id001 + + - name: Assert idempotent + assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..c347f1a --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/tests/httpapi/rtt.yaml @@ -0,0 +1,48 @@ +--- +- debug: + msg: START vyos_l3_interfaces round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: RTT - Apply base configuration + vyos.rest.vyos_l3_interfaces: + config: + - name: lo + ipv4: + - address: 10.0.0.1/32 + - address: 10.0.0.2/32 + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_l3_interfaces: + state: gathered + + - name: RTT - Assert gathered matches applied + assert: + that: + - gathered.gathered | selectattr('name', 'eq', 'lo') | list | length == 1 + - gathered.gathered | selectattr('name', 'eq', 'lo') | map(attribute='ipv4') | first | length == 2 + + - name: RTT - Modify configuration + vyos.rest.vyos_l3_interfaces: + config: + - name: lo + ipv4: + - address: 10.0.0.1/32 + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_l3_interfaces: + state: gathered + + - name: RTT - Assert modification applied correctly + assert: + that: + - gathered2.gathered | selectattr('name', 'eq', 'lo') | map(attribute='ipv4') | first | length == 1 + - gathered2.gathered | selectattr('name', 'eq', 'lo') | map(attribute='ipv4') | first | map(attribute='address') | first == '10.0.0.1/32' + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/vars/main.yaml b/tests/integration/targets/vyos_l3_interfaces/vars/main.yaml new file mode 100644 index 0000000..4303881 --- /dev/null +++ b/tests/integration/targets/vyos_l3_interfaces/vars/main.yaml @@ -0,0 +1,2 @@ +--- +# only common vars here diff --git a/tests/integration/targets/vyos_lag_interfaces/aliases b/tests/integration/targets/vyos_lag_interfaces/aliases new file mode 100644 index 0000000..cc0afef --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/aliases @@ -0,0 +1 @@ +network/vyos diff --git a/tests/integration/targets/vyos_lag_interfaces/defaults/main.yaml b/tests/integration/targets/vyos_lag_interfaces/defaults/main.yaml new file mode 100644 index 0000000..164afea --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/tests/integration/targets/vyos_lag_interfaces/tasks/httpapi.yaml b/tests/integration/targets/vyos_lag_interfaces/tasks/httpapi.yaml new file mode 100644 index 0000000..4147e6d --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/tasks/httpapi.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect all httpapi test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/httpapi" + patterns: "{{ testcase }}.yaml" + use_regex: true + register: test_cases + delegate_to: localhost + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + vars: + ansible_connection: ansible.netcommon.httpapi + ansible_network_os: vyos.rest.vyos + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_lag_interfaces/tasks/main.yaml b/tests/integration/targets/vyos_lag_interfaces/tasks/main.yaml new file mode 100644 index 0000000..b1f6193 --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Run httpapi tests + ansible.builtin.include_tasks: httpapi.yaml + tags: + - httpapi diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/_populate_config.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/_populate_config.yaml new file mode 100644 index 0000000..c21a3e6 --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/_populate_config.yaml @@ -0,0 +1,13 @@ +--- +- name: Populate LAG config for testing + vyos.rest.vyos_lag_interfaces: + config: + - name: bond0 + mode: active-backup + hash_policy: layer2 + arp_monitor: + interval: 100 + target: + - 192.0.2.1 + state: merged + ignore_errors: true diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/_remove_config.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/_remove_config.yaml new file mode 100644 index 0000000..f2dab9d --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/_remove_config.yaml @@ -0,0 +1,5 @@ +--- +- name: Remove pre-existing LAG config + vyos.rest.vyos_lag_interfaces: + state: deleted + ignore_errors: true diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/deleted.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/deleted.yaml new file mode 100644 index 0000000..c7959ec --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/deleted.yaml @@ -0,0 +1,28 @@ +--- +- debug: + msg: START vyos_lag_interfaces deleted integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Delete all LAG configuration + register: result + vyos.rest.vyos_lag_interfaces: &id001 + state: deleted + + - assert: + that: + - result.changed == true + + - name: Delete LAG configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_lag_interfaces: *id001 + + - name: Assert idempotent + assert: + that: + - result.changed == false + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/gathered.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/gathered.yaml new file mode 100644 index 0000000..7bf3a6e --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/gathered.yaml @@ -0,0 +1,21 @@ +--- +- debug: + msg: START vyos_lag_interfaces gathered integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Gather LAG configuration + register: result + vyos.rest.vyos_lag_interfaces: + state: gathered + + - assert: + that: + - result.changed == false + - result.gathered | selectattr('name', 'eq', 'bond0') | list | length == 1 + - result.gathered | selectattr('name', 'eq', 'bond0') | map(attribute='mode') | first == 'active-backup' + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/merged.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/merged.yaml new file mode 100644 index 0000000..8bda2ee --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/merged.yaml @@ -0,0 +1,36 @@ +--- +- debug: + msg: START vyos_lag_interfaces merged integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: Merge LAG configuration + register: result + vyos.rest.vyos_lag_interfaces: &id001 + config: + - name: bond0 + mode: active-backup + hash_policy: layer2 + arp_monitor: + interval: 100 + target: + - 192.0.2.1 + state: merged + + - assert: + that: + - result.changed == true + + - name: Merge LAG configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_lag_interfaces: *id001 + + - name: Assert idempotent + assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/overridden.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/overridden.yaml new file mode 100644 index 0000000..3024d71 --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/overridden.yaml @@ -0,0 +1,32 @@ +--- +- debug: + msg: START vyos_lag_interfaces overridden integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Override LAG configuration + register: result + vyos.rest.vyos_lag_interfaces: &id001 + config: + - name: bond0 + mode: active-backup + hash_policy: layer2+3 + state: overridden + + - assert: + that: + - result.changed == true + + - name: Override LAG configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_lag_interfaces: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/replaced.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/replaced.yaml new file mode 100644 index 0000000..e8eb972 --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/replaced.yaml @@ -0,0 +1,37 @@ +--- +- debug: + msg: START vyos_lag_interfaces replaced integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Replace LAG configuration + register: result + vyos.rest.vyos_lag_interfaces: &id001 + config: + - name: bond0 + mode: active-backup + hash_policy: layer2+3 + arp_monitor: + interval: 200 + target: + - 192.0.2.2 + state: replaced + + - assert: + that: + - result.changed == true + + - name: Replace LAG configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_lag_interfaces: *id001 + + - name: Assert idempotent + assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..4e58069 --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/tests/httpapi/rtt.yaml @@ -0,0 +1,56 @@ +--- +- debug: + msg: START vyos_lag_interfaces round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: RTT - Apply base configuration + vyos.rest.vyos_lag_interfaces: + config: + - name: bond0 + mode: active-backup + hash_policy: layer2 + arp_monitor: + interval: 100 + target: + - 192.0.2.1 + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_lag_interfaces: + state: gathered + + - name: RTT - Assert gathered matches applied + assert: + that: + - gathered.gathered | selectattr('name', 'eq', 'bond0') | list | length == 1 + - gathered.gathered | selectattr('name', 'eq', 'bond0') | map(attribute='mode') | first == 'active-backup' + - gathered.gathered | selectattr('name', 'eq', 'bond0') | map(attribute='hash_policy') | first == 'layer2' + + - name: RTT - Modify configuration + vyos.rest.vyos_lag_interfaces: + config: + - name: bond0 + mode: active-backup + hash_policy: layer2+3 + arp_monitor: + interval: 200 + target: + - 192.0.2.2 + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_lag_interfaces: + state: gathered + + - name: RTT - Assert modification applied correctly + assert: + that: + - gathered2.gathered | selectattr('name', 'eq', 'bond0') | map(attribute='hash_policy') | first == 'layer2+3' + - gathered2.gathered | selectattr('name', 'eq', 'bond0') | map(attribute='arp_monitor') | map(attribute='interval') | first == 200 + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lag_interfaces/vars/main.yaml b/tests/integration/targets/vyos_lag_interfaces/vars/main.yaml new file mode 100644 index 0000000..4303881 --- /dev/null +++ b/tests/integration/targets/vyos_lag_interfaces/vars/main.yaml @@ -0,0 +1,2 @@ +--- +# only common vars here diff --git a/tests/integration/targets/vyos_lldp_global/tests/httpapi/overridden.yaml b/tests/integration/targets/vyos_lldp_global/tests/httpapi/overridden.yaml new file mode 100644 index 0000000..8f85df5 --- /dev/null +++ b/tests/integration/targets/vyos_lldp_global/tests/httpapi/overridden.yaml @@ -0,0 +1,34 @@ +--- +- debug: + msg: START vyos_lldp_global overridden integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Override LLDP global configuration + register: result + vyos.rest.vyos_lldp_global: &id001 + config: + enable: true + addresses: + - 192.0.2.20 + legacy_protocols: + - cdp + state: replaced + + - assert: + that: + - result.changed == true + + - name: Override LLDP global configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_lldp_global: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_global/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_lldp_global/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..421f966 --- /dev/null +++ b/tests/integration/targets/vyos_lldp_global/tests/httpapi/rtt.yaml @@ -0,0 +1,53 @@ +--- +- debug: + msg: START vyos_lldp_global round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: RTT - Apply base configuration + vyos.rest.vyos_lldp_global: + config: + enable: true + addresses: + - 192.0.2.17 + legacy_protocols: + - cdp + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_lldp_global: + state: gathered + + - name: RTT - Assert gathered matches applied + assert: + that: + - gathered.gathered.enable == true + - "'192.0.2.17' in gathered.gathered.addresses" + - "'cdp' in gathered.gathered.legacy_protocols" + + - name: RTT - Modify configuration + vyos.rest.vyos_lldp_global: + config: + enable: true + addresses: + - 192.0.2.20 + legacy_protocols: + - fdp + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_lldp_global: + state: gathered + + - name: RTT - Assert modification applied correctly + assert: + that: + - "'192.0.2.20' in gathered2.gathered.addresses" + - "'fdp' in gathered2.gathered.legacy_protocols" + - "'cdp' not in gathered2.gathered.legacy_protocols" + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_interfaces/aliases b/tests/integration/targets/vyos_lldp_interfaces/aliases new file mode 100644 index 0000000..cc0afef --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/aliases @@ -0,0 +1 @@ +network/vyos diff --git a/tests/integration/targets/vyos_lldp_interfaces/defaults/main.yaml b/tests/integration/targets/vyos_lldp_interfaces/defaults/main.yaml new file mode 100644 index 0000000..164afea --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/tests/integration/targets/vyos_lldp_interfaces/tasks/httpapi.yaml b/tests/integration/targets/vyos_lldp_interfaces/tasks/httpapi.yaml new file mode 100644 index 0000000..4147e6d --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/tasks/httpapi.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect all httpapi test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/httpapi" + patterns: "{{ testcase }}.yaml" + use_regex: true + register: test_cases + delegate_to: localhost + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + vars: + ansible_connection: ansible.netcommon.httpapi + ansible_network_os: vyos.rest.vyos + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_lldp_interfaces/tasks/main.yaml b/tests/integration/targets/vyos_lldp_interfaces/tasks/main.yaml new file mode 100644 index 0000000..b1f6193 --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Run httpapi tests + ansible.builtin.include_tasks: httpapi.yaml + tags: + - httpapi diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/_populate_config.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/_populate_config.yaml new file mode 100644 index 0000000..f7f27b0 --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/_populate_config.yaml @@ -0,0 +1,16 @@ +--- +- name: Ensure LLDP service is enabled + vyos.rest.vyos_configure: + commands: + - "set service lldp" + ignore_errors: true + +- name: Populate LLDP interface config for testing + vyos.rest.vyos_lldp_interfaces: + config: + - name: eth0 + mode: disable + location: + elin: "1234567890" + state: merged + ignore_errors: true diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/_remove_config.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/_remove_config.yaml new file mode 100644 index 0000000..8612bd7 --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/_remove_config.yaml @@ -0,0 +1,5 @@ +--- +- name: Remove LLDP interface config + vyos.rest.vyos_lldp_interfaces: + state: deleted + ignore_errors: true diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/deleted.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/deleted.yaml new file mode 100644 index 0000000..cd432bb --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/deleted.yaml @@ -0,0 +1,28 @@ +--- +- debug: + msg: START vyos_lldp_interfaces deleted integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Delete LLDP interface configuration + register: result + vyos.rest.vyos_lldp_interfaces: &id001 + state: deleted + + - assert: + that: + - result.changed == true + + - name: Delete LLDP interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_lldp_interfaces: *id001 + + - name: Assert idempotent + assert: + that: + - result.changed == false + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/gathered.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/gathered.yaml new file mode 100644 index 0000000..590fe01 --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/gathered.yaml @@ -0,0 +1,21 @@ +--- +- debug: + msg: START vyos_lldp_interfaces gathered integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Gather LLDP interface configuration + register: result + vyos.rest.vyos_lldp_interfaces: + state: gathered + + - assert: + that: + - result.changed == false + - result.gathered | selectattr('name', 'eq', 'eth0') | list | length == 1 + - result.gathered | selectattr('name', 'eq', 'eth0') | map(attribute='mode') | first == 'disable' + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/merged.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/merged.yaml new file mode 100644 index 0000000..636157a --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/merged.yaml @@ -0,0 +1,48 @@ +--- +- debug: + msg: START vyos_lldp_interfaces merged integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Merge LLDP interface configuration + register: result + vyos.rest.vyos_lldp_interfaces: &id001 + config: + - name: eth0 + mode: disable + location: + elin: "1234567890" + state: merged + + - assert: + that: + - result.changed == false + + - name: Merge LLDP interface — add elin change + register: result + vyos.rest.vyos_lldp_interfaces: &id002 + config: + - name: eth0 + mode: disable + location: + elin: "0000000911" + state: merged + + - assert: + that: + - result.changed == true + + - name: Merge LLDP interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_lldp_interfaces: *id002 + + - name: Assert idempotent + assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/overridden.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/overridden.yaml new file mode 100644 index 0000000..4bc0a94 --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/overridden.yaml @@ -0,0 +1,32 @@ +--- +- debug: + msg: START vyos_lldp_interfaces overridden integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Override LLDP interface configuration + register: result + vyos.rest.vyos_lldp_interfaces: &id001 + config: + - name: eth0 + mode: rx-tx + state: overridden + + - assert: + that: + - result.changed == true + + - name: Override LLDP interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_lldp_interfaces: *id001 + + - name: Assert idempotent + assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/replaced.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/replaced.yaml new file mode 100644 index 0000000..bc9542b --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/replaced.yaml @@ -0,0 +1,34 @@ +--- +- debug: + msg: START vyos_lldp_interfaces replaced integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Replace LLDP interface configuration + register: result + vyos.rest.vyos_lldp_interfaces: &id001 + config: + - name: eth0 + mode: rx-tx + location: + elin: "9876543210" + state: replaced + + - assert: + that: + - result.changed == true + + - name: Replace LLDP interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_lldp_interfaces: *id001 + + - name: Assert idempotent + assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..44ad3c7 --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/httpapi/rtt.yaml @@ -0,0 +1,55 @@ +--- +- debug: + msg: START vyos_lldp_interfaces round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: Ensure LLDP service is enabled + vyos.rest.vyos_configure: + commands: + - "set service lldp" + + - name: RTT - Apply base configuration + vyos.rest.vyos_lldp_interfaces: + config: + - name: eth0 + mode: disable + location: + elin: "1234567890" + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_lldp_interfaces: + state: gathered + + - name: RTT - Assert gathered matches applied + assert: + that: + - gathered.gathered | selectattr('name', 'eq', 'eth0') | list | length == 1 + - gathered.gathered | selectattr('name', 'eq', 'eth0') | map(attribute='mode') | first == 'disable' + - gathered.gathered | selectattr('name', 'eq', 'eth0') | map(attribute='location') | map(attribute='elin') | first == '1234567890' + + - name: RTT - Modify configuration + vyos.rest.vyos_lldp_interfaces: + config: + - name: eth0 + mode: rx-tx + location: + elin: "9876543210" + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_lldp_interfaces: + state: gathered + + - name: RTT - Assert modification applied correctly + assert: + that: + - gathered2.gathered | selectattr('name', 'eq', 'eth0') | map(attribute='mode') | first == 'rx-tx' + - gathered2.gathered | selectattr('name', 'eq', 'eth0') | map(attribute='location') | map(attribute='elin') | first == '9876543210' + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_interfaces/vars/main.yaml b/tests/integration/targets/vyos_lldp_interfaces/vars/main.yaml new file mode 100644 index 0000000..4303881 --- /dev/null +++ b/tests/integration/targets/vyos_lldp_interfaces/vars/main.yaml @@ -0,0 +1,2 @@ +--- +# only common vars here diff --git a/tests/integration/targets/vyos_logging_global/tests/httpapi/_populate_config.yaml b/tests/integration/targets/vyos_logging_global/tests/httpapi/_populate_config.yaml index c081853..548038d 100644 --- a/tests/integration/targets/vyos_logging_global/tests/httpapi/_populate_config.yaml +++ b/tests/integration/targets/vyos_logging_global/tests/httpapi/_populate_config.yaml @@ -6,12 +6,6 @@ facilities: - facility: local7 severity: err - hosts: - - hostname: 172.16.0.1 - port: 514 - facilities: - - facility: local7 - severity: all global_params: facilities: - facility: cron diff --git a/tests/integration/targets/vyos_logging_global/tests/httpapi/overridden.yaml b/tests/integration/targets/vyos_logging_global/tests/httpapi/overridden.yaml new file mode 100644 index 0000000..76867cc --- /dev/null +++ b/tests/integration/targets/vyos_logging_global/tests/httpapi/overridden.yaml @@ -0,0 +1,37 @@ +--- +- debug: + msg: START vyos_logging_global overridden integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Override logging_global configuration + register: result + vyos.rest.vyos_logging_global: &id001 + config: + console: + facilities: + - facility: local7 + severity: warning + global_params: + facilities: + - facility: cron + severity: debug + state: replaced + + - assert: + that: + - result.changed == true + + - name: Override logging_global configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_logging_global: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_logging_global/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_logging_global/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..8bea580 --- /dev/null +++ b/tests/integration/targets/vyos_logging_global/tests/httpapi/rtt.yaml @@ -0,0 +1,58 @@ +--- +- debug: + msg: START vyos_logging_global round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: RTT - Apply base configuration + vyos.rest.vyos_logging_global: + config: + console: + facilities: + - facility: local7 + severity: err + global_params: + facilities: + - facility: cron + severity: debug + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_logging_global: + state: gathered + + - name: RTT - Assert gathered matches applied + assert: + that: + - gathered.gathered.console is defined + - gathered.gathered.global is defined + + - name: RTT - Modify configuration + vyos.rest.vyos_logging_global: + config: + console: + facilities: + - facility: local7 + severity: warning + global_params: + facilities: + - facility: cron + severity: info + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_logging_global: + state: gathered + + - name: RTT - Assert modification applied correctly + assert: + that: + - gathered2.gathered.console is defined + - gathered2.gathered.global is defined + - gathered2.gathered.global.facilities.cron == "info" + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ntp_global/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_ntp_global/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..d05e203 --- /dev/null +++ b/tests/integration/targets/vyos_ntp_global/tests/httpapi/rtt.yaml @@ -0,0 +1,65 @@ +--- +- debug: + msg: START vyos_ntp_global round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: RTT - Apply base configuration + vyos.rest.vyos_ntp_global: + config: + servers: + - server: 10.3.6.5 + options: + - noselect + - prefer + - server: server4.example.com + options: + - pool + allow_clients: + - 10.4.9.0/24 + listen_addresses: + - 10.1.9.16 + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_ntp_global: + state: gathered + + - name: RTT - Assert gathered matches applied + assert: + that: + - "'10.3.6.5' in gathered.gathered.servers" + - "'10.4.9.0/24' in gathered.gathered.allow_clients" + - "'10.1.9.16' in gathered.gathered.listen_addresses" + + - name: RTT - Modify configuration + vyos.rest.vyos_ntp_global: + config: + servers: + - server: 10.3.6.5 + options: + - noselect + - server: server5.example.com + allow_clients: + - 10.4.8.0/24 + listen_addresses: + - 10.1.9.16 + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_ntp_global: + state: gathered + + - name: RTT - Assert modification applied correctly + assert: + that: + - "'server5.example.com' in gathered2.gathered.servers" + - "'server4.example.com' not in gathered2.gathered.servers" + - "'10.4.8.0/24' in gathered2.gathered.allow_clients" + - "'10.4.9.0/24' not in gathered2.gathered.allow_clients" + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospf_interfaces/aliases b/tests/integration/targets/vyos_ospf_interfaces/aliases new file mode 100644 index 0000000..cc0afef --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/aliases @@ -0,0 +1 @@ +network/vyos diff --git a/tests/integration/targets/vyos_ospf_interfaces/defaults/main.yaml b/tests/integration/targets/vyos_ospf_interfaces/defaults/main.yaml new file mode 100644 index 0000000..164afea --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/tests/integration/targets/vyos_ospf_interfaces/tasks/httpapi.yaml b/tests/integration/targets/vyos_ospf_interfaces/tasks/httpapi.yaml new file mode 100644 index 0000000..4147e6d --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/tasks/httpapi.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect all httpapi test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/httpapi" + patterns: "{{ testcase }}.yaml" + use_regex: true + register: test_cases + delegate_to: localhost + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + vars: + ansible_connection: ansible.netcommon.httpapi + ansible_network_os: vyos.rest.vyos + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_ospf_interfaces/tasks/main.yaml b/tests/integration/targets/vyos_ospf_interfaces/tasks/main.yaml new file mode 100644 index 0000000..b1f6193 --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Run httpapi tests + ansible.builtin.include_tasks: httpapi.yaml + tags: + - httpapi diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/_populate_config.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/_populate_config.yaml new file mode 100644 index 0000000..cee0e3e --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/_populate_config.yaml @@ -0,0 +1,19 @@ +--- +- name: Populate ospf_interfaces config for testing + vyos.rest.vyos_ospf_interfaces: + config: + - name: eth1 + address_family: + - afi: ipv4 + cost: 100 + transmit_delay: 50 + priority: 26 + - afi: ipv6 + dead_interval: 39 + passive: true + - name: eth2 + address_family: + - afi: ipv4 + cost: 200 + state: merged + ignore_errors: true diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/_remove_config.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/_remove_config.yaml new file mode 100644 index 0000000..ed1b31b --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/_remove_config.yaml @@ -0,0 +1,5 @@ +--- +- name: Remove pre-existing ospf_interfaces config + vyos.rest.vyos_ospf_interfaces: + state: deleted + ignore_errors: true diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/deleted.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/deleted.yaml new file mode 100644 index 0000000..09ce0de --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/deleted.yaml @@ -0,0 +1,40 @@ +--- +- debug: + msg: START vyos_ospf_interfaces deleted integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Delete specific interface OSPF configuration + register: result + vyos.rest.vyos_ospf_interfaces: + config: + - name: eth1 + state: deleted + + - assert: + that: + - result.changed == true + + - name: Delete all OSPF interface configuration + register: result + vyos.rest.vyos_ospf_interfaces: + state: deleted + + - assert: + that: + - result.changed == true + + - name: Delete all OSPF interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_ospf_interfaces: + state: deleted + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/gathered.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/gathered.yaml new file mode 100644 index 0000000..13eaa25 --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/gathered.yaml @@ -0,0 +1,20 @@ +--- +- debug: + msg: START vyos_ospf_interfaces gathered integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Gather OSPF interface configuration + register: result + vyos.rest.vyos_ospf_interfaces: + state: gathered + + - assert: + that: + - result.gathered | selectattr('name', 'eq', 'eth1') | list | length == 1 + - result.gathered | selectattr('name', 'eq', 'eth2') | list | length == 1 + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/merged.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/merged.yaml new file mode 100644 index 0000000..f9fcd27 --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/merged.yaml @@ -0,0 +1,44 @@ +--- +- debug: + msg: START vyos_ospf_interfaces merged integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: Merge OSPF interface configuration + register: result + vyos.rest.vyos_ospf_interfaces: + config: + - name: eth1 + address_family: + - afi: ipv4 + cost: 100 + transmit_delay: 50 + - afi: ipv6 + dead_interval: 39 + state: merged + + - assert: + that: + - result.changed == true + + - name: Merge OSPF interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_ospf_interfaces: + config: + - name: eth1 + address_family: + - afi: ipv4 + cost: 100 + transmit_delay: 50 + - afi: ipv6 + dead_interval: 39 + state: merged + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/overridden.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/overridden.yaml new file mode 100644 index 0000000..9a57bf7 --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/overridden.yaml @@ -0,0 +1,33 @@ +--- +- debug: + msg: START vyos_ospf_interfaces overridden integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Override OSPF interface configuration + register: result + vyos.rest.vyos_ospf_interfaces: &id001 + config: + - name: eth1 + address_family: + - afi: ipv4 + cost: 300 + state: overridden + + - assert: + that: + - result.changed == true + + - name: Override OSPF interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_ospf_interfaces: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/replaced.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/replaced.yaml new file mode 100644 index 0000000..359c647 --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/replaced.yaml @@ -0,0 +1,35 @@ +--- +- debug: + msg: START vyos_ospf_interfaces replaced integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Replace OSPF interface configuration + register: result + vyos.rest.vyos_ospf_interfaces: &id001 + config: + - name: eth1 + address_family: + - afi: ipv4 + cost: 200 + - afi: ipv6 + passive: true + state: replaced + + - assert: + that: + - result.changed == true + + - name: Replace OSPF interface configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_ospf_interfaces: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..1997870 --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/tests/httpapi/rtt.yaml @@ -0,0 +1,66 @@ +--- +- debug: + msg: START vyos_ospf_interfaces round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: RTT - Apply base configuration + vyos.rest.vyos_ospf_interfaces: + config: + - name: eth1 + address_family: + - afi: ipv4 + cost: 100 + transmit_delay: 50 + - afi: ipv6 + dead_interval: 39 + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_ospf_interfaces: + state: gathered + + - name: RTT - Assert gathered matches applied + vars: + eth1_afs: >- + {{ gathered.gathered + | selectattr('name', 'eq', 'eth1') + | map(attribute='address_family') + | first }} + assert: + that: + - gathered.gathered | selectattr('name', 'eq', 'eth1') | list | length == 1 + - eth1_afs | selectattr('afi', 'eq', 'ipv4') | map(attribute='cost') | first == 100 + + - name: RTT - Modify configuration + vyos.rest.vyos_ospf_interfaces: + config: + - name: eth1 + address_family: + - afi: ipv4 + cost: 200 + - afi: ipv6 + passive: true + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_ospf_interfaces: + state: gathered + + - name: RTT - Assert modification applied correctly + vars: + eth1_afs2: >- + {{ gathered2.gathered + | selectattr('name', 'eq', 'eth1') + | map(attribute='address_family') + | first }} + assert: + that: + - eth1_afs2 | selectattr('afi', 'eq', 'ipv4') | map(attribute='cost') | first == 200 + - eth1_afs2 | selectattr('afi', 'eq', 'ipv6') | map(attribute='passive') | first == true + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospf_interfaces/vars/main.yaml b/tests/integration/targets/vyos_ospf_interfaces/vars/main.yaml new file mode 100644 index 0000000..4303881 --- /dev/null +++ b/tests/integration/targets/vyos_ospf_interfaces/vars/main.yaml @@ -0,0 +1,2 @@ +--- +# only common vars here diff --git a/tests/integration/targets/vyos_ospfv2/aliases b/tests/integration/targets/vyos_ospfv2/aliases new file mode 100644 index 0000000..cc0afef --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/aliases @@ -0,0 +1 @@ +network/vyos diff --git a/tests/integration/targets/vyos_ospfv2/defaults/main.yaml b/tests/integration/targets/vyos_ospfv2/defaults/main.yaml new file mode 100644 index 0000000..164afea --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/tests/integration/targets/vyos_ospfv2/tasks/httpapi.yaml b/tests/integration/targets/vyos_ospfv2/tasks/httpapi.yaml new file mode 100644 index 0000000..4147e6d --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/tasks/httpapi.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect all httpapi test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/httpapi" + patterns: "{{ testcase }}.yaml" + use_regex: true + register: test_cases + delegate_to: localhost + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + vars: + ansible_connection: ansible.netcommon.httpapi + ansible_network_os: vyos.rest.vyos + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_ospfv2/tasks/main.yaml b/tests/integration/targets/vyos_ospfv2/tasks/main.yaml new file mode 100644 index 0000000..b1f6193 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Run httpapi tests + ansible.builtin.include_tasks: httpapi.yaml + tags: + - httpapi diff --git a/tests/integration/targets/vyos_ospfv2/tests/httpapi/_populate_config.yaml b/tests/integration/targets/vyos_ospfv2/tests/httpapi/_populate_config.yaml new file mode 100644 index 0000000..67aa729 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/tests/httpapi/_populate_config.yaml @@ -0,0 +1,34 @@ +--- +- name: Populate ospfv2 config for testing + vyos.rest.vyos_ospfv2: + config: + parameters: + router_id: 192.0.1.1 + abr_type: cisco + auto_cost: + reference_bandwidth: 2 + log_adjacency_changes: detail + redistribute: + - route_type: bgp + metric: 10 + passive_interface: + - eth1 + areas: + - area_id: "2" + area_type: + normal: true + network: + - address: 192.0.2.0/24 + - area_id: "3" + area_type: + nssa: + set: true + - area_id: "4" + area_type: + stub: + default_cost: 20 + range: + - address: 192.0.3.0/24 + cost: 10 + state: merged + ignore_errors: true diff --git a/tests/integration/targets/vyos_ospfv2/tests/httpapi/_remove_config.yaml b/tests/integration/targets/vyos_ospfv2/tests/httpapi/_remove_config.yaml new file mode 100644 index 0000000..171ab62 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/tests/httpapi/_remove_config.yaml @@ -0,0 +1,5 @@ +--- +- name: Remove pre-existing ospfv2 config + vyos.rest.vyos_ospfv2: + state: deleted + ignore_errors: true diff --git a/tests/integration/targets/vyos_ospfv2/tests/httpapi/deleted.yaml b/tests/integration/targets/vyos_ospfv2/tests/httpapi/deleted.yaml new file mode 100644 index 0000000..f656d4a --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/tests/httpapi/deleted.yaml @@ -0,0 +1,29 @@ +--- +- debug: + msg: START vyos_ospfv2 deleted integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Delete OSPFv2 configuration + register: result + vyos.rest.vyos_ospfv2: + state: deleted + + - assert: + that: + - result.changed == true + + - name: Delete OSPFv2 configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_ospfv2: + state: deleted + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv2/tests/httpapi/gathered.yaml b/tests/integration/targets/vyos_ospfv2/tests/httpapi/gathered.yaml new file mode 100644 index 0000000..9b06985 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/tests/httpapi/gathered.yaml @@ -0,0 +1,22 @@ +--- +- debug: + msg: START vyos_ospfv2 gathered integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Gather OSPFv2 configuration + register: result + vyos.rest.vyos_ospfv2: + state: gathered + + - assert: + that: + - result.gathered.parameters.router_id == "192.0.1.1" + - result.gathered.areas | selectattr('area_id', 'eq', '2') | list | length == 1 + - result.gathered.redistribute | selectattr('route_type', 'eq', 'bgp') | list | length == 1 + - "'eth1' in result.gathered.passive_interface" + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv2/tests/httpapi/merged.yaml b/tests/integration/targets/vyos_ospfv2/tests/httpapi/merged.yaml new file mode 100644 index 0000000..db07c48 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/tests/httpapi/merged.yaml @@ -0,0 +1,56 @@ +--- +- debug: + msg: START vyos_ospfv2 merged integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: Merge OSPFv2 configuration + register: result + vyos.rest.vyos_ospfv2: + config: + parameters: + router_id: 192.0.1.1 + auto_cost: + reference_bandwidth: 2 + areas: + - area_id: "2" + area_type: + normal: true + network: + - address: 192.0.2.0/24 + redistribute: + - route_type: bgp + metric: 10 + state: merged + + - assert: + that: + - result.changed == true + + - name: Merge OSPFv2 configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_ospfv2: + config: + parameters: + router_id: 192.0.1.1 + auto_cost: + reference_bandwidth: 2 + areas: + - area_id: "2" + area_type: + normal: true + network: + - address: 192.0.2.0/24 + redistribute: + - route_type: bgp + metric: 10 + state: merged + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv2/tests/httpapi/overridden.yaml b/tests/integration/targets/vyos_ospfv2/tests/httpapi/overridden.yaml new file mode 100644 index 0000000..a364c0f --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/tests/httpapi/overridden.yaml @@ -0,0 +1,37 @@ +--- +- debug: + msg: START vyos_ospfv2 overridden integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Override OSPFv2 configuration + register: result + vyos.rest.vyos_ospfv2: &id001 + config: + parameters: + router_id: 192.0.1.2 + areas: + - area_id: "2" + area_type: + normal: true + network: + - address: 192.0.2.0/24 + state: replaced + + - assert: + that: + - result.changed == true + + - name: Override OSPFv2 configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_ospfv2: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv2/tests/httpapi/replaced.yaml b/tests/integration/targets/vyos_ospfv2/tests/httpapi/replaced.yaml new file mode 100644 index 0000000..7a58000 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/tests/httpapi/replaced.yaml @@ -0,0 +1,37 @@ +--- +- debug: + msg: START vyos_ospfv2 replaced integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Replace OSPFv2 configuration + register: result + vyos.rest.vyos_ospfv2: &id001 + config: + parameters: + router_id: 192.0.1.2 + areas: + - area_id: "2" + area_type: + normal: true + network: + - address: 192.0.2.0/24 + state: replaced + + - assert: + that: + - result.changed == true + + - name: Replace OSPFv2 configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_ospfv2: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv2/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_ospfv2/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..be2a3c9 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/tests/httpapi/rtt.yaml @@ -0,0 +1,61 @@ +--- +- debug: + msg: START vyos_ospfv2 round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: RTT - Apply base configuration + vyos.rest.vyos_ospfv2: + config: + parameters: + router_id: 192.0.1.1 + redistribute: + - route_type: bgp + metric: 10 + areas: + - area_id: "2" + area_type: + normal: true + network: + - address: 192.0.2.0/24 + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_ospfv2: + state: gathered + + - name: RTT - Assert gathered matches applied + assert: + that: + - gathered.gathered.parameters.router_id == "192.0.1.1" + - gathered.gathered.areas | selectattr('area_id', 'eq', '2') | list | length == 1 + - gathered.gathered.redistribute | selectattr('route_type', 'eq', 'bgp') | list | length == 1 + + - name: RTT - Modify configuration + vyos.rest.vyos_ospfv2: + config: + parameters: + router_id: 192.0.1.2 + areas: + - area_id: "2" + area_type: + normal: true + network: + - address: 192.0.2.0/24 + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_ospfv2: + state: gathered + + - name: RTT - Assert modification applied correctly + assert: + that: + - gathered2.gathered.parameters.router_id == "192.0.1.2" + - gathered2.gathered.redistribute is not defined or gathered2.gathered.redistribute | length == 0 + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv2/vars/main.yaml b/tests/integration/targets/vyos_ospfv2/vars/main.yaml new file mode 100644 index 0000000..4303881 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv2/vars/main.yaml @@ -0,0 +1,2 @@ +--- +# only common vars here diff --git a/tests/integration/targets/vyos_ospfv3/aliases b/tests/integration/targets/vyos_ospfv3/aliases new file mode 100644 index 0000000..cc0afef --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/aliases @@ -0,0 +1 @@ +network/vyos diff --git a/tests/integration/targets/vyos_ospfv3/defaults/main.yaml b/tests/integration/targets/vyos_ospfv3/defaults/main.yaml new file mode 100644 index 0000000..164afea --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/tests/integration/targets/vyos_ospfv3/tasks/httpapi.yaml b/tests/integration/targets/vyos_ospfv3/tasks/httpapi.yaml new file mode 100644 index 0000000..4147e6d --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tasks/httpapi.yaml @@ -0,0 +1,21 @@ +--- +- name: Collect all httpapi test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/httpapi" + patterns: "{{ testcase }}.yaml" + use_regex: true + register: test_cases + delegate_to: localhost + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + vars: + ansible_connection: ansible.netcommon.httpapi + ansible_network_os: vyos.rest.vyos + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_ospfv3/tasks/main.yaml b/tests/integration/targets/vyos_ospfv3/tasks/main.yaml new file mode 100644 index 0000000..b1f6193 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Run httpapi tests + ansible.builtin.include_tasks: httpapi.yaml + tags: + - httpapi diff --git a/tests/integration/targets/vyos_ospfv3/tests/httpapi/_populate_config.yaml b/tests/integration/targets/vyos_ospfv3/tests/httpapi/_populate_config.yaml new file mode 100644 index 0000000..19a61c7 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/httpapi/_populate_config.yaml @@ -0,0 +1,17 @@ +--- +- name: Populate ospfv3 config for testing + vyos.rest.vyos_ospfv3: + config: + parameters: + router_id: 192.0.2.10 + redistribute: + - route_type: bgp + areas: + - area_id: "2" + export_list: export1 + import_list: import1 + range: + - address: "2001:db10::/32" + - address: "2001:db20::/32" + state: merged + ignore_errors: true diff --git a/tests/integration/targets/vyos_ospfv3/tests/httpapi/_remove_config.yaml b/tests/integration/targets/vyos_ospfv3/tests/httpapi/_remove_config.yaml new file mode 100644 index 0000000..fe60eaf --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/httpapi/_remove_config.yaml @@ -0,0 +1,5 @@ +--- +- name: Remove pre-existing ospfv3 config + vyos.rest.vyos_ospfv3: + state: deleted + ignore_errors: true diff --git a/tests/integration/targets/vyos_ospfv3/tests/httpapi/deleted.yaml b/tests/integration/targets/vyos_ospfv3/tests/httpapi/deleted.yaml new file mode 100644 index 0000000..9b09ccd --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/httpapi/deleted.yaml @@ -0,0 +1,29 @@ +--- +- debug: + msg: START vyos_ospfv3 deleted integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Delete OSPFv3 configuration + register: result + vyos.rest.vyos_ospfv3: + state: deleted + + - assert: + that: + - result.changed == true + + - name: Delete OSPFv3 configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_ospfv3: + state: deleted + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv3/tests/httpapi/gathered.yaml b/tests/integration/targets/vyos_ospfv3/tests/httpapi/gathered.yaml new file mode 100644 index 0000000..bf2cc0c --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/httpapi/gathered.yaml @@ -0,0 +1,21 @@ +--- +- debug: + msg: START vyos_ospfv3 gathered integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Gather OSPFv3 configuration + register: result + vyos.rest.vyos_ospfv3: + state: gathered + + - assert: + that: + - result.gathered.parameters.router_id == "192.0.2.10" + - result.gathered.redistribute | selectattr('route_type', 'eq', 'bgp') | list | length == 1 + - result.gathered.areas | selectattr('area_id', 'eq', '2') | list | length == 1 + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv3/tests/httpapi/merged.yaml b/tests/integration/targets/vyos_ospfv3/tests/httpapi/merged.yaml new file mode 100644 index 0000000..10702e4 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/httpapi/merged.yaml @@ -0,0 +1,48 @@ +--- +- debug: + msg: START vyos_ospfv3 merged integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: Merge OSPFv3 configuration + register: result + vyos.rest.vyos_ospfv3: + config: + parameters: + router_id: 192.0.2.10 + redistribute: + - route_type: bgp + areas: + - area_id: "2" + export_list: export1 + range: + - address: "2001:db10::/32" + state: merged + + - assert: + that: + - result.changed == true + + - name: Merge OSPFv3 configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_ospfv3: + config: + parameters: + router_id: 192.0.2.10 + redistribute: + - route_type: bgp + areas: + - area_id: "2" + export_list: export1 + range: + - address: "2001:db10::/32" + state: merged + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv3/tests/httpapi/overridden.yaml b/tests/integration/targets/vyos_ospfv3/tests/httpapi/overridden.yaml new file mode 100644 index 0000000..609e7ff --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/httpapi/overridden.yaml @@ -0,0 +1,35 @@ +--- +- debug: + msg: START vyos_ospfv3 overridden integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Override OSPFv3 configuration + register: result + vyos.rest.vyos_ospfv3: &id001 + config: + parameters: + router_id: 192.0.2.11 + areas: + - area_id: "3" + range: + - address: "2001:db40::/32" + state: replaced + + - assert: + that: + - result.changed == true + + - name: Override OSPFv3 configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_ospfv3: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv3/tests/httpapi/replaced.yaml b/tests/integration/targets/vyos_ospfv3/tests/httpapi/replaced.yaml new file mode 100644 index 0000000..3f1be83 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/httpapi/replaced.yaml @@ -0,0 +1,35 @@ +--- +- debug: + msg: START vyos_ospfv3 replaced integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Replace OSPFv3 configuration + register: result + vyos.rest.vyos_ospfv3: &id001 + config: + parameters: + router_id: 192.0.2.11 + areas: + - area_id: "3" + range: + - address: "2001:db40::/32" + state: replaced + + - assert: + that: + - result.changed == true + + - name: Replace OSPFv3 configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_ospfv3: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv3/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_ospfv3/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..7636c23 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/httpapi/rtt.yaml @@ -0,0 +1,60 @@ +--- +- debug: + msg: START vyos_ospfv3 round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: RTT - Apply base configuration + vyos.rest.vyos_ospfv3: + config: + parameters: + router_id: 192.0.2.10 + redistribute: + - route_type: bgp + areas: + - area_id: "2" + export_list: export1 + range: + - address: "2001:db10::/32" + - address: "2001:db20::/32" + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_ospfv3: + state: gathered + + - name: RTT - Assert gathered matches applied + assert: + that: + - gathered.gathered.parameters.router_id == "192.0.2.10" + - "'bgp' in gathered.gathered.redistribute | map(attribute='route_type') | list" + - gathered.gathered.areas | selectattr('area_id', 'eq', '2') | list | length == 1 + + - name: RTT - Modify configuration + vyos.rest.vyos_ospfv3: + config: + parameters: + router_id: 192.0.2.11 + areas: + - area_id: "2" + export_list: export1 + range: + - address: "2001:db10::/32" + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_ospfv3: + state: gathered + + - name: RTT - Assert modification applied correctly + assert: + that: + - gathered2.gathered.parameters.router_id == "192.0.2.11" + - gathered2.gathered.redistribute is not defined or gathered2.gathered.redistribute | length == 0 + - gathered2.gathered.areas | selectattr('area_id', 'eq', '2') | map(attribute='range') | first | length == 1 + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv3/vars/main.yaml b/tests/integration/targets/vyos_ospfv3/vars/main.yaml new file mode 100644 index 0000000..4303881 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/vars/main.yaml @@ -0,0 +1,2 @@ +--- +# only common vars here diff --git a/tests/integration/targets/vyos_prefix_lists/tests/httpapi/_populate_config.yaml b/tests/integration/targets/vyos_prefix_lists/tests/httpapi/_populate_config.yaml deleted file mode 100644 index 9d73f0b..0000000 --- a/tests/integration/targets/vyos_prefix_lists/tests/httpapi/_populate_config.yaml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- name: Populate prefix_lists config for testing - vyos.rest.vyos_prefix_lists: - config: - - afi: ipv4 - prefix_lists: - - name: AnsibleIPv4PrefixList - description: PL configured by ansible - entries: - - sequence: 2 - action: permit - prefix: 92.168.10.0/26 - le: 32 - - sequence: 3 - action: deny - prefix: 72.168.2.0/24 - ge: 26 - - afi: ipv6 - prefix_lists: - - name: AllowIPv6Prefix - description: Configured by ansible for allowing IPv6 networks - entries: - - sequence: 5 - action: permit - prefix: 2001:db8:8000::/35 - le: 37 - state: merged - ignore_errors: true diff --git a/tests/integration/targets/vyos_prefix_lists/tests/httpapi/_remove_config.yaml b/tests/integration/targets/vyos_prefix_lists/tests/httpapi/_remove_config.yaml deleted file mode 100644 index 043fb3e..0000000 --- a/tests/integration/targets/vyos_prefix_lists/tests/httpapi/_remove_config.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: Remove pre-existing prefix_lists config - vyos.rest.vyos_prefix_lists: - state: deleted - ignore_errors: true diff --git a/tests/integration/targets/vyos_route_maps/tests/httpapi/overridden.yaml b/tests/integration/targets/vyos_route_maps/tests/httpapi/overridden.yaml new file mode 100644 index 0000000..cbe3908 --- /dev/null +++ b/tests/integration/targets/vyos_route_maps/tests/httpapi/overridden.yaml @@ -0,0 +1,40 @@ +--- +- debug: + msg: START vyos_route_maps overridden integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Override route_maps configuration + register: result + vyos.rest.vyos_route_maps: &id001 + config: + - route_map: RM-TEST-EXPORT-POLICY + entries: + - sequence: 10 + action: permit + match: + peer: 192.0.2.32 + set: + metric: "10" + as_path_exclude: "111" + aggregator: + as: 100 + state: overridden + + - assert: + that: + - result.changed == true + + - name: Override route_maps configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_route_maps: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_route_maps/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_route_maps/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..641a46f --- /dev/null +++ b/tests/integration/targets/vyos_route_maps/tests/httpapi/rtt.yaml @@ -0,0 +1,53 @@ +--- +- debug: + msg: START vyos_route_maps round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: RTT - Apply base configuration + vyos.rest.vyos_route_maps: + config: + - route_map: RM-TEST-EXPORT-POLICY + entries: + - sequence: 10 + action: permit + match: + peer: 192.0.2.32 + set: + metric: "5" + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_route_maps: + state: gathered + + - name: RTT - Assert gathered matches applied + assert: + that: + - gathered.gathered | selectattr('route_map', 'eq', 'RM-TEST-EXPORT-POLICY') | list | length == 1 + + - name: RTT - Modify configuration + vyos.rest.vyos_route_maps: + config: + - route_map: RM-TEST-EXPORT-POLICY + entries: + - sequence: 10 + action: permit + set: + metric: "20" + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_route_maps: + state: gathered + + - name: RTT - Assert modification applied correctly + assert: + that: + - gathered2.gathered | selectattr('route_map', 'eq', 'RM-TEST-EXPORT-POLICY') | list | length == 1 + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_snmp_server/tests/httpapi/overridden.yaml b/tests/integration/targets/vyos_snmp_server/tests/httpapi/overridden.yaml new file mode 100644 index 0000000..61a3311 --- /dev/null +++ b/tests/integration/targets/vyos_snmp_server/tests/httpapi/overridden.yaml @@ -0,0 +1,35 @@ +--- +- debug: + msg: START vyos_snmp_server overridden integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml +- include_tasks: _populate_config.yaml + +- block: + - name: Override snmp_server configuration + register: result + vyos.rest.vyos_snmp_server: &id001 + config: + communities: + - name: switches + authorization_type: rw + contact: admin@example.com + listen_addresses: + - address: 20.1.1.1 + state: replaced + + - assert: + that: + - result.changed == true + + - name: Override snmp_server configuration (IDEMPOTENT) + register: result + vyos.rest.vyos_snmp_server: *id001 + + - assert: + that: + - result.changed == false + - result.commands == [] + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_snmp_server/tests/httpapi/rtt.yaml b/tests/integration/targets/vyos_snmp_server/tests/httpapi/rtt.yaml new file mode 100644 index 0000000..1d354b7 --- /dev/null +++ b/tests/integration/targets/vyos_snmp_server/tests/httpapi/rtt.yaml @@ -0,0 +1,53 @@ +--- +- debug: + msg: START vyos_snmp_server round trip integration tests on connection={{ ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: RTT - Apply base configuration + vyos.rest.vyos_snmp_server: + config: + communities: + - name: switches + authorization_type: rw + contact: admin@example.com + listen_addresses: + - address: 20.1.1.1 + state: merged + + - name: RTT - Gather configuration + register: gathered + vyos.rest.vyos_snmp_server: + state: gathered + + - name: RTT - Assert gathered matches applied + assert: + that: + - gathered.gathered.contact == "admin@example.com" + - gathered.gathered.communities | selectattr('name', 'eq', 'switches') | list | length == 1 + + - name: RTT - Modify configuration + vyos.rest.vyos_snmp_server: + config: + communities: + - name: switches + authorization_type: ro + contact: ops@example.com + listen_addresses: + - address: 20.1.1.1 + state: replaced + + - name: RTT - Gather modified configuration + register: gathered2 + vyos.rest.vyos_snmp_server: + state: gathered + + - name: RTT - Assert modification applied correctly + assert: + that: + - gathered2.gathered.contact == "ops@example.com" + - gathered2.gathered.communities | selectattr('name', 'eq', 'switches') | map(attribute='authorization_type') | first == 'ro' + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/unit/fixtures/interfaces_running.json b/tests/unit/fixtures/interfaces_running.json new file mode 100644 index 0000000..ee67fa2 --- /dev/null +++ b/tests/unit/fixtures/interfaces_running.json @@ -0,0 +1,15 @@ +{ + "ethernet": { + "eth0": { + "address": "dhcp", + "description": "Management", + "duplex": "auto", + "hw-id": "52:54:00:65:5a:24", + "mtu": "1500", + "speed": "auto" + } + }, + "loopback": { + "lo": {} + } +} diff --git a/tests/unit/fixtures/l3_interfaces_running.json b/tests/unit/fixtures/l3_interfaces_running.json new file mode 100644 index 0000000..676055b --- /dev/null +++ b/tests/unit/fixtures/l3_interfaces_running.json @@ -0,0 +1,21 @@ +{ + "ethernet": { + "eth0": { + "address": "dhcp", + "hw-id": "52:54:00:65:5a:24", + "vif": { + "100": { + "address": "192.0.2.100/24" + } + } + } + }, + "loopback": { + "lo": { + "address": ["10.0.0.1/32", "10.0.0.2/32"] + } + }, + "dummy": { + "dummy0": {} + } +} diff --git a/tests/unit/fixtures/lag_interfaces_running.json b/tests/unit/fixtures/lag_interfaces_running.json new file mode 100644 index 0000000..3477b1d --- /dev/null +++ b/tests/unit/fixtures/lag_interfaces_running.json @@ -0,0 +1,12 @@ +{ + "bond0": { + "arp-monitor": { + "interval": "100", + "target": { + "192.0.2.1": {} + } + }, + "hash-policy": "layer2", + "mode": "active-backup" + } +} diff --git a/tests/unit/fixtures/lldp_interfaces_running.json b/tests/unit/fixtures/lldp_interfaces_running.json new file mode 100644 index 0000000..905a88d --- /dev/null +++ b/tests/unit/fixtures/lldp_interfaces_running.json @@ -0,0 +1,20 @@ +{ + "interface": { + "eth0": { + "location": { + "elin": "1234567890" + }, + "mode": "disable" + }, + "eth1": { + "location": { + "coordinate-based": { + "altitude": "2200", + "datum": "WGS84", + "latitude": "33.524449N", + "longitude": "22.267255E" + } + } + } + } +} diff --git a/tests/unit/fixtures/ospf_interfaces_ipv4.json b/tests/unit/fixtures/ospf_interfaces_ipv4.json new file mode 100644 index 0000000..1f199a6 --- /dev/null +++ b/tests/unit/fixtures/ospf_interfaces_ipv4.json @@ -0,0 +1,4 @@ +{ + "eth1": { "cost": "100", "transmit-delay": "50", "priority": "26" }, + "eth2": { "cost": "200" } +} diff --git a/tests/unit/fixtures/ospf_interfaces_ipv6.json b/tests/unit/fixtures/ospf_interfaces_ipv6.json new file mode 100644 index 0000000..580cecf --- /dev/null +++ b/tests/unit/fixtures/ospf_interfaces_ipv6.json @@ -0,0 +1,4 @@ +{ + "eth1": { "dead-interval": "39", "passive": {} }, + "eth2": {} +} diff --git a/tests/unit/fixtures/ospfv2_running.json b/tests/unit/fixtures/ospfv2_running.json new file mode 100644 index 0000000..9cc64a0 --- /dev/null +++ b/tests/unit/fixtures/ospfv2_running.json @@ -0,0 +1,42 @@ +{ + "area": { + "2": { + "area-type": { "normal": {} }, + "network": "192.0.2.0/24" + }, + "3": { + "area-type": { "nssa": {} } + }, + "4": { + "area-type": { "stub": { "default-cost": "20" } }, + "range": { + "192.0.3.0/24": { "cost": "10" }, + "192.0.4.0/24": {} + } + } + }, + "auto-cost": { "reference-bandwidth": "2" }, + "interface": { "eth1": { "passive": {} }, "eth2": { "passive": {} } }, + "log-adjacency-changes": { "detail": {} }, + "neighbor": { + "192.0.11.12": { "priority": "2", "poll-interval": "10" } + }, + "parameters": { + "router-id": "192.0.1.1", + "abr-type": "cisco", + "opaque-lsa": {}, + "rfc1583-compatibility": {} + }, + "redistribute": { + "bgp": { "metric": "10", "metric-type": "2" }, + "connected": {} + }, + "default-information": { + "originate": { + "always": {}, + "metric": "10", + "metric-type": "2", + "route-map": "ingress" + } + } +} diff --git a/tests/unit/fixtures/ospfv3_running.json b/tests/unit/fixtures/ospfv3_running.json new file mode 100644 index 0000000..44a1bcd --- /dev/null +++ b/tests/unit/fixtures/ospfv3_running.json @@ -0,0 +1,19 @@ +{ + "parameters": { "router-id": "192.0.2.10" }, + "redistribute": { "bgp": {}, "connected": { "route-map": "RM1" } }, + "area": { + "2": { + "export-list": "export1", + "import-list": "import1", + "range": { + "2001:db10::/32": {}, + "2001:db20::/32": { "not-advertise": {} } + } + }, + "3": { + "range": { + "2001:db40::/32": {} + } + } + } +} diff --git a/tests/unit/modules/test_vyos_interfaces.py b/tests/unit/modules/test_vyos_interfaces.py new file mode 100644 index 0000000..d522c81 --- /dev/null +++ b/tests/unit/modules/test_vyos_interfaces.py @@ -0,0 +1,315 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json +import os +import unittest + +from unittest.mock import MagicMock + +from ansible_collections.vyos.rest.plugins.modules.vyos_interfaces import ( + _delete_iface_config, + _iface_base, + _iface_cmds, + _iface_type, + build_commands, + get_running_config, +) + + +def load_fixture(filename): + fixtures_dir = os.path.join(os.path.dirname(__file__), "..", "fixtures") + path = os.path.join(fixtures_dir, filename) + with open(path) as f: + return json.load(f) + + +class VyOSModuleTestCase(unittest.TestCase): + def setUp(self): + self.mock_vyos = MagicMock() + self.mock_vyos.get_config = MagicMock(return_value={}) + + def set_running_config(self, data): + self.mock_vyos.get_config.return_value = data + + +class TestVyOSInterfacesIfaceType(unittest.TestCase): + + def test_eth_is_ethernet(self): + self.assertEqual(_iface_type("eth0"), "ethernet") + + def test_bond_is_bonding(self): + self.assertEqual(_iface_type("bond0"), "bonding") + + def test_lo_is_loopback(self): + self.assertEqual(_iface_type("lo"), "loopback") + + def test_wg_is_wireguard(self): + self.assertEqual(_iface_type("wg0"), "wireguard") + + def test_br_is_bridge(self): + self.assertEqual(_iface_type("br0"), "bridge") + + def test_unknown_defaults_to_ethernet(self): + self.assertEqual(_iface_type("xyz0"), "ethernet") + + def test_iface_base_ethernet(self): + self.assertEqual( + _iface_base("eth0"), + ["interfaces", "ethernet", "eth0"], + ) + + def test_iface_base_loopback(self): + self.assertEqual( + _iface_base("lo"), + ["interfaces", "loopback", "lo"], + ) + + +class TestVyOSInterfacesGetRunningFixture(VyOSModuleTestCase): + + def setUp(self): + super().setUp() + self.fixture = load_fixture("interfaces_running.json") + + def test_fixture_parses_eth0(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + eth0 = next(e for e in result if e["name"] == "eth0") + self.assertEqual(eth0["description"], "Management") + self.assertEqual(eth0["mtu"], 1500) + self.assertEqual(eth0["duplex"], "auto") + self.assertEqual(eth0["speed"], "auto") + self.assertTrue(eth0["enabled"]) + + def test_fixture_parses_loopback(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + lo = next(e for e in result if e["name"] == "lo") + self.assertTrue(lo["enabled"]) + self.assertNotIn("description", lo) + + def test_fixture_disabled_interface(self): + fixture = dict(self.fixture) + fixture["ethernet"]["eth1"] = {"disable": {}, "description": "Unused"} + self.set_running_config(fixture) + result = get_running_config(self.mock_vyos) + eth1 = next(e for e in result if e["name"] == "eth1") + self.assertFalse(eth1["enabled"]) + + +class TestVyOSInterfacesGetRunning(VyOSModuleTestCase): + + def test_empty_returns_empty_list(self): + self.set_running_config({}) + result = get_running_config(self.mock_vyos) + self.assertEqual(result, []) + + def test_mtu_cast_to_int(self): + self.set_running_config( + { + "ethernet": { + "eth0": {"mtu": "1500"}, + }, + }, + ) + result = get_running_config(self.mock_vyos) + eth0 = next(e for e in result if e["name"] == "eth0") + self.assertIsInstance(eth0["mtu"], int) + self.assertEqual(eth0["mtu"], 1500) + + def test_hw_id_not_included(self): + self.set_running_config( + { + "ethernet": { + "eth0": {"hw-id": "52:54:00:65:5a:24"}, + }, + }, + ) + result = get_running_config(self.mock_vyos) + eth0 = next(e for e in result if e["name"] == "eth0") + self.assertNotIn("hw_id", eth0) + self.assertNotIn("hw-id", eth0) + + def test_enabled_true_when_no_disable(self): + self.set_running_config( + { + "ethernet": {"eth0": {}}, + }, + ) + result = get_running_config(self.mock_vyos) + eth0 = next(e for e in result if e["name"] == "eth0") + self.assertTrue(eth0["enabled"]) + + def test_enabled_false_when_disable_present(self): + self.set_running_config( + { + "ethernet": {"eth0": {"disable": {}}}, + }, + ) + result = get_running_config(self.mock_vyos) + eth0 = next(e for e in result if e["name"] == "eth0") + self.assertFalse(eth0["enabled"]) + + +class TestVyOSInterfacesIfaceCmds(unittest.TestCase): + + def test_set_description(self): + want = {"description": "WAN", "enabled": True} + cmds = _iface_cmds("eth0", want, {}) + self.assertIn( + ("set", ["interfaces", "ethernet", "eth0", "description", "WAN"]), + cmds, + ) + + def test_set_mtu(self): + want = {"mtu": 9000, "enabled": True} + cmds = _iface_cmds("eth0", want, {}) + self.assertIn( + ("set", ["interfaces", "ethernet", "eth0", "mtu", "9000"]), + cmds, + ) + + def test_set_duplex(self): + want = {"duplex": "full", "enabled": True} + cmds = _iface_cmds("eth0", want, {}) + self.assertIn( + ("set", ["interfaces", "ethernet", "eth0", "duplex", "full"]), + cmds, + ) + + def test_set_speed(self): + want = {"speed": "1000", "enabled": True} + cmds = _iface_cmds("eth0", want, {}) + self.assertIn( + ("set", ["interfaces", "ethernet", "eth0", "speed", "1000"]), + cmds, + ) + + def test_disable_interface(self): + want = {"enabled": False} + have = {"enabled": True} + cmds = _iface_cmds("eth0", want, have) + self.assertIn( + ("set", ["interfaces", "ethernet", "eth0", "disable"]), + cmds, + ) + + def test_enable_interface(self): + want = {"enabled": True} + have = {"enabled": False} + cmds = _iface_cmds("eth0", want, have) + self.assertIn( + ("delete", ["interfaces", "ethernet", "eth0", "disable"]), + cmds, + ) + + def test_idempotent_description(self): + want = {"description": "WAN", "enabled": True} + have = {"description": "WAN", "enabled": True} + cmds = _iface_cmds("eth0", want, have) + self.assertEqual(cmds, []) + + def test_delete_description_when_none(self): + want = {"enabled": True} + have = {"description": "Old", "enabled": True} + cmds = _iface_cmds("eth0", want, have) + self.assertIn( + ("delete", ["interfaces", "ethernet", "eth0", "description"]), + cmds, + ) + + +class TestVyOSInterfacesDeleteIfaceConfig(unittest.TestCase): + + def test_deletes_all_l2_fields(self): + have = { + "description": "WAN", + "mtu": 1500, + "duplex": "auto", + "speed": "auto", + "enabled": True, + } + cmds = _delete_iface_config("eth0", have) + paths = [c[1] for c in cmds] + self.assertIn(["interfaces", "ethernet", "eth0", "description"], paths) + self.assertIn(["interfaces", "ethernet", "eth0", "mtu"], paths) + self.assertIn(["interfaces", "ethernet", "eth0", "duplex"], paths) + self.assertIn(["interfaces", "ethernet", "eth0", "speed"], paths) + + def test_deletes_disable_when_disabled(self): + have = {"enabled": False} + cmds = _delete_iface_config("eth0", have) + self.assertIn( + ("delete", ["interfaces", "ethernet", "eth0", "disable"]), + cmds, + ) + + def test_empty_have_produces_no_commands(self): + cmds = _delete_iface_config("eth0", {}) + self.assertEqual(cmds, []) + + +class TestVyOSInterfacesBuildCommands(unittest.TestCase): + + def _have_eth0(self): + return [ + { + "name": "eth0", + "description": "Management", + "mtu": 1500, + "enabled": True, + }, + ] + + def test_merged_adds_description(self): + config = [{"name": "eth0", "description": "WAN", "enabled": True}] + cmds = build_commands(config, [], "merged") + paths = [c[1] for c in cmds] + self.assertIn( + ["interfaces", "ethernet", "eth0", "description", "WAN"], + paths, + ) + + def test_merged_idempotent(self): + cmds = build_commands(self._have_eth0(), self._have_eth0(), "merged") + self.assertEqual(cmds, []) + + def test_deleted_removes_l2_fields(self): + config = [{"name": "eth0", "enabled": True}] + cmds = build_commands(config, self._have_eth0(), "deleted") + paths = [c[1] for c in cmds] + self.assertIn(["interfaces", "ethernet", "eth0", "description"], paths) + self.assertIn(["interfaces", "ethernet", "eth0", "mtu"], paths) + + def test_deleted_idempotent_when_no_l2(self): + have = [{"name": "eth0", "enabled": True}] + config = [{"name": "eth0", "enabled": True}] + cmds = build_commands(config, have, "deleted") + self.assertEqual(cmds, []) + + def test_replaced_idempotent(self): + cmds = build_commands(self._have_eth0(), self._have_eth0(), "replaced") + self.assertEqual(cmds, []) + + def test_replaced_updates_description(self): + config = [{"name": "eth0", "description": "NEW", "mtu": 1500, "enabled": True}] + cmds = build_commands(config, self._have_eth0(), "replaced") + self.assertTrue(len(cmds) > 0) + + def test_overridden_clears_interfaces_not_in_want(self): + have = [ + {"name": "eth0", "description": "Management", "enabled": True}, + {"name": "eth1", "description": "LAN", "enabled": True}, + ] + config = [{"name": "eth0", "description": "Management", "enabled": True}] + cmds = build_commands(config, have, "overridden") + paths = [c[1] for c in cmds] + self.assertIn(["interfaces", "ethernet", "eth1", "description"], paths) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/unit/modules/test_vyos_l3_interfaces.py b/tests/unit/modules/test_vyos_l3_interfaces.py new file mode 100644 index 0000000..66cd1fc --- /dev/null +++ b/tests/unit/modules/test_vyos_l3_interfaces.py @@ -0,0 +1,306 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json +import os +import unittest + +from unittest.mock import MagicMock + +from ansible_collections.vyos.rest.plugins.modules.vyos_l3_interfaces import ( + _addr_cmds, + _addr_list, + _normalize, + _parse_iface, + _split_addresses, + build_commands, + get_running_config, +) + + +def load_fixture(filename): + fixtures_dir = os.path.join(os.path.dirname(__file__), "..", "fixtures") + path = os.path.join(fixtures_dir, filename) + with open(path) as f: + return json.load(f) + + +class VyOSModuleTestCase(unittest.TestCase): + def setUp(self): + self.mock_vyos = MagicMock() + self.mock_vyos.get_config = MagicMock(return_value={}) + + def set_running_config(self, data): + self.mock_vyos.get_config.return_value = data + + +class TestVyOSL3InterfacesAddrList(unittest.TestCase): + + def test_string_returns_list(self): + self.assertEqual(_addr_list("dhcp"), ["dhcp"]) + + def test_list_returned_sorted(self): + result = _addr_list(["10.0.0.2/32", "10.0.0.1/32"]) + self.assertEqual(result, ["10.0.0.1/32", "10.0.0.2/32"]) + + def test_none_returns_empty(self): + self.assertEqual(_addr_list(None), []) + + def test_empty_list_returns_empty(self): + self.assertEqual(_addr_list([]), []) + + +class TestVyOSL3InterfacesSplitAddresses(unittest.TestCase): + + def test_dhcp_goes_to_ipv4(self): + ipv4, ipv6 = _split_addresses(["dhcp"]) + self.assertIn("dhcp", ipv4) + self.assertEqual(ipv6, []) + + def test_dhcpv6_goes_to_ipv6(self): + ipv4, ipv6 = _split_addresses(["dhcpv6"]) + self.assertEqual(ipv4, []) + self.assertIn("dhcpv6", ipv6) + + def test_ipv4_cidr(self): + ipv4, ipv6 = _split_addresses(["192.0.2.1/24"]) + self.assertIn("192.0.2.1/24", ipv4) + self.assertEqual(ipv6, []) + + def test_ipv6_cidr(self): + ipv4, ipv6 = _split_addresses(["2001:db8::1/128"]) + self.assertEqual(ipv4, []) + self.assertIn("2001:db8::1/128", ipv6) + + def test_mixed(self): + ipv4, ipv6 = _split_addresses(["dhcp", "192.0.2.1/24", "2001:db8::1/128"]) + self.assertIn("dhcp", ipv4) + self.assertIn("192.0.2.1/24", ipv4) + self.assertIn("2001:db8::1/128", ipv6) + + +class TestVyOSL3InterfacesParseIface(unittest.TestCase): + + def test_parse_dhcp(self): + result = _parse_iface("eth0", {"address": "dhcp"}) + self.assertEqual(result["name"], "eth0") + self.assertEqual(result["ipv4"], [{"address": "dhcp"}]) + + def test_parse_multiple_addresses(self): + result = _parse_iface("lo", {"address": ["10.0.0.1/32", "10.0.0.2/32"]}) + addrs = [a["address"] for a in result["ipv4"]] + self.assertIn("10.0.0.1/32", addrs) + self.assertIn("10.0.0.2/32", addrs) + + def test_parse_vif(self): + result = _parse_iface( + "eth0", + { + "address": "dhcp", + "vif": {"100": {"address": "192.0.2.100/24"}}, + }, + ) + self.assertIn("vifs", result) + self.assertEqual(result["vifs"][0]["vlan_id"], 100) + self.assertEqual(result["vifs"][0]["ipv4"][0]["address"], "192.0.2.100/24") + + def test_parse_no_address(self): + result = _parse_iface("lo", {}) + self.assertNotIn("ipv4", result) + self.assertNotIn("ipv6", result) + + def test_hw_id_ignored(self): + result = _parse_iface("eth0", {"hw-id": "52:54:00:65:5a:24"}) + self.assertNotIn("hw_id", result) + self.assertNotIn("hw-id", result) + + +class TestVyOSL3InterfacesGetRunningFixture(VyOSModuleTestCase): + + def setUp(self): + super().setUp() + self.fixture = load_fixture("l3_interfaces_running.json") + + def test_fixture_parses_eth0_dhcp(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + eth0 = next((e for e in result if e["name"] == "eth0"), None) + self.assertIsNotNone(eth0) + addrs = [a["address"] for a in eth0.get("ipv4", [])] + self.assertIn("dhcp", addrs) + + def test_fixture_parses_loopback_addresses(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + lo = next((e for e in result if e["name"] == "lo"), None) + self.assertIsNotNone(lo) + addrs = [a["address"] for a in lo.get("ipv4", [])] + self.assertIn("10.0.0.1/32", addrs) + self.assertIn("10.0.0.2/32", addrs) + + def test_fixture_parses_vif(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + eth0 = next(e for e in result if e["name"] == "eth0") + self.assertIn("vifs", eth0) + self.assertEqual(eth0["vifs"][0]["vlan_id"], 100) + + def test_empty_interface_not_included(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + names = [e["name"] for e in result] + # loopback with no addresses should not appear + self.assertNotIn("dummy0", names) + + +class TestVyOSL3InterfacesGetRunning(VyOSModuleTestCase): + + def test_empty_returns_empty_list(self): + self.set_running_config({}) + result = get_running_config(self.mock_vyos) + self.assertEqual(result, []) + + def test_interface_without_address_excluded(self): + self.set_running_config( + { + "ethernet": {"eth0": {"hw-id": "52:54:00:65:5a:24"}}, + }, + ) + result = get_running_config(self.mock_vyos) + self.assertEqual(result, []) + + +class TestVyOSL3InterfacesNormalize(unittest.TestCase): + + def test_normalize_ipv4(self): + config = [ + { + "name": "lo", + "ipv4": [{"address": "10.0.0.1/32"}], + }, + ] + result = _normalize(config) + self.assertIn("lo", result) + self.assertIn("10.0.0.1/32", result["lo"]["ipv4"]) + + def test_normalize_vif(self): + config = [ + { + "name": "eth0", + "vifs": [{"vlan_id": 100, "ipv4": [{"address": "192.0.2.100/24"}]}], + }, + ] + result = _normalize(config) + self.assertIn(100, result["eth0"]["vifs"]) + self.assertIn("192.0.2.100/24", result["eth0"]["vifs"][100]["ipv4"]) + + def test_normalize_empty(self): + result = _normalize([]) + self.assertEqual(result, {}) + + +class TestVyOSL3InterfacesAddrCmds(unittest.TestCase): + + def test_adds_new_address(self): + base = ["interfaces", "loopback", "lo"] + cmds = _addr_cmds(base, ["10.0.0.1/32"], [], "merged") + self.assertIn(("set", base + ["address", "10.0.0.1/32"]), cmds) + + def test_idempotent(self): + base = ["interfaces", "loopback", "lo"] + cmds = _addr_cmds(base, ["10.0.0.1/32"], ["10.0.0.1/32"], "merged") + self.assertEqual(cmds, []) + + def test_merged_does_not_delete_extra(self): + base = ["interfaces", "loopback", "lo"] + cmds = _addr_cmds(base, ["10.0.0.1/32"], ["10.0.0.1/32", "10.0.0.2/32"], "merged") + self.assertEqual(cmds, []) + + def test_replaced_deletes_extra(self): + base = ["interfaces", "loopback", "lo"] + cmds = _addr_cmds(base, ["10.0.0.1/32"], ["10.0.0.1/32", "10.0.0.2/32"], "replaced") + self.assertIn(("delete", base + ["address", "10.0.0.2/32"]), cmds) + + +class TestVyOSL3InterfacesBuildCommands(unittest.TestCase): + + def _have_lo(self): + return [ + { + "name": "lo", + "ipv4": [ + {"address": "10.0.0.1/32"}, + {"address": "10.0.0.2/32"}, + ], + }, + ] + + def test_merged_adds_address(self): + config = [{"name": "lo", "ipv4": [{"address": "10.0.0.3/32"}]}] + cmds = build_commands(config, [], "merged") + self.assertIn( + ("set", ["interfaces", "loopback", "lo", "address", "10.0.0.3/32"]), + cmds, + ) + + def test_merged_idempotent(self): + cmds = build_commands(self._have_lo(), self._have_lo(), "merged") + self.assertEqual(cmds, []) + + def test_deleted_no_config_removes_all(self): + cmds = build_commands([], self._have_lo(), "deleted") + paths = [c[1] for c in cmds] + self.assertIn(["interfaces", "loopback", "lo", "address", "10.0.0.1/32"], paths) + self.assertIn(["interfaces", "loopback", "lo", "address", "10.0.0.2/32"], paths) + + def test_deleted_with_config_removes_interface_addresses(self): + config = [{"name": "lo"}] + cmds = build_commands(config, self._have_lo(), "deleted") + paths = [c[1] for c in cmds] + self.assertIn(["interfaces", "loopback", "lo", "address", "10.0.0.1/32"], paths) + + def test_deleted_idempotent_when_empty(self): + cmds = build_commands([], [], "deleted") + self.assertEqual(cmds, []) + + def test_replaced_removes_extra_address(self): + config = [{"name": "lo", "ipv4": [{"address": "10.0.0.1/32"}]}] + cmds = build_commands(config, self._have_lo(), "replaced") + self.assertIn( + ("delete", ["interfaces", "loopback", "lo", "address", "10.0.0.2/32"]), + cmds, + ) + + def test_overridden_removes_unlisted_interface(self): + config = [{"name": "lo", "ipv4": [{"address": "10.0.0.1/32"}]}] + have = self._have_lo() + [ + { + "name": "eth0", + "ipv4": [{"address": "192.0.2.1/24"}], + }, + ] + cmds = build_commands(config, have, "overridden") + self.assertIn( + ("delete", ["interfaces", "ethernet", "eth0", "address", "192.0.2.1/24"]), + cmds, + ) + + def test_vif_added(self): + config = [ + { + "name": "eth0", + "vifs": [{"vlan_id": 100, "ipv4": [{"address": "192.0.2.100/24"}]}], + }, + ] + cmds = build_commands(config, [], "merged") + self.assertIn( + ("set", ["interfaces", "ethernet", "eth0", "vif", "100", "address", "192.0.2.100/24"]), + cmds, + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/unit/modules/test_vyos_lag_interfaces.py b/tests/unit/modules/test_vyos_lag_interfaces.py new file mode 100644 index 0000000..7c6df87 --- /dev/null +++ b/tests/unit/modules/test_vyos_lag_interfaces.py @@ -0,0 +1,293 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json +import os +import unittest + +from unittest.mock import MagicMock + +from ansible_collections.vyos.rest.plugins.modules.vyos_lag_interfaces import ( + _bond_base, + _bond_cmds, + _normalize, + build_commands, + get_running_config, +) + + +def load_fixture(filename): + fixtures_dir = os.path.join(os.path.dirname(__file__), "..", "fixtures") + path = os.path.join(fixtures_dir, filename) + with open(path) as f: + return json.load(f) + + +class VyOSModuleTestCase(unittest.TestCase): + def setUp(self): + self.mock_vyos = MagicMock() + self.mock_vyos.get_config = MagicMock(return_value={}) + + def set_running_config(self, data): + self.mock_vyos.get_config.return_value = data + + +class TestVyOSLagInterfacesBondBase(unittest.TestCase): + + def test_bond_base(self): + self.assertEqual( + _bond_base("bond0"), + ["interfaces", "bonding", "bond0"], + ) + + +class TestVyOSLagInterfacesGetRunningFixture(VyOSModuleTestCase): + + def setUp(self): + super().setUp() + self.fixture = load_fixture("lag_interfaces_running.json") + + def test_fixture_parses_bond0_mode(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + bond0 = next((e for e in result if e["name"] == "bond0"), None) + self.assertIsNotNone(bond0) + self.assertEqual(bond0["mode"], "active-backup") + + def test_fixture_parses_hash_policy(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + bond0 = next(e for e in result if e["name"] == "bond0") + self.assertEqual(bond0["hash_policy"], "layer2") + + def test_fixture_parses_arp_monitor(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + bond0 = next(e for e in result if e["name"] == "bond0") + self.assertIn("arp_monitor", bond0) + self.assertEqual(bond0["arp_monitor"]["interval"], 100) + self.assertIn("192.0.2.1", bond0["arp_monitor"]["target"]) + + def test_fixture_unwraps_bonding_key(self): + # wrap in extra "bonding" key as VyOS sometimes returns + wrapped = {"bonding": self.fixture} + self.set_running_config(wrapped) + result = get_running_config(self.mock_vyos) + self.assertTrue(len(result) > 0) + self.assertEqual(result[0]["name"], "bond0") + + +class TestVyOSLagInterfacesGetRunning(VyOSModuleTestCase): + + def test_empty_returns_empty_list(self): + self.set_running_config({}) + result = get_running_config(self.mock_vyos) + self.assertEqual(result, []) + + def test_parses_mode(self): + self.set_running_config( + { + "bond0": {"mode": "802.3ad"}, + }, + ) + result = get_running_config(self.mock_vyos) + self.assertEqual(result[0]["mode"], "802.3ad") + + def test_parses_hash_policy(self): + self.set_running_config( + { + "bond0": {"hash-policy": "layer2+3"}, + }, + ) + result = get_running_config(self.mock_vyos) + self.assertEqual(result[0]["hash_policy"], "layer2+3") + + def test_parses_members(self): + self.set_running_config( + { + "bond0": {"member": {"interface": {"eth1": {}, "eth2": {}}}}, + }, + ) + result = get_running_config(self.mock_vyos) + members = [m["member"] for m in result[0]["members"]] + self.assertIn("eth1", members) + self.assertIn("eth2", members) + + def test_parses_arp_monitor_interval(self): + self.set_running_config( + { + "bond0": {"arp-monitor": {"interval": "100"}}, + }, + ) + result = get_running_config(self.mock_vyos) + self.assertEqual(result[0]["arp_monitor"]["interval"], 100) + + def test_parses_arp_monitor_target_dict(self): + self.set_running_config( + { + "bond0": {"arp-monitor": {"target": {"192.0.2.1": {}}}}, + }, + ) + result = get_running_config(self.mock_vyos) + self.assertIn("192.0.2.1", result[0]["arp_monitor"]["target"]) + + def test_skips_type_keys(self): + self.set_running_config( + { + "bonding": {"bond0": {"mode": "802.3ad"}}, + }, + ) + result = get_running_config(self.mock_vyos) + # "bonding" key should be skipped + names = [e["name"] for e in result] + self.assertNotIn("bonding", names) + + +class TestVyOSLagInterfacesNormalize(unittest.TestCase): + + def test_normalize_basic(self): + config = [{"name": "bond0", "mode": "802.3ad", "hash_policy": "layer2"}] + result = _normalize(config) + self.assertIn("bond0", result) + self.assertEqual(result["bond0"]["mode"], "802.3ad") + self.assertEqual(result["bond0"]["hash_policy"], "layer2") + + def test_normalize_members_sorted(self): + config = [ + { + "name": "bond0", + "members": [{"member": "eth2"}, {"member": "eth1"}], + }, + ] + result = _normalize(config) + self.assertEqual(result["bond0"]["members"], ["eth1", "eth2"]) + + def test_normalize_arp_targets_sorted(self): + config = [ + { + "name": "bond0", + "arp_monitor": {"interval": 100, "target": ["192.0.2.2", "192.0.2.1"]}, + }, + ] + result = _normalize(config) + self.assertEqual(result["bond0"]["arp_targets"], ["192.0.2.1", "192.0.2.2"]) + + def test_normalize_empty(self): + result = _normalize([]) + self.assertEqual(result, {}) + + +class TestVyOSLagInterfacesBondCmds(unittest.TestCase): + + def test_set_mode(self): + want = {"mode": "802.3ad"} + cmds = _bond_cmds("bond0", want, {}) + self.assertIn( + ("set", ["interfaces", "bonding", "bond0", "mode", "802.3ad"]), + cmds, + ) + + def test_set_hash_policy(self): + want = {"hash_policy": "layer2"} + cmds = _bond_cmds("bond0", want, {}) + self.assertIn( + ("set", ["interfaces", "bonding", "bond0", "hash-policy", "layer2"]), + cmds, + ) + + def test_set_member(self): + want = {"members": ["eth1"]} + cmds = _bond_cmds("bond0", want, {}) + self.assertIn( + ("set", ["interfaces", "bonding", "bond0", "member", "interface", "eth1"]), + cmds, + ) + + def test_set_arp_interval(self): + want = {"arp_interval": 100} + cmds = _bond_cmds("bond0", want, {}) + self.assertIn( + ("set", ["interfaces", "bonding", "bond0", "arp-monitor", "interval", "100"]), + cmds, + ) + + def test_set_arp_target(self): + want = {"arp_targets": ["192.0.2.1"]} + cmds = _bond_cmds("bond0", want, {}) + self.assertIn( + ("set", ["interfaces", "bonding", "bond0", "arp-monitor", "target", "192.0.2.1"]), + cmds, + ) + + def test_idempotent_mode(self): + want = {"mode": "802.3ad"} + have = {"mode": "802.3ad"} + cmds = _bond_cmds("bond0", want, have) + self.assertEqual(cmds, []) + + def test_no_commands_when_empty_want(self): + cmds = _bond_cmds("bond0", {}, {}) + self.assertEqual(cmds, []) + + +class TestVyOSLagInterfacesBuildCommands(unittest.TestCase): + + def _have_bond0(self): + return [ + { + "name": "bond0", + "mode": "active-backup", + "hash_policy": "layer2", + "arp_monitor": {"interval": 100, "target": ["192.0.2.1"]}, + }, + ] + + def test_merged_adds_bond(self): + config = [{"name": "bond0", "mode": "802.3ad"}] + cmds = build_commands(config, [], "merged") + self.assertIn( + ("set", ["interfaces", "bonding", "bond0", "mode", "802.3ad"]), + cmds, + ) + + def test_merged_idempotent(self): + cmds = build_commands(self._have_bond0(), self._have_bond0(), "merged") + self.assertEqual(cmds, []) + + def test_deleted_no_config_removes_all(self): + cmds = build_commands([], self._have_bond0(), "deleted") + self.assertIn( + ("delete", ["interfaces", "bonding", "bond0"]), + cmds, + ) + + def test_deleted_with_name_removes_bond(self): + config = [{"name": "bond0"}] + cmds = build_commands(config, self._have_bond0(), "deleted") + self.assertIn( + ("delete", ["interfaces", "bonding", "bond0"]), + cmds, + ) + + def test_deleted_idempotent_when_empty(self): + cmds = build_commands([], [], "deleted") + self.assertEqual(cmds, []) + + def test_replaced_idempotent(self): + cmds = build_commands(self._have_bond0(), self._have_bond0(), "replaced") + self.assertEqual(cmds, []) + + def test_overridden_removes_unlisted_bond(self): + config = [{"name": "bond1", "mode": "802.3ad"}] + cmds = build_commands(config, self._have_bond0(), "overridden") + self.assertIn( + ("delete", ["interfaces", "bonding", "bond0"]), + cmds, + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/unit/modules/test_vyos_lldp_interfaces.py b/tests/unit/modules/test_vyos_lldp_interfaces.py new file mode 100644 index 0000000..0950991 --- /dev/null +++ b/tests/unit/modules/test_vyos_lldp_interfaces.py @@ -0,0 +1,291 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json +import os +import unittest + +from unittest.mock import MagicMock + +from ansible_collections.vyos.rest.plugins.modules.vyos_lldp_interfaces import ( + _iface_base, + _iface_cmds, + _normalize, + build_commands, + get_running_config, +) + + +def load_fixture(filename): + fixtures_dir = os.path.join(os.path.dirname(__file__), "..", "fixtures") + path = os.path.join(fixtures_dir, filename) + with open(path) as f: + return json.load(f) + + +class VyOSModuleTestCase(unittest.TestCase): + def setUp(self): + self.mock_vyos = MagicMock() + self.mock_vyos.get_config = MagicMock(return_value={}) + + def set_running_config(self, data): + self.mock_vyos.get_config.return_value = data + + +class TestVyOSLldpInterfacesIfaceBase(unittest.TestCase): + + def test_iface_base(self): + self.assertEqual( + _iface_base("eth0"), + ["service", "lldp", "interface", "eth0"], + ) + + +class TestVyOSLldpInterfacesGetRunningFixture(VyOSModuleTestCase): + + def setUp(self): + super().setUp() + self.fixture = load_fixture("lldp_interfaces_running.json") + + def test_fixture_parses_eth0_mode(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + eth0 = next((e for e in result if e["name"] == "eth0"), None) + self.assertIsNotNone(eth0) + self.assertEqual(eth0["mode"], "disable") + + def test_fixture_parses_elin(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + eth0 = next(e for e in result if e["name"] == "eth0") + self.assertEqual(eth0["location"]["elin"], "1234567890") + + def test_fixture_parses_coordinate_based(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + eth1 = next((e for e in result if e["name"] == "eth1"), None) + self.assertIsNotNone(eth1) + cb = eth1["location"]["coordinate_based"] + self.assertEqual(cb["latitude"], "33.524449N") + self.assertEqual(cb["longitude"], "22.267255E") + self.assertEqual(cb["altitude"], 2200) + self.assertEqual(cb["datum"], "WGS84") + + +class TestVyOSLldpInterfacesGetRunning(VyOSModuleTestCase): + + def test_empty_returns_empty_list(self): + self.set_running_config({}) + result = get_running_config(self.mock_vyos) + self.assertEqual(result, []) + + def test_no_interface_returns_empty(self): + self.set_running_config({"snmp": "enable"}) + result = get_running_config(self.mock_vyos) + self.assertEqual(result, []) + + def test_parses_mode(self): + self.set_running_config( + { + "interface": {"eth0": {"mode": "rx-tx"}}, + }, + ) + result = get_running_config(self.mock_vyos) + self.assertEqual(result[0]["mode"], "rx-tx") + + def test_parses_elin(self): + self.set_running_config( + { + "interface": {"eth0": {"location": {"elin": "9876543210"}}}, + }, + ) + result = get_running_config(self.mock_vyos) + self.assertEqual(result[0]["location"]["elin"], "9876543210") + + def test_parses_coordinate_based(self): + self.set_running_config( + { + "interface": { + "eth0": { + "location": { + "coordinate-based": { + "latitude": "33.524449N", + "longitude": "22.267255E", + "altitude": "2200", + "datum": "WGS84", + }, + }, + }, + }, + }, + ) + result = get_running_config(self.mock_vyos) + cb = result[0]["location"]["coordinate_based"] + self.assertEqual(cb["latitude"], "33.524449N") + self.assertEqual(cb["altitude"], 2200) + + def test_no_mode_not_in_entry(self): + self.set_running_config( + { + "interface": {"eth0": {"location": {"elin": "1234567890"}}}, + }, + ) + result = get_running_config(self.mock_vyos) + self.assertNotIn("mode", result[0]) + + +class TestVyOSLldpInterfacesNormalize(unittest.TestCase): + + def test_normalize_mode(self): + config = [{"name": "eth0", "mode": "disable"}] + result = _normalize(config) + self.assertEqual(result["eth0"]["mode"], "disable") + + def test_normalize_elin(self): + config = [{"name": "eth0", "location": {"elin": "1234567890"}}] + result = _normalize(config) + self.assertEqual(result["eth0"]["elin"], "1234567890") + + def test_normalize_coordinate_based(self): + config = [ + { + "name": "eth0", + "location": { + "coordinate_based": { + "latitude": "33.524449N", + "longitude": "22.267255E", + "altitude": 2200, + "datum": "WGS84", + }, + }, + }, + ] + result = _normalize(config) + self.assertEqual(result["eth0"]["latitude"], "33.524449N") + self.assertEqual(result["eth0"]["altitude"], 2200) + + def test_normalize_empty(self): + result = _normalize([]) + self.assertEqual(result, {}) + + +class TestVyOSLldpInterfacesIfaceCmds(unittest.TestCase): + + def test_set_mode(self): + want = {"mode": "disable"} + cmds = _iface_cmds("eth0", want, {}) + self.assertIn( + ("set", ["service", "lldp", "interface", "eth0", "mode", "disable"]), + cmds, + ) + + def test_set_elin(self): + want = {"elin": "1234567890"} + cmds = _iface_cmds("eth0", want, {}) + self.assertIn( + ("set", ["service", "lldp", "interface", "eth0", "location", "elin", "1234567890"]), + cmds, + ) + + def test_set_latitude(self): + want = {"latitude": "33.524449N", "longitude": "22.267255E"} + cmds = _iface_cmds("eth0", want, {}) + self.assertIn( + ( + "set", + [ + "service", + "lldp", + "interface", + "eth0", + "location", + "coordinate-based", + "latitude", + "33.524449N", + ], + ), + cmds, + ) + + def test_idempotent_mode(self): + want = {"mode": "disable"} + have = {"mode": "disable"} + cmds = _iface_cmds("eth0", want, have) + self.assertEqual(cmds, []) + + def test_idempotent_elin(self): + want = {"elin": "1234567890"} + have = {"elin": "1234567890"} + cmds = _iface_cmds("eth0", want, have) + self.assertEqual(cmds, []) + + def test_delete_mode_when_none(self): + want = {} + have = {"mode": "disable"} + cmds = _iface_cmds("eth0", want, have) + self.assertIn( + ("delete", ["service", "lldp", "interface", "eth0", "mode"]), + cmds, + ) + + +class TestVyOSLldpInterfacesBuildCommands(unittest.TestCase): + + def _have_eth0(self): + return [ + { + "name": "eth0", + "mode": "disable", + "location": {"elin": "1234567890"}, + }, + ] + + def test_merged_adds_interface(self): + config = [{"name": "eth0", "mode": "disable"}] + cmds = build_commands(config, [], "merged") + self.assertIn( + ("set", ["service", "lldp", "interface", "eth0", "mode", "disable"]), + cmds, + ) + + def test_merged_idempotent(self): + cmds = build_commands(self._have_eth0(), self._have_eth0(), "merged") + self.assertEqual(cmds, []) + + def test_deleted_no_config_removes_all(self): + cmds = build_commands([], self._have_eth0(), "deleted") + self.assertIn( + ("delete", ["service", "lldp", "interface", "eth0"]), + cmds, + ) + + def test_deleted_with_config_removes_named(self): + config = [{"name": "eth0"}] + cmds = build_commands(config, self._have_eth0(), "deleted") + self.assertIn( + ("delete", ["service", "lldp", "interface", "eth0"]), + cmds, + ) + + def test_deleted_idempotent_when_empty(self): + cmds = build_commands([], [], "deleted") + self.assertEqual(cmds, []) + + def test_replaced_idempotent(self): + cmds = build_commands(self._have_eth0(), self._have_eth0(), "replaced") + self.assertEqual(cmds, []) + + def test_overridden_removes_unlisted(self): + config = [{"name": "eth1", "mode": "rx-tx"}] + cmds = build_commands(config, self._have_eth0(), "overridden") + self.assertIn( + ("delete", ["service", "lldp", "interface", "eth0"]), + cmds, + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/unit/modules/test_vyos_logging_global.py b/tests/unit/modules/test_vyos_logging_global.py index 8593f1f..7d91182 100644 --- a/tests/unit/modules/test_vyos_logging_global.py +++ b/tests/unit/modules/test_vyos_logging_global.py @@ -98,7 +98,7 @@ class TestVyOSLoggingGlobalNormalize(unittest.TestCase): def test_normalize_running_host_port_not_cast(self): """Port is NOT cast to int — stored as-is from API response.""" raw = { - "host": { + "remote": { "172.16.0.1": { "port": "514", "facility": {}, @@ -112,7 +112,7 @@ class TestVyOSLoggingGlobalNormalize(unittest.TestCase): def test_normalize_running_global_archive_key(self): """Archive stored under 'archive' key — no file_num remapping.""" raw = { - "global": { + "local": { "archive": {"file": "2", "size": "111"}, "marker": {"interval": "111"}, "preserve-fqdn": {}, @@ -133,7 +133,7 @@ class TestVyOSLoggingGlobalNormalize(unittest.TestCase): def test_normalize_running_host_facilities(self): raw = { - "host": { + "remote": { "172.16.0.1": { "facility": { "local7": {"level": "all"}, @@ -196,14 +196,14 @@ class TestVyOSLoggingGlobalBuildCommands(unittest.TestCase): cmds = build_commands(want, self._empty_have(), "merged") paths = [c[1] for c in cmds] # diff_map only adds the host key, not per-facility details - self.assertIn(["system", "syslog", "host", "172.16.0.1"], paths) + self.assertIn(["system", "syslog", "remote", "172.16.0.1"], paths) def test_replaced_removes_extra_host(self): want = self._empty_have() have = self._empty_have() have["hosts"]["172.16.0.1"] = {"port": None, "facilities": {}} cmds = build_commands(want, have, "replaced") - self.assertIn(("delete", ["system", "syslog", "host", "172.16.0.1"]), cmds) + self.assertIn(("delete", ["system", "syslog", "remote", "172.16.0.1"]), cmds) def test_deleted_removes_per_field(self): """deleted state removes per-facility entries, not single subtree.""" diff --git a/tests/unit/modules/test_vyos_ospf_interfaces.py b/tests/unit/modules/test_vyos_ospf_interfaces.py new file mode 100644 index 0000000..4d6be0d --- /dev/null +++ b/tests/unit/modules/test_vyos_ospf_interfaces.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json +import os +import unittest + +from unittest.mock import MagicMock + +from ansible_collections.vyos.rest.plugins.modules.vyos_ospf_interfaces import ( + _parse_ipv4_iface, + _parse_ipv6_iface, + build_commands, + get_running_config, +) + + +_BASE4 = ["protocols", "ospf", "interface"] +_BASE6 = ["protocols", "ospfv3", "interface"] + + +def load_fixture(filename): + fixtures_dir = os.path.join(os.path.dirname(__file__), "..", "fixtures") + with open(os.path.join(fixtures_dir, filename)) as f: + return json.load(f) + + +class VyOSModuleTestCase(unittest.TestCase): + def setUp(self): + self.mock_vyos = MagicMock() + self.ipv4_fixture = load_fixture("ospf_interfaces_ipv4.json") + self.ipv6_fixture = load_fixture("ospf_interfaces_ipv6.json") + self.mock_vyos.get_config = MagicMock( + side_effect=lambda path: (self.ipv4_fixture if path == _BASE4 else self.ipv6_fixture), + ) + + +class TestVyOSOspfInterfacesParse(VyOSModuleTestCase): + + def test_parse_ipv4_scalars(self): + raw = {"cost": "100", "transmit-delay": "50", "priority": "26"} + result = _parse_ipv4_iface(raw) + self.assertEqual(result["afi"], "ipv4") + self.assertEqual(result["cost"], 100) + self.assertEqual(result["transmit_delay"], 50) + self.assertEqual(result["priority"], 26) + + def test_parse_ipv4_md5_auth(self): + raw = {"authentication": {"md5": {"key-id": {"10": {"md5-key": "secret"}}}}} + result = _parse_ipv4_iface(raw) + self.assertEqual(result["authentication"]["md5_key"]["key_id"], 10) + self.assertEqual(result["authentication"]["md5_key"]["key"], "secret") + + def test_parse_ipv6_scalars(self): + raw = {"dead-interval": "39", "passive": {}} + result = _parse_ipv6_iface(raw) + self.assertEqual(result["afi"], "ipv6") + self.assertEqual(result["dead_interval"], 39) + self.assertTrue(result["passive"]) + + def test_get_running_config(self): + result = get_running_config(self.mock_vyos) + names = [e["name"] for e in result] + self.assertIn("eth1", names) + self.assertIn("eth2", names) + eth1 = next(e for e in result if e["name"] == "eth1") + afis = {af["afi"] for af in eth1["address_family"]} + self.assertIn("ipv4", afis) + self.assertIn("ipv6", afis) + + def test_get_running_config_empty(self): + self.mock_vyos.get_config = MagicMock(return_value={}) + result = get_running_config(self.mock_vyos) + self.assertEqual(result, []) + + +class TestVyOSOspfInterfacesBuildCommands(unittest.TestCase): + + def test_deleted_all(self): + have = [ + { + "name": "eth1", + "address_family": [{"afi": "ipv4", "cost": 100}, {"afi": "ipv6", "passive": True}], + }, + ] + cmds = build_commands([], have, "deleted") + self.assertIn(("delete", _BASE4 + ["eth1"]), cmds) + self.assertIn(("delete", _BASE6 + ["eth1"]), cmds) + + def test_deleted_specific(self): + have = [ + {"name": "eth1", "address_family": [{"afi": "ipv4", "cost": 100}]}, + {"name": "eth2", "address_family": [{"afi": "ipv4", "cost": 200}]}, + ] + cmds = build_commands([{"name": "eth1"}], have, "deleted") + self.assertIn(("delete", _BASE4 + ["eth1"]), cmds) + paths = [c[1] for c in cmds] + self.assertNotIn(_BASE4 + ["eth2"], paths) + + def test_merged_adds_cost(self): + config = [{"name": "eth1", "address_family": [{"afi": "ipv4", "cost": 100}]}] + cmds = build_commands(config, [], "merged") + self.assertIn(("set", _BASE4 + ["eth1", "cost", "100"]), cmds) + + def test_merged_idempotent(self): + have = [{"name": "eth1", "address_family": [{"afi": "ipv4", "cost": 100}]}] + config = [{"name": "eth1", "address_family": [{"afi": "ipv4", "cost": 100}]}] + cmds = build_commands(config, have, "merged") + self.assertEqual(cmds, []) + + def test_merged_ipv6_passive(self): + config = [{"name": "eth1", "address_family": [{"afi": "ipv6", "passive": True}]}] + cmds = build_commands(config, [], "merged") + self.assertIn(("set", _BASE6 + ["eth1", "passive"]), cmds) + + def test_overridden_removes_extra_interface(self): + have = [ + {"name": "eth1", "address_family": [{"afi": "ipv4", "cost": 100}]}, + {"name": "eth2", "address_family": [{"afi": "ipv4", "cost": 200}]}, + ] + config = [{"name": "eth1", "address_family": [{"afi": "ipv4", "cost": 100}]}] + cmds = build_commands(config, have, "overridden") + self.assertIn(("delete", _BASE4 + ["eth2"]), cmds) + + def test_replaced_idempotent(self): + have = [{"name": "eth1", "address_family": [{"afi": "ipv4", "cost": 200}]}] + config = [{"name": "eth1", "address_family": [{"afi": "ipv4", "cost": 200}]}] + cmds = build_commands(config, have, "replaced") + self.assertEqual(cmds, []) + + def test_replaced_rebuilds_on_change(self): + have = [ + { + "name": "eth1", + "address_family": [{"afi": "ipv4", "cost": 100, "transmit_delay": 50}], + }, + ] + config = [{"name": "eth1", "address_family": [{"afi": "ipv4", "cost": 200}]}] + cmds = build_commands(config, have, "replaced") + self.assertIn(("delete", _BASE4 + ["eth1"]), cmds) + self.assertIn(("set", _BASE4 + ["eth1", "cost", "200"]), cmds) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/unit/modules/test_vyos_ospfv2.py b/tests/unit/modules/test_vyos_ospfv2.py new file mode 100644 index 0000000..c05dd77 --- /dev/null +++ b/tests/unit/modules/test_vyos_ospfv2.py @@ -0,0 +1,180 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json +import os +import unittest + +from unittest.mock import MagicMock + +from ansible_collections.vyos.rest.plugins.modules.vyos_ospfv2 import ( + _parse_areas, + _parse_default_information, + _parse_neighbor, + _parse_parameters, + _parse_redistribute, + build_commands, + get_running_config, +) + + +_BASE = ["protocols", "ospf"] + + +def load_fixture(filename): + fixtures_dir = os.path.join(os.path.dirname(__file__), "..", "fixtures") + with open(os.path.join(fixtures_dir, filename)) as f: + return json.load(f) + + +class VyOSModuleTestCase(unittest.TestCase): + def setUp(self): + self.mock_vyos = MagicMock() + self.fixture = load_fixture("ospfv2_running.json") + self.mock_vyos.get_config = MagicMock(return_value=self.fixture) + + +class TestVyOSOspfv2Parse(VyOSModuleTestCase): + + def test_parse_parameters(self): + result = _parse_parameters(self.fixture["parameters"]) + self.assertEqual(result["router_id"], "192.0.1.1") + self.assertEqual(result["abr_type"], "cisco") + self.assertTrue(result["opaque_lsa"]) + self.assertTrue(result["rfc1583_compatibility"]) + + def test_parse_redistribute(self): + result = _parse_redistribute(self.fixture["redistribute"]) + route_types = [r["route_type"] for r in result] + self.assertIn("bgp", route_types) + self.assertIn("connected", route_types) + bgp = next(r for r in result if r["route_type"] == "bgp") + self.assertEqual(bgp["metric"], 10) + self.assertEqual(bgp["metric_type"], 2) + + def test_parse_neighbor(self): + result = _parse_neighbor(self.fixture["neighbor"]) + self.assertEqual(len(result), 1) + nb = result[0] + self.assertEqual(nb["neighbor_id"], "192.0.11.12") + self.assertEqual(nb["priority"], 2) + self.assertEqual(nb["poll_interval"], 10) + + def test_parse_default_information(self): + result = _parse_default_information(self.fixture["default-information"]) + orig = result["originate"] + self.assertTrue(orig["always"]) + self.assertEqual(orig["metric"], 10) + self.assertEqual(orig["metric_type"], 2) + self.assertEqual(orig["route_map"], "ingress") + + def test_parse_areas(self): + result = _parse_areas(self.fixture["area"]) + self.assertEqual(len(result), 3) + area2 = next(a for a in result if a["area_id"] == "2") + self.assertTrue(area2["area_type"]["normal"]) + self.assertEqual(area2["network"][0]["address"], "192.0.2.0/24") + + area3 = next(a for a in result if a["area_id"] == "3") + self.assertTrue(area3["area_type"]["nssa"]["set"]) + + area4 = next(a for a in result if a["area_id"] == "4") + self.assertEqual(area4["area_type"]["stub"]["default_cost"], 20) + self.assertEqual(len(area4["range"]), 2) + r = next(r for r in area4["range"] if r["address"] == "192.0.3.0/24") + self.assertEqual(r["cost"], 10) + + def test_get_running_config(self): + result = get_running_config(self.mock_vyos) + self.assertEqual(result["parameters"]["router_id"], "192.0.1.1") + self.assertIn("eth1", result["passive_interface"]) + self.assertIn("eth2", result["passive_interface"]) + self.assertEqual(result["auto_cost"]["reference_bandwidth"], 2) + self.assertEqual(result["log_adjacency_changes"], "detail") + + def test_get_running_config_empty(self): + self.mock_vyos.get_config = MagicMock(return_value={}) + result = get_running_config(self.mock_vyos) + self.assertEqual(result, {}) + + +class TestVyOSOspfv2BuildCommands(unittest.TestCase): + + def test_deleted_with_have(self): + have = {"parameters": {"router_id": "192.0.1.1"}} + cmds = build_commands({}, have, "deleted") + self.assertEqual(cmds, [("delete", _BASE)]) + + def test_deleted_without_have(self): + cmds = build_commands({}, {}, "deleted") + self.assertEqual(cmds, []) + + def test_merged_parameters(self): + config = {"parameters": {"router_id": "192.0.1.1"}} + cmds = build_commands(config, {}, "merged") + self.assertIn(("set", _BASE + ["parameters", "router-id", "192.0.1.1"]), cmds) + + def test_merged_redistribute(self): + config = {"redistribute": [{"route_type": "bgp", "metric": 10}]} + cmds = build_commands(config, {}, "merged") + self.assertIn(("set", _BASE + ["redistribute", "bgp"]), cmds) + self.assertIn(("set", _BASE + ["redistribute", "bgp", "metric", "10"]), cmds) + + def test_merged_passive_interface(self): + config = {"passive_interface": ["eth1"]} + cmds = build_commands(config, {}, "merged") + self.assertIn(("set", _BASE + ["interface", "eth1", "passive"]), cmds) + + def test_merged_area_normal(self): + config = {"areas": [{"area_id": "2", "area_type": {"normal": True}}]} + cmds = build_commands(config, {}, "merged") + self.assertIn(("set", _BASE + ["area", "2", "area-type", "normal"]), cmds) + + def test_merged_area_stub_with_cost(self): + config = {"areas": [{"area_id": "4", "area_type": {"stub": {"default_cost": 20}}}]} + cmds = build_commands(config, {}, "merged") + self.assertIn( + ("set", _BASE + ["area", "4", "area-type", "stub", "default-cost", "20"]), + cmds, + ) + + def test_merged_idempotent(self): + have = {"parameters": {"router_id": "192.0.1.1"}} + config = {"parameters": {"router_id": "192.0.1.1"}} + cmds = build_commands(config, have, "merged") + self.assertEqual(cmds, []) + + def test_replaced_idempotent(self): + have = {"parameters": {"router_id": "192.0.1.1"}} + config = {"parameters": {"router_id": "192.0.1.1"}} + cmds = build_commands(config, have, "replaced") + self.assertEqual(cmds, []) + + def test_replaced_rebuilds_on_change(self): + have = {"parameters": {"router_id": "192.0.1.1"}} + config = {"parameters": {"router_id": "192.0.1.2"}} + cmds = build_commands(config, have, "replaced") + self.assertEqual(cmds[0], ("delete", _BASE)) + self.assertIn( + ("set", _BASE + ["parameters", "router-id", "192.0.1.2"]), + cmds, + ) + + def test_merged_neighbor(self): + config = {"neighbor": [{"neighbor_id": "192.0.11.12", "priority": 2}]} + cmds = build_commands(config, {}, "merged") + self.assertIn(("set", _BASE + ["neighbor", "192.0.11.12"]), cmds) + self.assertIn(("set", _BASE + ["neighbor", "192.0.11.12", "priority", "2"]), cmds) + + def test_merged_default_information(self): + config = {"default_information": {"originate": {"always": True, "metric": 10}}} + cmds = build_commands(config, {}, "merged") + self.assertIn(("set", _BASE + ["default-information", "originate", "always"]), cmds) + self.assertIn(("set", _BASE + ["default-information", "originate", "metric", "10"]), cmds) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/unit/modules/test_vyos_ospfv3.py b/tests/unit/modules/test_vyos_ospfv3.py new file mode 100644 index 0000000..a84041b --- /dev/null +++ b/tests/unit/modules/test_vyos_ospfv3.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json +import os +import unittest + +from unittest.mock import MagicMock + +from ansible_collections.vyos.rest.plugins.modules.vyos_ospfv3 import ( + build_commands, + get_running_config, +) + + +def load_fixture(filename): + fixtures_dir = os.path.join(os.path.dirname(__file__), "..", "fixtures") + with open(os.path.join(fixtures_dir, filename)) as f: + return json.load(f) + + +class VyOSModuleTestCase(unittest.TestCase): + def setUp(self): + self.mock_vyos = MagicMock() + self.mock_vyos.get_config = MagicMock(return_value={}) + + def set_running_config(self, data): + self.mock_vyos.get_config.return_value = data + + +class TestVyOSOspfv3Parse(VyOSModuleTestCase): + + def setUp(self): + super().setUp() + self.fixture = load_fixture("ospfv3_running.json") + + def test_parses_parameters(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + self.assertEqual(result["parameters"]["router_id"], "192.0.2.10") + + def test_parses_redistribute(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + route_types = [r["route_type"] for r in result["redistribute"]] + self.assertIn("bgp", route_types) + self.assertIn("connected", route_types) + connected = next(r for r in result["redistribute"] if r["route_type"] == "connected") + self.assertEqual(connected["route_map"], "RM1") + + def test_parses_areas(self): + self.set_running_config(self.fixture) + result = get_running_config(self.mock_vyos) + self.assertEqual(len(result["areas"]), 2) + area2 = next(a for a in result["areas"] if a["area_id"] == "2") + self.assertEqual(area2["export_list"], "export1") + self.assertEqual(area2["import_list"], "import1") + self.assertEqual(len(area2["range"]), 2) + not_adv = next(r for r in area2["range"] if r["address"] == "2001:db20::/32") + self.assertTrue(not_adv["not_advertise"]) + + def test_empty_config_returns_empty(self): + self.set_running_config({}) + result = get_running_config(self.mock_vyos) + self.assertEqual(result, {}) + + +class TestVyOSOspfv3BuildCommands(unittest.TestCase): + + def test_deleted_with_have(self): + have = {"parameters": {"router_id": "192.0.2.10"}} + cmds = build_commands({}, have, "deleted") + self.assertEqual(cmds, [("delete", ["protocols", "ospfv3"])]) + + def test_deleted_without_have(self): + cmds = build_commands({}, {}, "deleted") + self.assertEqual(cmds, []) + + def test_merged_parameters(self): + config = {"parameters": {"router_id": "192.0.2.10"}} + cmds = build_commands(config, {}, "merged") + self.assertIn( + ("set", ["protocols", "ospfv3", "parameters", "router-id", "192.0.2.10"]), + cmds, + ) + + def test_merged_redistribute(self): + config = {"redistribute": [{"route_type": "bgp"}]} + cmds = build_commands(config, {}, "merged") + self.assertIn( + ("set", ["protocols", "ospfv3", "redistribute", "bgp"]), + cmds, + ) + + def test_merged_idempotent(self): + config = {"parameters": {"router_id": "192.0.2.10"}} + have = {"parameters": {"router_id": "192.0.2.10"}} + cmds = build_commands(config, have, "merged") + self.assertEqual(cmds, []) + + def test_merged_area_range(self): + config = { + "areas": [{"area_id": "2", "range": [{"address": "2001:db10::/32"}]}], + } + cmds = build_commands(config, {}, "merged") + self.assertIn( + ("set", ["protocols", "ospfv3", "area", "2", "range", "2001:db10::/32"]), + cmds, + ) + + def test_replaced_idempotent(self): + config = {"parameters": {"router_id": "192.0.2.10"}} + have = {"parameters": {"router_id": "192.0.2.10"}} + cmds = build_commands(config, have, "replaced") + self.assertEqual(cmds, []) + + def test_replaced_rebuilds_on_change(self): + config = {"parameters": {"router_id": "192.0.2.11"}} + have = {"parameters": {"router_id": "192.0.2.10"}} + cmds = build_commands(config, have, "replaced") + self.assertEqual(cmds[0], ("delete", ["protocols", "ospfv3"])) + self.assertIn( + ("set", ["protocols", "ospfv3", "parameters", "router-id", "192.0.2.11"]), + cmds, + ) + + def test_merged_area_export_list(self): + config = {"areas": [{"area_id": "2", "export_list": "export1"}]} + cmds = build_commands(config, {}, "merged") + self.assertIn( + ("set", ["protocols", "ospfv3", "area", "2", "export-list", "export1"]), + cmds, + ) + + +if __name__ == "__main__": + unittest.main() |
