Giter VIP home page Giter VIP logo

napalm-asa's People

Contributors

diogoandre avatar mirceaulinic avatar optiz0r avatar wvandeun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

napalm-asa's Issues

py23_compat has been removed but it is still used in tests

This patch needs to be applied:

---
 napalm_asa/asa.py |    7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

--- a/napalm_asa/asa.py
+++ b/napalm_asa/asa.py
@@ -30,7 +30,6 @@ from collections import OrderedDict
 from netaddr import IPNetwork
 
 from napalm.base import NetworkDriver
-from napalm.base.utils import py23_compat
 from napalm.base.exceptions import (
     ConnectionException,
     CommandErrorException,
@@ -70,7 +69,7 @@ class RespFetcherHttps:
             else:
                 return (False, token_request.status_code)
         except requests.exceptions.RequestException as e:
-            raise ConnectionException(py23_compat.text_type(e))
+            raise ConnectionException(str(e))
 
     def delete_token(self):
         """Delete auth token."""
@@ -85,7 +84,7 @@ class RespFetcherHttps:
             else:
                 return (False, token_delete_request.status_code)
         except requests.exceptions.RequestException as e:
-            raise ConnectionException(py23_compat.text_type(e))
+            raise ConnectionException(str(e))
 
     def get_resp(self, endpoint="", data=None):
         """Get response from device and returne parsed json."""
@@ -103,7 +102,7 @@ class RespFetcherHttps:
 
             return f.json()
         except requests.exceptions.RequestException as e:
-            raise ConnectionException(py23_compat.text_type(e))
+            raise ConnectionException(str(e))
 
 
 class ASADriver(NetworkDriver):

Multiple tests fail with napalm 4.0.0

While packaging for openSUSE/Factory with napalm 4.0.0 some tests are failing:

[   28s] =================================== FAILURES ===================================
[   28s] ______________________ TestGetter.test_method_signatures _______________________
[   28s] 
[   28s] self = <test.unit.test_getters.TestGetter object at 0x7fe5c6be0610>
[   28s] 
[   28s]     def test_method_signatures(self):
[   28s]         """
[   28s]         Test that all methods have the same signature.
[   28s]     
[   28s]         The type hint annotations are ignored here because the import paths might differ."""
[   28s]         errors = {}
[   28s]         cls = self.driver
[   28s]         # Create fictional driver instance (py3 needs bound methods)
[   28s]         tmp_obj = cls(hostname="test", username="admin", password="pwd")
[   28s]         attrs = [m for m, v in inspect.getmembers(tmp_obj)]
[   28s]         for attr in attrs:
[   28s]             func = getattr(tmp_obj, attr)
[   28s]             if attr.startswith("_") or not inspect.ismethod(func):
[   28s]                 continue
[   28s]             try:
[   28s]                 orig = getattr(NetworkDriver, attr)
[   28s]                 orig_spec = inspect.getfullargspec(orig)[:4]
[   28s]             except AttributeError:
[   28s]                 orig_spec = "Method does not exist in napalm.base"
[   28s]             func_spec = inspect.getfullargspec(func)[:4]
[   28s]             if orig_spec != func_spec:
[   28s]                 errors[attr] = (orig_spec, func_spec)
[   28s]     
[   28s]         EXTRA_METHODS = ["__init__"]
[   28s]         for method in EXTRA_METHODS:
[   28s]             orig_spec = inspect.getfullargspec(getattr(NetworkDriver, method))[:4]
[   28s]             func_spec = inspect.getfullargspec(getattr(cls, method))[:4]
[   28s]             if orig_spec != func_spec:
[   28s]                 errors[attr] = (orig_spec, func_spec)
[   28s]     
[   28s] >       assert not errors, "Some methods vary. \n{}".format(errors.keys())
[   28s] E       AssertionError: Some methods vary. 
[   28s] E       dict_keys(['cli'])
[   28s] 
[   28s] /usr/lib/python3.8/site-packages/napalm/base/test/getters.py:141: AssertionError
[   28s] ______________________ TestGetter.test_get_facts[normal] _______________________
[   28s] 
[   28s] self = <test.unit.test_getters.TestGetter object at 0x7fe5c6be0e80>
[   28s] test_case = 'normal'
[   28s] 
[   28s]     @wrap_test_cases
[   28s]     def test_get_facts(self, test_case):
[   28s]         """Test get_facts method."""
[   28s]         facts = self.device.get_facts()
[   28s] >       assert helpers.test_model(models.FactsDict, facts)
[   28s] E       AssertionError
[   28s] 
[   28s] /usr/lib/python3.8/site-packages/napalm/base/test/getters.py:154: AssertionError
[   28s] _______________________ TestGetter.test_get_facts[stack] _______________________
[   28s] 
[   28s] self = <test.unit.test_getters.TestGetter object at 0x7fe5c6bc0760>
[   28s] test_case = 'stack'
[   28s] 
[   28s]     @wrap_test_cases
[   28s]     def test_get_facts(self, test_case):
[   28s]         """Test get_facts method."""
[   28s]         facts = self.device.get_facts()
[   28s] >       assert helpers.test_model(models.FactsDict, facts)
[   28s] E       AssertionError
[   28s] 
[   28s] /usr/lib/python3.8/site-packages/napalm/base/test/getters.py:154: AssertionError
[   28s] ____________________ TestGetter.test_get_interfaces[normal] ____________________
[   28s] 
[   28s] self = <test.unit.test_getters.TestGetter object at 0x7fe5c6bc0a00>
[   28s] test_case = 'normal'
[   28s] 
[   28s]     @wrap_test_cases
[   28s]     def test_get_interfaces(self, test_case):
[   28s]         """Test get_interfaces."""
[   28s]         get_interfaces = self.device.get_interfaces()
[   28s]         assert len(get_interfaces) > 0
[   28s]     
[   28s]         for interface, interface_data in get_interfaces.items():
[   28s] >           assert helpers.test_model(models.InterfaceDict, interface_data)
[   28s] E           AssertionError
[   28s] 
[   28s] /usr/lib/python3.8/site-packages/napalm/base/test/getters.py:164: AssertionError
[   28s] ______________________ TestGetter.test_traceroute[normal] ______________________
[   28s] 
[   28s] cls = <test.unit.test_getters.TestGetter object at 0x7fe5c6bea130>
[   28s] test_case = 'normal'
[   28s] 
[   28s]     @functools.wraps(func)
[   28s]     def mock_wrapper(cls, test_case):
[   28s]         for patched_attr in cls.device.patched_attrs:
[   28s]             attr = getattr(cls.device, patched_attr)
[   28s]             attr.current_test = func.__name__
[   28s]             attr.current_test_case = test_case
[   28s]     
[   28s]         try:
[   28s]             # This is an ugly, ugly, ugly hack because some python objects don't load
[   28s]             # as expected. For example, dicts where integers are strings
[   28s]             result = json.loads(json.dumps(func(cls, test_case)))
[   28s]         except IOError:
[   28s]             if test_case == "no_test_case_found":
[   28s]                 pytest.fail("No test case for '{}' found".format(func.__name__))
[   28s]             else:
[   28s]                 raise
[   28s]         except NotImplementedError:
[   28s]             pytest.skip("Method not implemented")
[   28s]             return
[   28s]     
[   28s]         # This is an ugly, ugly, ugly hack because some python objects don't load
[   28s]         # as expected. For example, dicts where integers are strings
[   28s]     
[   28s]         try:
[   28s]             expected_result = attr.expected_result
[   28s]         except IOError as e:
[   28s]             raise Exception("{}. Actual result was: {}".format(e, json.dumps(result)))
[   28s]         if isinstance(result, list):
[   28s]             diff = list_dicts_diff(result, expected_result)
[   28s]         else:
[   28s]             diff = dict_diff(result, expected_result)
[   28s]         if diff:
[   28s]             print("Resulting JSON object was: {}".format(json.dumps(result)))
[   28s] >           raise AssertionError(
[   28s]                 "Expected result varies on some keys {}".format(json.dumps(diff))
[   28s]             )
[   28s] E           AssertionError: Expected result varies on some keys {"success": {"5": {"probes": {"1": {"host_name": {"result": "", "expected": "dns.google"}}, "3": {"host_name": {"result": "", "expected": "dns.google"}}, "2": {"host_name": {"result": "", "expected": "dns.google"}}}}}}
[   28s] 
[   28s] /usr/lib/python3.8/site-packages/napalm/base/test/getters.py:83: AssertionError
[   28s] =============================== warnings summary ===============================
[   28s] ../../../../../usr/lib/python3.8/site-packages/_pytest/config/__init__.py:1252
[   28s]   /usr/lib/python3.8/site-packages/_pytest/config/__init__.py:1252: PytestConfigWarning: Unknown config option: json_report
[   28s]   
[   28s]     self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")
[   28s] 
[   28s] ../../../../../usr/lib/python3.8/site-packages/_pytest/config/__init__.py:1252
[   28s]   /usr/lib/python3.8/site-packages/_pytest/config/__init__.py:1252: PytestConfigWarning: Unknown config option: jsonapi
[   28s]   
[   28s]     self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")
[   28s] 
[   28s] -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
[   28s] 
[   28s] ---------- coverage: platform linux, python 3.8.16-final-0 -----------
[   28s] Name                                                  Stmts   Miss  Cover   Missing
[   28s] -----------------------------------------------------------------------------------
[   28s] napalm_arubaoss/ArubaOS.py                              141     29    79%   71-72, 75, 94-96, 116-118, 126-128, 138, 147, 155, 163-166, 504, 512-514, 529-533, 551-555, 569, 577-585, 620, 628, 636-638
[   28s] napalm_arubaoss/__init__.py                               2      0   100%
[   28s] napalm_arubaoss/helper/__init__.py                       24      0   100%
[   28s] napalm_arubaoss/helper/base.py                           97     68    30%   50-101, 105-114, 124-126, 136-138, 148-150, 160-162, 171-192, 205-227, 236-237
[   28s] napalm_arubaoss/helper/commit_config.py                  27     19    30%   26-60
[   28s] napalm_arubaoss/helper/compare_config.py                 22     17    23%   19-52
[   28s] napalm_arubaoss/helper/confirm_commit.py                 10      4    60%   19-23
[   28s] napalm_arubaoss/helper/get_arp_table.py                  16      0   100%
[   28s] napalm_arubaoss/helper/get_config.py                     13      2    85%   19-21
[   28s] napalm_arubaoss/helper/get_facts.py                      37      0   100%
[   28s] napalm_arubaoss/helper/get_interfaces.py                 43      5    88%   28-29, 32-33, 56
[   28s] napalm_arubaoss/helper/get_interfaces_ip.py              22      0   100%
[   28s] napalm_arubaoss/helper/get_lldp_neighbors.py             15      0   100%
[   28s] napalm_arubaoss/helper/get_lldp_neighbors_detail.py      15      0   100%
[   28s] napalm_arubaoss/helper/get_mac_address_table.py          12      0   100%
[   28s] napalm_arubaoss/helper/get_ntp_servers.py                16      0   100%
[   28s] napalm_arubaoss/helper/get_ntp_stats.py                  33      9    73%   29-38, 58, 74
[   28s] napalm_arubaoss/helper/get_route_to.py                   33      6    82%   68-83, 103
[   28s] napalm_arubaoss/helper/has_pending_commit.py              9      5    44%   18-24
[   28s] napalm_arubaoss/helper/is_alive.py                        9      5    44%   16-22
[   28s] napalm_arubaoss/helper/load_merge_candidate.py           13      8    38%   25-36
[   28s] napalm_arubaoss/helper/load_replace_candidate.py         14      9    36%   28-37
[   28s] napalm_arubaoss/helper/ping.py                           15      1    93%   25
[   28s] napalm_arubaoss/helper/rollback.py                       11      6    45%   18-25
[   28s] napalm_arubaoss/helper/traceroute.py                     23      1    96%   24
[   28s] napalm_arubaoss/helper/utils.py                          61     46    25%   19-20, 30-32, 43-62, 79-101, 112-122, 133-140
[   28s] -----------------------------------------------------------------------------------
[   28s] TOTAL                                                   733    240    67%
[   28s] 
[   28s] =========================== short test summary info ============================
[   28s] FAILED test/unit/test_getters.py::TestGetter::test_method_signatures - Assert...
[   28s] FAILED test/unit/test_getters.py::TestGetter::test_get_facts[normal] - Assert...
[   28s] FAILED test/unit/test_getters.py::TestGetter::test_get_facts[stack] - Asserti...
[   28s] FAILED test/unit/test_getters.py::TestGetter::test_get_interfaces[normal] - A...
[   28s] FAILED test/unit/test_getters.py::TestGetter::test_traceroute[normal] - Asser...
[   28s] ====== 5 failed, 18 passed, 15 skipped, 2 deselected, 2 warnings in 1.42s ======

Complete build log with all details of packages used and steps taken.

Support ASA Multi-Context Mode

I'm creating this issue following @Enzzzy's suggestion on Slack. We will try to provide some POC code and discuss what is the best way to implement multi-context support for this driver.

SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED

Hi, I'm trying to use this driver with Netbox to retrieve some date from our Cisco ASA firewalls.
I've just tried on an ASA running ASA software version 9.15 and I get this error.
image
This is what I've got from the ASA logs:
image

Can you help me?

ASA - REST API compatibility with certain platforms

I believe that the NAPALM-ASA driver was setup to leverage the REST API. Recent versions of SourceFire software (>6.0) on ASA 5506-X platforms no longer supports the REST API.

Should it look to be moved to Netmiko for connectivity? And possibility of using the ASDM HTTP interface as referenced ktbyers/netmiko#841. This could also open up for use on older ASA platforms that never supported REST API as well.

Unable to open connection to ASAv

Hello,
Really appreciate the work you've put into this project.
But I can't seem to get past open(). I get the error below.. I'm trying to connect to an ASAv on VIRL.
Is there something I'm missing?
Thanks!

`driver_asa = napalm.get_network_driver('asa')
a = driver_asa('172.16.1.134', 'cisco', "cisco", optional_args={'secret': 'cisco', 'port': 22})
a.open()
Traceback (most recent call last):
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/urllib3/connectionpool.py", line 600, in urlopen
chunked=chunked)
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/urllib3/connectionpool.py", line 343, in _make_request
self._validate_conn(conn)
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/urllib3/connectionpool.py", line 849, in validate_conn
conn.connect()
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/urllib3/connection.py", line 356, in connect
ssl_context=context)
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/urllib3/util/ssl
.py", line 372, in ssl_wrap_socket
return context.wrap_socket(sock)
File "/usr/lib64/python3.6/ssl.py", line 407, in wrap_socket
_context=self, _session=session)
File "/usr/lib64/python3.6/ssl.py", line 814, in init
self.do_handshake()
File "/usr/lib64/python3.6/ssl.py", line 1068, in do_handshake
self._sslobj.do_handshake()
File "/usr/lib64/python3.6/ssl.py", line 689, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:841)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/requests/adapters.py", line 445, in send
timeout=timeout
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/urllib3/connectionpool.py", line 638, in urlopen
_stacktrace=sys.exc_info()[2])
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/urllib3/util/retry.py", line 398, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='172.16.1.134', port=22): Max retries exceeded with url: /api/tokenservices (Caused by SSLError(SSLError(1, '[SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:841)'),))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/napalm_asa/asa.py", line 65, in get_auth_token
data="", timeout=self.timeout, verify=False)
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/requests/sessions.py", line 559, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/requests/sessions.py", line 512, in request
resp = self.send(prep, **send_kwargs)
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/requests/sessions.py", line 622, in send
r = adapter.send(request, **kwargs)
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/requests/adapters.py", line 511, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='172.16.1.134', port=22): Max retries exceeded with url: /api/tokenservices (Caused by SSLError(SSLError(1, '[SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:841)'),))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "", line 1, in
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/napalm_asa/asa.py", line 185, in open
auth_result, code = self._authenticate()
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/napalm_asa/asa.py", line 131, in _authenticate
auth_result = self.device.get_auth_token()
File "/home/gladpark/NET_TOOLS_ENV/lib/python3.6/site-packages/napalm_asa/asa.py", line 73, in get_auth_token
raise ConnectionException(py23_compat.text_type(e))
napalm.base.exceptions.ConnectionException: HTTPSConnectionPool(host='172.16.1.134', port=22): Max retries exceeded with url: /api/tokenservices (Caused by SSLError(SSLError(1, '[SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:841)'),))`

ownership for asa driver

Hello,
community drivers are going to be maintained by the community or considered deprecated and unmaintained. For that reason we are looking for people willing to maintain this repo. Owners will have full admin rights on this repo and on its pypy package.

Pinging top contributors to see if they are interested; @DiogoAndre @ogenstad

If you have questions/comments let me know.

Regards

With napalm 2.5.0 the tests are failing

[   10s] =================================== FAILURES ===================================
[   10s] ______________________ TestGetter.test_method_signatures _______________________
[   10s]
[   10s] self = <test_getters.TestGetter object at 0x7f5631babeb0>
[   10s]
[   10s]     def test_method_signatures(self):
[   10s]         """Test that all methods have the same signature."""
[   10s]         errors = {}
[   10s]         cls = self.driver
[   10s]         # Create fictional driver instance (py3 needs bound methods)
[   10s]         tmp_obj = cls(hostname="test", username="admin", password="pwd")
[   10s]         attrs = [m for m, v in inspect.getmembers(tmp_obj)]
[   10s]         for attr in attrs:
[   10s]             func = getattr(tmp_obj, attr)
[   10s]             if attr.startswith("_") or not inspect.ismethod(func):
[   10s]                 continue
[   10s]             try:
[   10s]                 orig = getattr(NetworkDriver, attr)
[   10s]                 orig_spec = argspec(orig)
[   10s]             except AttributeError:
[   10s]                 orig_spec = "Method does not exist in napalm.base"
[   10s]             func_spec = argspec(func)
[   10s]             if orig_spec != func_spec:
[   10s]                 errors[attr] = (orig_spec, func_spec)
[   10s]
[   10s]         EXTRA_METHODS = ["__init__"]
[   10s]         for method in EXTRA_METHODS:
[   10s]             orig_spec = argspec(getattr(NetworkDriver, method))
[   10s]             func_spec = argspec(getattr(cls, method))
[   10s]             if orig_spec != func_spec:
[   10s]                 errors[attr] = (orig_spec, func_spec)
[   10s]
[   10s] >       assert not errors, "Some methods vary. \n{}".format(errors.keys())
[   10s] E       AssertionError: Some methods vary.
[   10s] E       dict_keys(['get_config'])
[   10s]
[   10s] /usr/lib/python3.8/site-packages/napalm/base/test/getters.py:151: AssertionError
[   10s] ____________________ TestGetter.test_get_interfaces[normal] ____________________
[   10s]
[   10s] self = <test_getters.TestGetter object at 0x7f5631b43250>, test_case = 'normal'
[   10s]
[   10s]     @wrap_test_cases
[   10s]     def test_get_interfaces(self, test_case):
[   10s]         """Test get_interfaces."""
[   10s]         get_interfaces = self.device.get_interfaces()
[   10s]         assert len(get_interfaces) > 0
[   10s]
[   10s] >           assert helpers.test_model(models.interface, interface_data)
[   10s]
[   10s] /usr/lib/python3.8/site-packages/napalm/base/test/getters.py:174:
[   10s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[   10s]
[   10s] model = {'description': <class 'str'>, 'is_enabled': <class 'bool'>, 'is_up': <class 'bool'>, 'last_flapped': <class 'float'>, ...}
[   10s] data = {'description': '', 'is_enabled': True, 'is_up': True, 'last_flapped': -1.0, ...}
[   10s]
[   10s]     def test_model(model, data):
[   10s]         """Return if the dictionary `data` complies with the `model`."""
[   10s]         same_keys = set(model.keys()) == set(data.keys())
[   10s]
[   10s]         if not same_keys:
[   10s]             print(
[   10s]                 "model_keys: {}\ndata_keys: {}".format(
[   10s]                     sorted(model.keys()), sorted(data.keys())
[   10s]                 )
[   10s]             )
[   10s]
[   10s]         correct_class = True
[   10s]         for key, instance_class in model.items():
[   10s]             if py23_compat.PY2 and isinstance(data[key], long):  # noqa
[   10s]                 # Properly handle PY2 long
[   10s]                 correct_class = (
[   10s]                     isinstance(data[key], long)  # noqa
[   10s]                     and isinstance(1, instance_class)
[   10s]                     and correct_class
[   10s]                 )
[   10s]             else:
[   10s] >               correct_class = isinstance(data[key], instance_class) and correct_class
[   10s] E               KeyError: 'mtu'
[   10s]
[   10s] /usr/lib/python3.8/site-packages/napalm/base/test/helpers.py:31: KeyError
[   10s] ----------------------------- Captured stdout call -----------------------------
[   10s] model_keys: ['description', 'is_enabled', 'is_up', 'last_flapped', 'mac_address', 'mtu', 'speed']
[   10s] data_keys: ['description', 'is_enabled', 'is_up', 'last_flapped', 'mac_address', 'speed']
[   10s] =============================== warnings summary ===============================
[   10s] napalm_asa/asa.py:66
[   10s]   /home/abuild/rpmbuild/BUILD/napalm-asa-0.1.1/napalm_asa/asa.py:66: SyntaxWarning: "is" with a literal. Did you mean "=="?
[   10s]     if token_request.status_code is 204 and 'X-Auth-Token' in token_request.headers.keys():
[   10s]
[   10s] napalm_asa/asa.py:82
[   10s]   /home/abuild/rpmbuild/BUILD/napalm-asa-0.1.1/napalm_asa/asa.py:82: SyntaxWarning: "is" with a literal. Did you mean "=="?
[   10s]     if token_delete_request.status_code is 204:

New Version for NAPALM 3 and Python 3.8

Hello together,

Is it possible that you release a new version of the NAPALM community driver for the Cisco ASA platform, for example 0.1.2?
So that it can be installed with pip and and requirements.txt file.

After some changes I was able to use the NAPALM-ASA driver with NAPALM 3 and Python 3.8.

What I did:

Install NAPALM ASA via Pip

pip install git+https://github.com/napalm-automation-community/napalm-asa.git@develop

Changed asa.py to use with Python 3

nano .../lib/python3.8/site-packages/napalm_asa/asa.py

Changes I found here: https://github.com/napalm-automation-community/napalm-asa/pull/31/commits/8942fd6f7ecdb5b8f71425bdb70d86fa6c895d55

Changed asa.py again to use it with Python 3.8

Python 3.8 raised the following errors: 

.../lib/python3.8/site-packages/napalm_asa/asa.py:58: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if token_request.status_code is 204 and 'X-Auth-Token' in token_request.headers.keys():

.../lib/python3.8/site-packages/napalm_asa/asa.py:74: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if token_delete_request.status_code is 204:

So I replaced "is" with "==".

After changing I was able to query the ASA Rest API:

# ipython
Python 3.8.6 (default, Sep 25 2020, 09:36:53)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.20.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from napalm import get_network_driver
   ...:
   ...: driver = get_network_driver("asa")

In [2]: device = driver(hostname='172.16.105.209', username='testuser', password='secret')

In [3]: device.open()
Out[3]: True

In [4]: facts = device.get_facts()
   ...: device.close()
Out[4]: True

In [5]: facts
Out[5]:
{'uptime': 183600,
 'vendor': 'Cisco Systems',
 'os_version': '9.12(4)10',
 'serial_number': 'ABCDEFGH',
 'model': 'ASA5512',
 'hostname': 'ciscoasa',
 'fqdn': 'ciscoasa',
 'interface_list': ['Management0/0',
  'GigabitEthernet0/0',
  'GigabitEthernet0/1',
  'GigabitEthernet0/2',
  'GigabitEthernet0/3',
  'GigabitEthernet0/4',
  'GigabitEthernet0/5']}

In [6]:

pylama rightly complaints against two expressions in asa.py

To avoid those this patch needs to be applied:

---
 napalm_asa/asa.py |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/napalm_asa/asa.py
+++ b/napalm_asa/asa.py
@@ -62,7 +62,7 @@ class RespFetcherHttps:
         try:
             token_request = self.session.post(full_url, auth=(self.username, self.password),
                                               data="", timeout=self.timeout, verify=False)
-            if token_request.status_code is 204 and 'X-Auth-Token' in token_request.headers.keys():
+            if token_request.status_code == 204 and 'X-Auth-Token' in token_request.headers.keys():
                 self.token = token_request.headers['X-Auth-Token']
                 self.session.headers.update({'X-Auth-Token': token_request.headers['X-Auth-Token']})
                 return (True, None)
@@ -78,7 +78,7 @@ class RespFetcherHttps:
             token_delete_request = self.session.delete(full_url,
                                                        auth=(self.username, self.password),
                                                        timeout=self.timeout, verify=False)
-            if token_delete_request.status_code is 204:
+            if token_delete_request.status_code == 204:
                 self.session.headers.pop('X-Auth-Token', None)
                 return (True, None)
             else:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.