napalm-automation-community / napalm-ros

MikroTik RouterOS NAPALM driver
100 stars 39 forks source link

Support for RouterOS v7 #133

Open bramwittendorp opened 3 weeks ago

bramwittendorp commented 3 weeks ago

Description of Issue/Question

The BGP syntax has changed between RouterOS v6 and RouterOS v7. The bgp-functionality in this driver is not working on RouterOS v7.

Setup

napalm-ros version

(Paste verbatim output from pip freeze | grep napalm-ros between quotes below)

napalm-ros==1.2.6

ROS version

(Paste verbatim output from /system package print between quotes below)

7.15.1 (but applies to all 7.x versions)

librouteros version

(Paste verbatim output from pip freeze | grep librouteros between quotes below)

librouteros==3.2.1

python version

(paste output of python --version)

Python 3.9.18

Steps to Reproduce the Issue

Error Traceback

(Paste the complete traceback of the exception between quotes below)

napalm --user <<redacted >> --vendor napalm_ros <<redacted>> call get_bgp_neighbors
Enter password:
2024-08-19 20:37:33,355 - napalm - ERROR - method - Failed: 'prefix'

================= Traceback =================

Traceback (most recent call last):
  File "/opt/peering-manager/venv/bin/napalm", line 8, in <module>
    sys.exit(main())
  File "/opt/peering-manager/venv/lib64/python3.9/site-packages/napalm/base/clitools/cl_napalm.py", line 308, in main
    run_tests(args)
  File "/opt/peering-manager/venv/lib64/python3.9/site-packages/napalm/base/clitools/cl_napalm.py", line 291, in run_tests
    call_getter(device, args.method, **method_kwargs)
  File "/opt/peering-manager/venv/lib64/python3.9/site-packages/napalm/base/clitools/cl_napalm.py", line 27, in wrapper
    r = func(*args, **kwargs)
  File "/opt/peering-manager/venv/lib64/python3.9/site-packages/napalm/base/clitools/cl_napalm.py", line 255, in call_getter
    r = func(**kwargs)
  File "/opt/peering-manager/venv/lib64/python3.9/site-packages/napalm_ros/ros.py", line 116, in get_bgp_neighbors
    ip_version = IPNetwork(route["prefix"]).version
KeyError: 'prefix'
bramwittendorp commented 3 weeks ago

Below an overview of all commands:

luqasz commented 3 weeks ago

Could you paste output of bgp items (anomized of course) ? I don't have any working BGP peers to test.

bramwittendorp commented 3 weeks ago

Sure, I have identified that the first part is already where the main issue occurs. Currently the code is calling for menu's like: /routing/bgp/peer/print or /routing/bgp/instance/print. These levels don't exist anymore in RouterOSv7.

For example you'll need the /routing/bgp/session/print command to show an overview of the (established) BGP sessions. That's what I am using in the snippet below.

>>> from librouteros import connect
>>> from pprint import pprint
>>> api = connect(
... username='<<redacted>>',
... password='<<redacted>>',
... host='<<redacted>>',
... )
>>>
>>> for row in api('/routing/bgp/session/print'):
...     pprint(row)
...
{'.id': '*2800001',
 'ebgp': '',
 'established': True,
 'hold-time': '3m',
 'input.procid': 20,
 'keepalive-time': '1m',
 'last-started': '2024-07-31 08:40:13',
 'local.address': '2001:db8:1234:70::1',
 'local.afi': 'ipv6',
 'local.as': 65000,
 'local.bytes': 546189,
 'local.capabilities': 'mp,rr,gr,as4',
 'local.eor': '',
 'local.id': '172.16.0.254',
 'local.messages': 28733,
 'name': 'test-bgp-1',
 'output.procid': 20,
 'output.remove-private-as': True,
 'prefix-count': 0,
 'remote.address': '2001:db8:1234:70::253',
 'remote.afi': 'ipv6',
 'remote.as': 65200,
 'remote.bytes': 545851,
 'remote.capabilities': 'mp,rr,gr,as4',
 'remote.eor': '',
 'remote.id': '172.16.12.253',
 'remote.messages': 28729,
 'uptime': '2w5d22h50m25s190ms'}

I think the main question is: do we want to support both RouterOS v6 and RouterOS v7 in the same version of the driver? I can imagine creating a 2.X release that supports RouterOS 7 but lacks support for RouterOS 6 (which would require 1.X releases).

I am open to contributing to this issue myself, I am not an experienced developer. But I believe in contributing to the community and this might be a useful way to develop my python-skills.

luqasz commented 3 weeks ago

Driver can support both versions. It's just a matter of executing different functions depending on version. tests/unit/mocked_data/test_get_bgp_neighbors/ipv4-only This is a sample mocked data which well mocks real data on device. I can help you develop a patch for v7.x The trick here is to mock data from v7.x and write code that extracts necessary info. You can put mocked data for v7.x into tests/unit/mocked_data/test_get_bgp_neighbors/v7.x/ and write code. file names starting with _ represent command that would be run on mikrotik. _routing_bgp_peer_print.json is equal to /routing/bgp/peer/print in api.