[email protected] - June 2020 - Copyright
This tool contains two modes :
- Integrity & Sanity checks
- CLI
The idea of this project is to offer a test platform for the network to allow engineers to perform tests without having to write python code (or other languages ๐).
In addition, this platform does not consider the OS, it is possible to run tests on Cisco, Cumulus, Juniper devices without changing the data structure.
- You have to create a Nornir or an Ansible inventory (Example based on an Ansible Inventory)
hosts
file.
[leaf]
leaf01 # Cumulus Networks
leaf02 # Cisco Nexus 9k
leaf03 # Arista vEOS
leaf04 # Juniper Networks
leaf05 # Cisco IOS
[spine]
spine01 # Cumulus Networks
spine02 # Extreme Networks VSP
spine03 # Cisco IOS-XR
- Define device parameters in
host_vars/inventory_hostname.yml
files
hostname: 10.0.5.202
platform: linux # <<=== specify device OS (Cumulus Linux)
username: admin
password: Ci$co123
connexion: ssh # <<=== specify connexion method - check supported protocols
port: 22
hostname: 10.0.5.204
platform: junos # <<=== specify device OS (Juniper)
username: root
password: Jun1p3r
connexion: netconf # <<=== specify connexion method - check supported protocols
port: 830
hostname: 10.0.5.203
platform: eos # <<=== specify device OS (Arista)
username: admin
password: admin123
connexion: api # <<=== specify connexion method - check supported protocols
port: 443
Tests are defined in the file netests.yml
. In this file you can define which test will be executed.
config:
nornir_cfg: ./nornir/config_ansible.yml
inventory: ./inventory/ansible/hosts
protocols:
bgp:
test: false
cdp:
test: false
lldp:
test: true
facts:
test: false
ping:
test: false
In truth_vars/
you need to define the configuration that you want on your production devices.
There are three ways to define variables :
- For a specific host - define your configuration in
truth_vars/hosts/hostname/protocol.yml
LLDP configuration
- local_name: leaf03
local_port: Ethernet1
neighbor_mgmt_ip: 192.168.1.148
neighbor_name: cumulus
neighbor_os: Cumulus Linux version 4.0.0
neighbor_port: swp1
neighbor_type: ["Bridge", "Router"]
Will test that the neighbor on the port
Ethernet1
is a device namedcumulus
and the connexion is on the portswp1
.
- For all hosts defined in a group - such as
spines
- define intruth_vars/groups/group/protocol.yml
Group is spine-arista
.
Facts configuration
domain: dh.local
version: 4.24.0F
Will test if all devices linked to this group has
dh.local
as domain name,4.24.0F
as version.
- for all devices - define
truth_vars/all/{{ protocol }}.yml
domain: dh.local
Will test if all devices in your inventory have t domain
dh.local
.
The script will connect on each devices, retrieveinformations and campre them with the data define in your truth_vars/
(source of truth).
If the informations are the same the tests is OK ๐
./netests.py -x -i inventory/ansible/hosts -a netests.yml
[netests - base_run.py](ping) is working = True
# -x / Define that you will use an Ansible inventory
# -i / Path to your Ansible inventory
# -a / Path to your netests configuration file (default is netests.yml)
You can get some informations regarding you network configuration directly from the CLI.
This tool will use your Ansible/Nornir/Netbox Inventory. For example :
[leaf]
leaf01
leaf02
leaf03
leaf04
leaf05
[spine]
spine01
spine02
spine03
โก ./netests.py -x -i inventory/ansible/hosts -a netests.yml -t
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Welcome to Netests CLI
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
> help
+------------------------------------------------------------+
| Netests Help |
+------------------------------------------------------------+
| [help] Display help |
| [select] Select devices on which on action will be exec |
| [unselect] Remove a device from the selected |
| [selected] Show devices currently selected |
| [get xx] Get XX protocols informations |
| [options] Set arguments that will retrieve for a Protocol|
| [more xx] Show XX Protocol class arguments selected |
| [show xx] Show XX Protocol class arguments |
| [print yy] Show YY devices informations |
| [compare yy xx] Compare device config with source of truth|
| [exit] Quit Netests CLI |
+------------------------------------------------------------+
> help options
+------------------------------------------------------------+
| Netests - Options Commands |
+------------------------------------------------------------+
| This command is used to define which parameter will be |
| retrieve for a protocol. |
| It is possible to get a subset of protocols parameters. |
| Format : |
| > options {{ protocol }} {{ classArg1,classArg2 }} |
| (To get all protocols parameters use the 'show' command) |
| |
| Examples : |
| > options vrf vrf_name,rd,rt_imp,rt_exp |
+------------------------------------------------------------+
{ 'leaf01': { 'connexion': 'ssh',
'hostname': '172.16.194.51',
'platform': 'linux',
'port': 22},
'leaf02': { 'connexion': 'api',
'hostname': 'sbx-nxos-mgmt.cisco.com',
'platform': 'nxos',
'port': 443},
'leaf04': { 'connexion': 'netconf',
'hostname': '66.129.235.11',
'platform': 'junos',
'port': 40002},
'leaf05': { 'connexion': 'ssh',
'hostname': 'ios-xe-mgmt.cisco.com',
'platform': 'ios',
'port': 8181}}
At the beginning if you use a command to get some network informations, nothing will happend. The reason is that no device is selected.
> get vrf
[[netests - get_vrf]] no device selected.
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
@End GET
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
You have to select devices on which one you would get informations
> select *
@Followings devices will be added to the list :
@['leaf01', 'leaf02', 'leaf03', 'leaf04', 'leaf05', 'spine01', 'spine02', 'spine03']
> select leaf01,spine03
@Followings devices will be added to the list :
@['leaf01', 'spine03']
> selected
@Followings devices are selected :
@['leaf01', 'leaf02', 'leaf04', 'leaf05']
Run the command get
and the protocols that you would like retrieve.
> select leaf01,spine03
@Followings devices will be added to the list :
@['leaf01', 'spine03']
> get vrf
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
>>>>> spine03
{ 'ListVRF': [ { 'VRF': { 'exp_targ': 'NOT_SET',
'imp_targ': 'NOT_SET',
'l3_vni': 'NOT_SET',
'rd': 'NOT_SET',
'rt_exp': 'NOT_SET',
'rt_imp': 'NOT_SET',
'vrf_id': 'NOT_SET',
'vrf_name': 'MGMT_VRF',
'vrf_type': 'NOT_SET'}},
{ 'VRF': { 'exp_targ': 'NOT_SET',
'imp_targ': 'NOT_SET',
'l3_vni': 'NOT_SET',
'rd': 'NOT_SET',
'rt_exp': '65000:1',
'rt_imp': '65000:1',
'vrf_id': 'NOT_SET',
'vrf_name': 'EXTERNAL_PEERING',
'vrf_type': 'NOT_SET'}}]}
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
>>>>> leaf01
{ 'ListVRF': [ { 'VRF': { 'exp_targ': 'NOT_SET',
'imp_targ': 'NOT_SET',
'l3_vni': 'NOT_SET',
'rd': 'NOT_SET',
'rt_exp': 'NOT_SET',
'rt_imp': 'NOT_SET',
'vrf_id': '1001',
'vrf_name': 'mgmt',
'vrf_type': 'NOT_SET'}}]}
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
@End GET
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
> compare facts
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
{ 'Facts': { 'base_mac': 'NOT_SET',
'build': 'fc2',
'domain': 'NOT_SET',
'hostname': 'csr1000v',
'interfaces_lst': [ 'GigabitEthernet1',
'GigabitEthernet2',
'GigabitEthernet3',
'Loopback3',
'Loopback1234',
'Loopback9009'],
'memory': '8113280',
'model': 'CSR1000V',
'serial': '9OOFTICVAFM',
'vendor': 'Cisco',
'version': '16.9.3'}}
[netests - compare_facts] Key infos_data is missingfor leaf05 or no Facts data has been found.
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
@The following devices have the same configuration that defined in the source of truth :
@[leaf05].
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
>
Dylan Hamel - [email protected]