diff options
Diffstat (limited to 'tests/units')
-rw-r--r-- | tests/units/anta_tests/routing/test_isis.py | 1350 | ||||
-rw-r--r-- | tests/units/cli/get/test_commands.py | 48 | ||||
-rw-r--r-- | tests/units/cli/get/test_utils.py | 13 |
3 files changed, 1393 insertions, 18 deletions
diff --git a/tests/units/anta_tests/routing/test_isis.py b/tests/units/anta_tests/routing/test_isis.py index ec41105..2167ea4 100644 --- a/tests/units/anta_tests/routing/test_isis.py +++ b/tests/units/anta_tests/routing/test_isis.py @@ -3,11 +3,23 @@ # that can be found in the LICENSE file. """Tests for anta.tests.routing.ospf.py.""" +# pylint: disable=too-many-lines + from __future__ import annotations from typing import Any -from anta.tests.routing.isis import VerifyISISInterfaceMode, VerifyISISNeighborCount, VerifyISISNeighborState +import pytest + +from anta.tests.routing.isis import ( + VerifyISISInterfaceMode, + VerifyISISNeighborCount, + VerifyISISNeighborState, + VerifyISISSegmentRoutingAdjacencySegments, + VerifyISISSegmentRoutingDataplane, + VerifyISISSegmentRoutingTunnels, + _get_interface_data, +) from tests.lib.anta import test # noqa: F401; pylint: disable=W0611 DATA: list[dict[str, Any]] = [ @@ -155,6 +167,18 @@ DATA: list[dict[str, Any]] = [ }, }, { + "name": "skipped - no neighbor", + "test": VerifyISISNeighborState, + "eos_data": [ + {"vrfs": {"default": {"isisInstances": {"CORE-ISIS": {"neighbors": {}}}}}}, + ], + "inputs": None, + "expected": { + "result": "skipped", + "messages": ["No IS-IS neighbor detected"], + }, + }, + { "name": "success only default vrf", "test": VerifyISISNeighborCount, "eos_data": [ @@ -227,6 +251,108 @@ DATA: list[dict[str, Any]] = [ "expected": {"result": "success"}, }, { + "name": "skipped - no neighbor", + "test": VerifyISISNeighborCount, + "eos_data": [ + {"vrfs": {"default": {"isisInstances": {"CORE-ISIS": {"interfaces": {}}}}}}, + ], + "inputs": { + "interfaces": [ + {"name": "Ethernet1", "level": 2, "count": 1}, + ] + }, + "expected": { + "result": "skipped", + "messages": ["No IS-IS neighbor detected"], + }, + }, + { + "name": "failure - missing interface", + "test": VerifyISISNeighborCount, + "eos_data": [ + { + "vrfs": { + "default": { + "isisInstances": { + "CORE-ISIS": { + "interfaces": { + "Ethernet1": { + "intfLevels": { + "2": { + "ipv4Metric": 10, + "numAdjacencies": 0, + "linkId": "84", + "sharedSecretProfile": "", + "isisAdjacencies": [], + "passive": False, + "v4Protection": "link", + "v6Protection": "disabled", + } + }, + "interfaceSpeed": 1000, + "areaProxyBoundary": False, + }, + } + } + } + } + } + }, + ], + "inputs": { + "interfaces": [ + {"name": "Ethernet2", "level": 2, "count": 1}, + ] + }, + "expected": { + "result": "failure", + "messages": ["No neighbor detected for interface Ethernet2"], + }, + }, + { + "name": "failure - wrong count", + "test": VerifyISISNeighborCount, + "eos_data": [ + { + "vrfs": { + "default": { + "isisInstances": { + "CORE-ISIS": { + "interfaces": { + "Ethernet1": { + "intfLevels": { + "2": { + "ipv4Metric": 10, + "numAdjacencies": 3, + "linkId": "84", + "sharedSecretProfile": "", + "isisAdjacencies": [], + "passive": False, + "v4Protection": "link", + "v6Protection": "disabled", + } + }, + "interfaceSpeed": 1000, + "areaProxyBoundary": False, + }, + } + } + } + } + } + }, + ], + "inputs": { + "interfaces": [ + {"name": "Ethernet1", "level": 2, "count": 1}, + ] + }, + "expected": { + "result": "failure", + "messages": ["Interface Ethernet1: expected Level 2: count 1, got Level 2: count 3"], + }, + }, + { "name": "success VerifyISISInterfaceMode only default vrf", "test": VerifyISISInterfaceMode, "eos_data": [ @@ -567,4 +693,1226 @@ DATA: list[dict[str, Any]] = [ ], }, }, + { + "name": "skipped VerifyISISInterfaceMode no vrf", + "test": VerifyISISInterfaceMode, + "eos_data": [{"vrfs": {}}], + "inputs": { + "interfaces": [ + {"name": "Loopback0", "mode": "passive"}, + {"name": "Ethernet2", "mode": "passive"}, + {"name": "Ethernet1", "mode": "point-to-point", "vrf": "default"}, + ] + }, + "expected": {"result": "skipped", "messages": ["IS-IS is not configured on device"]}, + }, + { + "name": "Skipped of VerifyISISSegmentRoutingAdjacencySegments no VRF.", + "test": VerifyISISSegmentRoutingAdjacencySegments, + "eos_data": [{"vrfs": {}}], + "inputs": { + "instances": [ + { + "name": "CORE-ISIS", + "vrf": "default", + "segments": [ + { + "interface": "Ethernet2", + "address": "10.0.1.3", + "sid_origin": "dynamic", + } + ], + } + ] + }, + "expected": {"result": "skipped", "messages": ["IS-IS is not configured on device"]}, + }, + { + "test": VerifyISISSegmentRoutingAdjacencySegments, + "name": "Success of VerifyISISSegmentRoutingAdjacencySegments in default VRF.", + "eos_data": [ + { + "vrfs": { + "default": { + "isisInstances": { + "CORE-ISIS": { + "dataPlane": "MPLS", + "routerId": "1.0.0.11", + "systemId": "0168.0000.0011", + "hostname": "s1-pe01", + "adjSidAllocationMode": "SrOnly", + "adjSidPoolBase": 116384, + "adjSidPoolSize": 16384, + "adjacencySegments": [ + { + "ipAddress": "10.0.1.3", + "localIntf": "Ethernet2", + "sid": 116384, + "lan": False, + "sidOrigin": "dynamic", + "protection": "unprotected", + "flags": { + "b": False, + "v": True, + "l": True, + "f": False, + "s": False, + }, + "level": 2, + }, + { + "ipAddress": "10.0.1.1", + "localIntf": "Ethernet1", + "sid": 116385, + "lan": False, + "sidOrigin": "dynamic", + "protection": "unprotected", + "flags": { + "b": False, + "v": True, + "l": True, + "f": False, + "s": False, + }, + "level": 2, + }, + ], + "receivedGlobalAdjacencySegments": [], + "misconfiguredAdjacencySegments": [], + } + } + } + } + } + ], + "inputs": { + "instances": [ + { + "name": "CORE-ISIS", + "vrf": "default", + "segments": [ + { + "interface": "Ethernet2", + "address": "10.0.1.3", + "sid_origin": "dynamic", + } + ], + } + ] + }, + "expected": { + "result": "success", + "messages": [], + }, + }, + { + "test": VerifyISISSegmentRoutingAdjacencySegments, + "name": "Failure of VerifyISISSegmentRoutingAdjacencySegments in default VRF for incorrect segment definition.", + "eos_data": [ + { + "vrfs": { + "default": { + "isisInstances": { + "CORE-ISIS": { + "dataPlane": "MPLS", + "routerId": "1.0.0.11", + "systemId": "0168.0000.0011", + "hostname": "s1-pe01", + "adjSidAllocationMode": "SrOnly", + "adjSidPoolBase": 116384, + "adjSidPoolSize": 16384, + "adjacencySegments": [ + { + "ipAddress": "10.0.1.3", + "localIntf": "Ethernet2", + "sid": 116384, + "lan": False, + "sidOrigin": "dynamic", + "protection": "unprotected", + "flags": { + "b": False, + "v": True, + "l": True, + "f": False, + "s": False, + }, + "level": 2, + }, + { + "ipAddress": "10.0.1.1", + "localIntf": "Ethernet1", + "sid": 116385, + "lan": False, + "sidOrigin": "dynamic", + "protection": "unprotected", + "flags": { + "b": False, + "v": True, + "l": True, + "f": False, + "s": False, + }, + "level": 2, + }, + ], + "receivedGlobalAdjacencySegments": [], + "misconfiguredAdjacencySegments": [], + } + } + } + } + } + ], + "inputs": { + "instances": [ + { + "name": "CORE-ISIS", + "vrf": "default", + "segments": [ + { + "interface": "Ethernet2", + "address": "10.0.1.3", + "sid_origin": "dynamic", + }, + { + "interface": "Ethernet3", + "address": "10.0.1.2", + "sid_origin": "dynamic", + }, + ], + } + ] + }, + "expected": { + "result": "failure", + "messages": ["Your segment has not been found: interface='Ethernet3' level=2 sid_origin='dynamic' address=IPv4Address('10.0.1.2')."], + }, + }, + { + "test": VerifyISISSegmentRoutingAdjacencySegments, + "name": "Failure of VerifyISISSegmentRoutingAdjacencySegments with incorrect VRF.", + "eos_data": [ + { + "vrfs": { + "default": { + "isisInstances": { + "CORE-ISIS": { + "dataPlane": "MPLS", + "routerId": "1.0.0.11", + "systemId": "0168.0000.0011", + "hostname": "s1-pe01", + "adjSidAllocationMode": "SrOnly", + "adjSidPoolBase": 116384, + "adjSidPoolSize": 16384, + "adjacencySegments": [ + { + "ipAddress": "10.0.1.3", + "localIntf": "Ethernet2", + "sid": 116384, + "lan": False, + "sidOrigin": "dynamic", + "protection": "unprotected", + "flags": { + "b": False, + "v": True, + "l": True, + "f": False, + "s": False, + }, + "level": 2, + }, + { + "ipAddress": "10.0.1.1", + "localIntf": "Ethernet1", + "sid": 116385, + "lan": False, + "sidOrigin": "dynamic", + "protection": "unprotected", + "flags": { + "b": False, + "v": True, + "l": True, + "f": False, + "s": False, + }, + "level": 2, + }, + ], + "receivedGlobalAdjacencySegments": [], + "misconfiguredAdjacencySegments": [], + } + } + } + } + } + ], + "inputs": { + "instances": [ + { + "name": "CORE-ISIS", + "vrf": "custom", + "segments": [ + { + "interface": "Ethernet2", + "address": "10.0.1.3", + "sid_origin": "dynamic", + }, + { + "interface": "Ethernet3", + "address": "10.0.1.2", + "sid_origin": "dynamic", + }, + ], + } + ] + }, + "expected": { + "result": "failure", + "messages": ["VRF custom is not configured to run segment routging."], + }, + }, + { + "test": VerifyISISSegmentRoutingAdjacencySegments, + "name": "Failure of VerifyISISSegmentRoutingAdjacencySegments with incorrect Instance.", + "eos_data": [ + { + "vrfs": { + "default": { + "isisInstances": { + "CORE-ISIS": { + "dataPlane": "MPLS", + "routerId": "1.0.0.11", + "systemId": "0168.0000.0011", + "hostname": "s1-pe01", + "adjSidAllocationMode": "SrOnly", + "adjSidPoolBase": 116384, + "adjSidPoolSize": 16384, + "adjacencySegments": [ + { + "ipAddress": "10.0.1.3", + "localIntf": "Ethernet2", + "sid": 116384, + "lan": False, + "sidOrigin": "dynamic", + "protection": "unprotected", + "flags": { + "b": False, + "v": True, + "l": True, + "f": False, + "s": False, + }, + "level": 2, + }, + { + "ipAddress": "10.0.1.1", + "localIntf": "Ethernet1", + "sid": 116385, + "lan": False, + "sidOrigin": "dynamic", + "protection": "unprotected", + "flags": { + "b": False, + "v": True, + "l": True, + "f": False, + "s": False, + }, + "level": 2, + }, + ], + "receivedGlobalAdjacencySegments": [], + "misconfiguredAdjacencySegments": [], + } + } + } + } + } + ], + "inputs": { + "instances": [ + { + "name": "CORE-ISIS2", + "vrf": "default", + "segments": [ + { + "interface": "Ethernet2", + "address": "10.0.1.3", + "sid_origin": "dynamic", + }, + { + "interface": "Ethernet3", + "address": "10.0.1.2", + "sid_origin": "dynamic", + }, + ], + } + ] + }, + "expected": { + "result": "failure", + "messages": ["Instance CORE-ISIS2 is not found in vrf default."], + }, + }, + { + "test": VerifyISISSegmentRoutingAdjacencySegments, + "name": "Failure of VerifyISISSegmentRoutingAdjacencySegments with incorrect segment info.", + "eos_data": [ + { + "vrfs": { + "default": { + "isisInstances": { + "CORE-ISIS": { + "dataPlane": "MPLS", + "routerId": "1.0.0.11", + "systemId": "0168.0000.0011", + "hostname": "s1-pe01", + "adjSidAllocationMode": "SrOnly", + "adjSidPoolBase": 116384, + "adjSidPoolSize": 16384, + "adjacencySegments": [ + { + "ipAddress": "10.0.1.3", + "localIntf": "Ethernet2", + "sid": 116384, + "lan": False, + "sidOrigin": "dynamic", + "protection": "unprotected", + "flags": { + "b": False, + "v": True, + "l": True, + "f": False, + "s": False, + }, + "level": 2, + }, + ], + "receivedGlobalAdjacencySegments": [], + "misconfiguredAdjacencySegments": [], + } + } + } + } + } + ], + "inputs": { + "instances": [ + { + "name": "CORE-ISIS", + "vrf": "default", + "segments": [ + { + "interface": "Ethernet2", + "address": "10.0.1.3", + "sid_origin": "dynamic", + "level": 1, # Wrong level + }, + ], + } + ] + }, + "expected": { + "result": "failure", + "messages": [ + ( + "Your segment is not correct: Expected: interface='Ethernet2' level=1 sid_origin='dynamic' address=IPv4Address('10.0.1.3') - " + "Found: {'ipAddress': '10.0.1.3', 'localIntf': 'Ethernet2', 'sid': 116384, 'lan': False, 'sidOrigin': 'dynamic', 'protection': " + "'unprotected', 'flags': {'b': False, 'v': True, 'l': True, 'f': False, 's': False}, 'level': 2}." + ) + ], + }, + }, + { + "test": VerifyISISSegmentRoutingDataplane, + "name": "Check VerifyISISSegmentRoutingDataplane is running successfully", + "eos_data": [ + { + "vrfs": { + "default": { + "isisInstances": { + "CORE-ISIS": { + "dataPlane": "MPLS", + "routerId": "1.0.0.11", + "systemId": "0168.0000.0011", + "hostname": "s1-pe01", + } + } + } + } + } + ], + "inputs": { + "instances": [ + { + "name": "CORE-ISIS", + "vrf": "default", + "dataplane": "MPLS", + }, + ] + }, + "expected": { + "result": "success", + "messages": [], + }, + }, + { + "test": VerifyISISSegmentRoutingDataplane, + "name": "Check VerifyISISSegmentRoutingDataplane is failing with incorrect dataplane", + "eos_data": [ + { + "vrfs": { + "default": { + "isisInstances": { + "CORE-ISIS": { + "dataPlane": "MPLS", + "routerId": "1.0.0.11", + "systemId": "0168.0000.0011", + "hostname": "s1-pe01", + } + } + } + } + } + ], + "inputs": { + "instances": [ + { + "name": "CORE-ISIS", + "vrf": "default", + "dataplane": "unset", + }, + ] + }, + "expected": { + "result": "failure", + "messages": ["ISIS instance CORE-ISIS is not running dataplane unset (MPLS)"], + }, + }, + { + "test": VerifyISISSegmentRoutingDataplane, + "name": "Check VerifyISISSegmentRoutingDataplane is failing for unknown instance", + "eos_data": [ + { + "vrfs": { + "default": { + "isisInstances": { + "CORE-ISIS": { + "dataPlane": "MPLS", + "routerId": "1.0.0.11", + "systemId": "0168.0000.0011", + "hostname": "s1-pe01", + } + } + } + } + } + ], + "inputs": { + "instances": [ + { + "name": "CORE-ISIS2", + "vrf": "default", + "dataplane": "unset", + }, + ] + }, + "expected": { + "result": "failure", + "messages": ["Instance CORE-ISIS2 is not found in vrf default."], + }, + }, + { + "test": VerifyISISSegmentRoutingDataplane, + "name": "Check VerifyISISSegmentRoutingDataplane is failing for unknown VRF", + "eos_data": [ + { + "vrfs": { + "default": { + "isisInstances": { + "CORE-ISIS": { + "dataPlane": "MPLS", + "routerId": "1.0.0.11", + "systemId": "0168.0000.0011", + "hostname": "s1-pe01", + } + } + } + } + } + ], + "inputs": { + "instances": [ + { + "name": "CORE-ISIS", + "vrf": "wrong_vrf", + "dataplane": "unset", + }, + ] + }, + "expected": { + "result": "failure", + "messages": ["VRF wrong_vrf is not configured to run segment routing."], + }, + }, + { + "test": VerifyISISSegmentRoutingDataplane, + "name": "Check VerifyISISSegmentRoutingDataplane is skipped", + "eos_data": [{"vrfs": {}}], + "inputs": { + "instances": [ + { + "name": "CORE-ISIS", + "vrf": "wrong_vrf", + "dataplane": "unset", + }, + ] + }, + "expected": { + "result": "skipped", + "messages": ["IS-IS-SR is not running on device"], + }, + }, + { + "test": VerifyISISSegmentRoutingTunnels, + "name": "runs successfully", + "eos_data": [ + { + "entries": { + "3": { + "endpoint": "1.0.0.122/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "31": { + "endpoint": "1.0.0.13/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "32": { + "endpoint": "1.0.0.122/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "2": { + "endpoint": "1.0.0.111/32", + "vias": [ + { + "type": "tunnel", + "tunnelId": {"type": "TI-LFA", "index": 4}, + "labels": ["3"], + } + ], + }, + } + } + ], + "inputs": { + "entries": [ + {"endpoint": "1.0.0.122/32"}, + {"endpoint": "1.0.0.13/32", "vias": [{"type": "ip"}]}, + { + "endpoint": "1.0.0.111/32", + "vias": [{"type": "tunnel", "tunnel_id": "ti-lfa"}], + }, + { + "endpoint": "1.0.0.122/32", + "vias": [ + {"interface": "Ethernet1", "nexthop": "10.0.1.1"}, # Testing empty type + {"type": "ip", "interface": "Ethernet2", "nexthop": "10.0.1.3"}, + ], + }, + ] + }, + "expected": { + "result": "success", + "messages": [], + }, + }, + { + "test": VerifyISISSegmentRoutingTunnels, + "name": "is skipped if not entry founf in EOS", + "eos_data": [{"entries": {}}], + "inputs": { + "entries": [ + {"endpoint": "1.0.0.122/32"}, + ] + }, + "expected": { + "result": "skipped", + "messages": ["IS-IS-SR is not running on device."], + }, + }, + { + "test": VerifyISISSegmentRoutingTunnels, + "name": "runs successfully", + "eos_data": [ + { + "entries": { + "2": { + "endpoint": "1.0.0.111/32", + "vias": [ + { + "type": "tunnel", + "tunnelId": {"type": "TI-LFA", "index": 4}, + "labels": ["3"], + } + ], + }, + } + } + ], + "inputs": { + "entries": [ + {"endpoint": "1.0.0.122/32"}, + ] + }, + "expected": { + "result": "failure", + "messages": ["Tunnel to endpoint=IPv4Network('1.0.0.122/32') vias=None is not found."], + }, + }, + { + "test": VerifyISISSegmentRoutingTunnels, + "name": "fails with incorrect tunnel type", + "eos_data": [ + { + "entries": { + "3": { + "endpoint": "1.0.0.122/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "31": { + "endpoint": "1.0.0.13/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "32": { + "endpoint": "1.0.0.122/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "2": { + "endpoint": "1.0.0.111/32", + "vias": [ + { + "type": "tunnel", + "tunnelId": {"type": "TI-LFA", "index": 4}, + "labels": ["3"], + } + ], + }, + } + } + ], + "inputs": { + "entries": [ + {"endpoint": "1.0.0.122/32"}, + {"endpoint": "1.0.0.13/32", "vias": [{"type": "tunnel"}]}, + ] + }, + "expected": { + "result": "failure", + "messages": ["Tunnel to 1.0.0.13/32 is incorrect: incorrect tunnel type"], + }, + }, + { + "test": VerifyISISSegmentRoutingTunnels, + "name": "fails with incorrect nexthop", + "eos_data": [ + { + "entries": { + "3": { + "endpoint": "1.0.0.122/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "31": { + "endpoint": "1.0.0.13/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "32": { + "endpoint": "1.0.0.122/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "2": { + "endpoint": "1.0.0.111/32", + "vias": [ + { + "type": "tunnel", + "tunnelId": {"type": "TI-LFA", "index": 4}, + "labels": ["3"], + } + ], + }, + } + } + ], + "inputs": { + "entries": [ + {"endpoint": "1.0.0.122/32"}, + {"endpoint": "1.0.0.13/32", "vias": [{"type": "ip"}]}, + { + "endpoint": "1.0.0.122/32", + "vias": [ + {"type": "ip", "interface": "Ethernet1", "nexthop": "10.0.1.2"}, + {"type": "ip", "interface": "Ethernet2", "nexthop": "10.0.1.3"}, + ], + }, + ] + }, + "expected": { + "result": "failure", + "messages": ["Tunnel to 1.0.0.122/32 is incorrect: incorrect nexthop"], + }, + }, + { + "test": VerifyISISSegmentRoutingTunnels, + "name": "fails with incorrect nexthop", + "eos_data": [ + { + "entries": { + "3": { + "endpoint": "1.0.0.122/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "31": { + "endpoint": "1.0.0.13/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "32": { + "endpoint": "1.0.0.122/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "2": { + "endpoint": "1.0.0.111/32", + "vias": [ + { + "type": "tunnel", + "tunnelId": {"type": "TI-LFA", "index": 4}, + "labels": ["3"], + } + ], + }, + } + } + ], + "inputs": { + "entries": [ + {"endpoint": "1.0.0.122/32"}, + {"endpoint": "1.0.0.13/32", "vias": [{"type": "ip"}]}, + { + "endpoint": "1.0.0.122/32", + "vias": [ + {"type": "ip", "interface": "Ethernet4", "nexthop": "10.0.1.1"}, + {"type": "ip", "interface": "Ethernet2", "nexthop": "10.0.1.3"}, + ], + }, + ] + }, + "expected": { + "result": "failure", + "messages": ["Tunnel to 1.0.0.122/32 is incorrect: incorrect interface"], + }, + }, + { + "test": VerifyISISSegmentRoutingTunnels, + "name": "fails with incorrect interface", + "eos_data": [ + { + "entries": { + "3": { + "endpoint": "1.0.0.122/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "31": { + "endpoint": "1.0.0.13/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "32": { + "endpoint": "1.0.0.122/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "2": { + "endpoint": "1.0.0.111/32", + "vias": [ + { + "type": "tunnel", + "tunnelId": {"type": "TI-LFA", "index": 4}, + "labels": ["3"], + } + ], + }, + } + } + ], + "inputs": { + "entries": [ + {"endpoint": "1.0.0.122/32"}, + {"endpoint": "1.0.0.13/32", "vias": [{"type": "ip"}]}, + { + "endpoint": "1.0.0.122/32", + "vias": [ + {"type": "ip", "interface": "Ethernet1", "nexthop": "10.0.1.2"}, + {"type": "ip", "interface": "Ethernet2", "nexthop": "10.0.1.3"}, + ], + }, + ] + }, + "expected": { + "result": "failure", + "messages": ["Tunnel to 1.0.0.122/32 is incorrect: incorrect nexthop"], + }, + }, + { + "test": VerifyISISSegmentRoutingTunnels, + "name": "fails with incorrect tunnel ID type", + "eos_data": [ + { + "entries": { + "3": { + "endpoint": "1.0.0.122/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "31": { + "endpoint": "1.0.0.13/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "32": { + "endpoint": "1.0.0.122/32", + "vias": [ + { + "type": "ip", + "nexthop": "10.0.1.1", + "interface": "Ethernet1", + "labels": ["900021"], + }, + { + "type": "ip", + "nexthop": "10.0.1.3", + "interface": "Ethernet2", + "labels": ["900021"], + }, + ], + }, + "2": { + "endpoint": "1.0.0.111/32", + "vias": [ + { + "type": "tunnel", + "tunnelId": {"type": "TI-LFA", "index": 4}, + "labels": ["3"], + } + ], + }, + } + } + ], + "inputs": { + "entries": [ + {"endpoint": "1.0.0.122/32"}, + {"endpoint": "1.0.0.13/32", "vias": [{"type": "ip"}]}, + { + "endpoint": "1.0.0.111/32", + "vias": [ + {"type": "tunnel", "tunnel_id": "unset"}, + ], + }, + ] + }, + "expected": { + "result": "failure", + "messages": ["Tunnel to 1.0.0.111/32 is incorrect: incorrect tunnel ID"], + }, + }, ] + + +COMMAND_OUTPUT = { + "vrfs": { + "default": { + "isisInstances": { + "CORE-ISIS": { + "interfaces": { + "Loopback0": { + "enabled": True, + "intfLevels": { + "2": { + "ipv4Metric": 10, + "sharedSecretProfile": "", + "isisAdjacencies": [], + "passive": True, + "v4Protection": "disabled", + "v6Protection": "disabled", + } + }, + "areaProxyBoundary": False, + }, + "Ethernet1": { + "intfLevels": { + "2": { + "ipv4Metric": 10, + "numAdjacencies": 1, + "linkId": "84", + "sharedSecretProfile": "", + "isisAdjacencies": [], + "passive": False, + "v4Protection": "link", + "v6Protection": "disabled", + } + }, + "interfaceSpeed": 1000, + "areaProxyBoundary": False, + }, + } + } + } + }, + "EMPTY": {"isisInstances": {}}, + "NO_INTERFACES": {"isisInstances": {"CORE-ISIS": {}}}, + } +} +EXPECTED_LOOPBACK_0_OUTPUT = { + "enabled": True, + "intfLevels": { + "2": { + "ipv4Metric": 10, + "sharedSecretProfile": "", + "isisAdjacencies": [], + "passive": True, + "v4Protection": "disabled", + "v6Protection": "disabled", + } + }, + "areaProxyBoundary": False, +} + + +@pytest.mark.parametrize( + ("interface", "vrf", "expected_value"), + [ + pytest.param("Loopback0", "WRONG_VRF", None, id="VRF_not_found"), + pytest.param("Loopback0", "EMPTY", None, id="VRF_no_ISIS_instances"), + pytest.param("Loopback0", "NO_INTERFACES", None, id="ISIS_instance_no_interfaces"), + pytest.param("Loopback42", "default", None, id="interface_not_found"), + pytest.param("Loopback0", "default", EXPECTED_LOOPBACK_0_OUTPUT, id="interface_found"), + ], +) +def test__get_interface_data(interface: str, vrf: str, expected_value: dict[str, Any] | None) -> None: + """Test anta.tests.routing.isis._get_interface_data.""" + assert _get_interface_data(interface, vrf, COMMAND_OUTPUT) == expected_value diff --git a/tests/units/cli/get/test_commands.py b/tests/units/cli/get/test_commands.py index e0b17a0..1e8c6e9 100644 --- a/tests/units/cli/get/test_commands.py +++ b/tests/units/cli/get/test_commands.py @@ -11,6 +11,7 @@ from typing import TYPE_CHECKING from unittest.mock import ANY, patch import pytest +import requests from cvprac.cvp_client_errors import CvpApiError from anta.cli._main import anta @@ -24,19 +25,25 @@ DATA_DIR: Path = Path(__file__).parents[3].resolve() / "data" @pytest.mark.parametrize( - ("cvp_container", "cvp_connect_failure"), + ("cvp_container", "verify_cert", "cv_token_failure", "cvp_connect_failure"), [ - pytest.param(None, False, id="all devices"), - pytest.param("custom_container", False, id="custom container"), - pytest.param(None, True, id="cvp connect failure"), + pytest.param(None, True, False, False, id="all devices - verify cert"), + pytest.param(None, True, True, False, id="all devices - fail SSL check"), + pytest.param(None, False, False, False, id="all devices - do not verify cert"), + pytest.param("custom_container", False, False, False, id="custom container"), + pytest.param(None, False, False, True, id="cvp connect failure"), ], ) def test_from_cvp( tmp_path: Path, click_runner: CliRunner, cvp_container: str | None, + verify_cert: bool, + cv_token_failure: bool, cvp_connect_failure: bool, ) -> None: + # pylint: disable=too-many-arguments + # ruff: noqa: C901 """Test `anta get from-cvp`. This test verifies that username and password are NOT mandatory to run this command @@ -57,6 +64,12 @@ def test_from_cvp( if cvp_container is not None: cli_args.extend(["--container", cvp_container]) + if not verify_cert: + cli_args.extend(["--ignore-cert"]) + + def mock_get_cv_token(*_args: str, **_kwargs: str) -> None: + if cv_token_failure: + raise requests.exceptions.SSLError def mock_cvp_connect(_self: CvpClient, *_args: str, **_kwargs: str) -> None: if cvp_connect_failure: @@ -64,7 +77,7 @@ def test_from_cvp( # always get a token with ( - patch("anta.cli.get.commands.get_cv_token", return_value="dummy_token"), + patch("anta.cli.get.commands.get_cv_token", autospec=True, side_effect=mock_get_cv_token), patch( "cvprac.cvp_client.CvpClient.connect", autospec=True, @@ -79,20 +92,27 @@ def test_from_cvp( ): result = click_runner.invoke(anta, cli_args) - if not cvp_connect_failure: + if not cvp_connect_failure and not cv_token_failure: assert output.exists() + if cv_token_failure: + assert "Authentication to CloudVison failed" in result.output + assert result.exit_code == ExitCode.USAGE_ERROR + return + mocked_cvp_connect.assert_called_once() - if not cvp_connect_failure: - assert "Connected to CloudVision" in result.output - if cvp_container is not None: - mocked_get_devices_in_container.assert_called_once_with(ANY, cvp_container) - else: - mocked_get_inventory.assert_called_once() - assert result.exit_code == ExitCode.OK - else: + + if cvp_connect_failure: assert "Error connecting to CloudVision" in result.output assert result.exit_code == ExitCode.USAGE_ERROR + return + + assert "Connected to CloudVision" in result.output + if cvp_container is not None: + mocked_get_devices_in_container.assert_called_once_with(ANY, cvp_container) + else: + mocked_get_inventory.assert_called_once() + assert result.exit_code == ExitCode.OK @pytest.mark.parametrize( diff --git a/tests/units/cli/get/test_utils.py b/tests/units/cli/get/test_utils.py index 7ce85dc..e105f94 100644 --- a/tests/units/cli/get/test_utils.py +++ b/tests/units/cli/get/test_utils.py @@ -19,7 +19,14 @@ from anta.inventory import AntaInventory DATA_DIR: Path = Path(__file__).parents[3].resolve() / "data" -def test_get_cv_token() -> None: +@pytest.mark.parametrize( + "verify_cert", + [ + pytest.param(True, id="Verify cert enabled"), + pytest.param(False, id="Verify cert disabled"), + ], +) +def test_get_cv_token(verify_cert: bool) -> None: """Test anta.get.utils.get_cv_token.""" ip_addr = "42.42.42.42" username = "ant" @@ -29,13 +36,13 @@ def test_get_cv_token() -> None: mocked_ret = MagicMock(autospec=requests.Response) mocked_ret.json.return_value = {"sessionId": "simple"} patched_request.return_value = mocked_ret - res = get_cv_token(ip_addr, username, password) + res = get_cv_token(ip_addr, username, password, verify_cert=verify_cert) patched_request.assert_called_once_with( "POST", "https://42.42.42.42/cvpservice/login/authenticate.do", headers={"Content-Type": "application/json", "Accept": "application/json"}, data='{"userId": "ant", "password": "formica"}', - verify=False, + verify=verify_cert, timeout=10, ) assert res == "simple" |