napalm-automation-community / napalm-ros

MikroTik RouterOS NAPALM driver
104 stars 39 forks source link

Ping broken on ROS 7.10 - ValueError: could not convert string to float: '27699us' #120

Closed ggiesen closed 1 year ago

ggiesen commented 1 year ago

Description of Issue/Question

When attempting a ping using ROS 7.10, I receive a ValueError: could not convert string to float: '27699us'

$ napalm --debug --user admin --password Iecee3quoh1Aimoh --vendor ros 192.0.2.1 call ping --method-kwargs "destination='198.51.100.1'"
2023-06-27 17:13:15,084 - napalm - DEBUG - Starting napalm's debugging tool
2023-06-27 17:13:15,084 - napalm - DEBUG - Gathering napalm packages
2023-06-27 17:13:15,085 - napalm - DEBUG - napalm-ros==1.2.4
2023-06-27 17:13:15,085 - napalm - DEBUG - napalm==4.1.0
2023-06-27 17:13:15,086 - napalm - DEBUG - get_network_driver - Calling with args: ('ros',), {}
2023-06-27 17:13:15,104 - napalm - DEBUG - get_network_driver - Successful
2023-06-27 17:13:15,104 - napalm - DEBUG - __init__ - Calling with args: (<class 'napalm_ros.ros.ROSDriver'>, '192.0.2.1', 'admin'), {'password': '*******', 'timeout': 60, 'optional_args': {}}
2023-06-27 17:13:15,105 - napalm - DEBUG - __init__ - Successful
2023-06-27 17:13:15,106 - napalm - DEBUG - pre_connection_tests - Calling with args: (<napalm_ros.ros.ROSDriver object at 0x7f2aecaf20d0>,), {}
2023-06-27 17:13:15,106 - napalm - DEBUG - open - Calling with args: (<napalm_ros.ros.ROSDriver object at 0x7f2aecaf20d0>,), {}
2023-06-27 17:13:15,245 - napalm - DEBUG - open - Successful
2023-06-27 17:13:15,246 - napalm - DEBUG - connection_tests - Calling with args: (<napalm_ros.ros.ROSDriver object at 0x7f2aecaf20d0>,), {}
2023-06-27 17:13:15,246 - napalm - DEBUG - get_facts - Calling with args: (<napalm_ros.ros.ROSDriver object at 0x7f2aecaf20d0>,), {}
2023-06-27 17:13:15,536 - napalm - DEBUG - Gathered facts:
{
    "uptime": 102476.0,
    "vendor": "MikroTik",
    "model": "RBM33G",
    "hostname": "mikrominion",
    "fqdn": "",
    "os_version": "7.10 (stable)",
    "serial_number": "HDG00000000",
    "interface_list": [
        "bridge1",
        "ether1",
        "ether2",
        "ether3",
        "gre-tunnel1",
        "gre-tunnel2",
        "gre-tunnel3",
        "gre-tunnel4",
        "lo1",
        "lo2",
        "lte1",
        "lte2",
        "vlan1"
    ]
}
{
    "uptime": 102476.0,
    "vendor": "MikroTik",
    "model": "RBM33G",
    "hostname": "mikrominion",
    "fqdn": "",
    "os_version": "7.10 (stable)",
    "serial_number": "HDG00000000",
    "interface_list": [
        "bridge1",
        "ether1",
        "ether2",
        "ether3",
        "gre-tunnel1",
        "gre-tunnel2",
        "gre-tunnel3",
        "gre-tunnel4",
        "lo1",
        "lo2",
        "lte1",
        "lte2",
        "vlan1"
    ]
}
2023-06-27 17:13:15,541 - napalm - DEBUG - get_facts - Successful
2023-06-27 17:13:15,541 - napalm - DEBUG - method - Calling with args: (<napalm_ros.ros.ROSDriver object at 0x7f2aecaf20d0>, 'ping'), {'destination': '198.51.100.1'}
2023-06-27 17:13:15,542 - napalm - DEBUG - ping - Attempting to resolve method
2023-06-27 17:13:15,542 - napalm - DEBUG - ping - Attempting to call method with kwargs: {'destination': '198.51.100.1'}
2023-06-27 17:13:19,662 - napalm - ERROR - method - Failed: could not convert string to float: '27699us'

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

Traceback (most recent call last):
  File "/opt/napalm/bin/napalm", line 8, in <module>
    sys.exit(main())
  File "/opt/napalm/lib64/python3.9/site-packages/napalm/base/clitools/cl_napalm.py", line 308, in main
    run_tests(args)
  File "/opt/napalm/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/napalm/lib64/python3.9/site-packages/napalm/base/clitools/cl_napalm.py", line 27, in wrapper
    r = func(*args, **kwargs)
  File "/opt/napalm/lib64/python3.9/site-packages/napalm/base/clitools/cl_napalm.py", line 255, in call_getter
    r = func(**kwargs)
  File "/opt/napalm/lib64/python3.9/site-packages/napalm_ros/ros.py", line 504, in ping
    'rtt_min': min(rtt('min-rtt', results)),
  File "/opt/napalm/lib64/python3.9/site-packages/napalm_ros/utils.py", line 7, in <genexpr>
    return (float(row.get(key, '-1ms').replace('ms', '')) for row in iterable)
ValueError: could not convert string to float: '27699us'

Setup

napalm-ros version

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

napalm-ros==1.2.4

ROS version

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

Columns: NAME, VERSION
# NAME      VERSION
0 routeros  7.10 

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.16

Steps to Reproduce the Issue

Error Traceback

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

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

Traceback (most recent call last):
  File "/opt/napalm/bin/napalm", line 8, in <module>
    sys.exit(main())
  File "/opt/napalm/lib64/python3.9/site-packages/napalm/base/clitools/cl_napalm.py", line 308, in main
    run_tests(args)
  File "/opt/napalm/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/napalm/lib64/python3.9/site-packages/napalm/base/clitools/cl_napalm.py", line 27, in wrapper
    r = func(*args, **kwargs)
  File "/opt/napalm/lib64/python3.9/site-packages/napalm/base/clitools/cl_napalm.py", line 255, in call_getter
    r = func(**kwargs)
  File "/opt/napalm/lib64/python3.9/site-packages/napalm_ros/ros.py", line 504, in ping
    'rtt_min': min(rtt('min-rtt', results)),
  File "/opt/napalm/lib64/python3.9/site-packages/napalm_ros/utils.py", line 7, in <genexpr>
    return (float(row.get(key, '-1ms').replace('ms', '')) for row in iterable)
ValueError: could not convert string to float: '27699us'
ggiesen commented 1 year ago

I've managed to make a quick fix to this with the following patch:

--- a/ros.py      2023-06-28 16:27:20.625172826 +0000
+++ b/ros.py      2023-06-28 16:29:09.245630466 +0000
@@ -503,7 +503,7 @@
             'packet_loss': max(row['packet-loss'] for row in results),
             'rtt_min': min(rtt('min-rtt', results)),
             'rtt_max': max(rtt('max-rtt', results)),  # Last result has calculated avg
-            'rtt_avg': float(results[-1].get('avg-rtt', '-1ms').replace('ms', '')),
+            'rtt_avg': float(re.sub(r'([0-9]+)ms(?:([0-9]+)+us)?', r'\1.\2', results[-1].get('avg-rtt', '-1ms'))),
             'rtt_stddev': float(-1),
             'results': []
         }
@@ -511,7 +511,7 @@
         for row in results:
             ping_results['results'].append({
                 'ip_address': cast_ip(row['host']),
-                'rtt': float(row.get('time', '-1ms').replace('ms', '')),
+                'rtt': float(re.sub(r'([0-9]+)ms(?:([0-9]+)+us)?', r'\1.\2', row.get('time', '-1ms'))),
             })

         return dict(success=ping_results)
--- a/utils.py      2023-06-28 16:29:56.460723748 +0000
+++ b/utils.py      2023-06-28 16:10:04.953124459 +0000
@@ -2,9 +2,11 @@
     ip as cast_ip,
 )

+import re
+

 def rtt(key, iterable):
-    return (float(row.get(key, '-1ms').replace('ms', '')) for row in iterable)
+    return (float(re.sub(r'([0-9]+)ms(?:([0-9]+)+us)?', r'\1.\2', row.get(key, '-1ms'))) for row in iterable)

 def to_seconds(time_format):

It should work for both ROS6 (no µs) and ROS7 (includes µs)

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

luqasz commented 1 year ago

Sorry for leaving this issue.