Skip to content

Commit dde6a59

Browse files
authored
Merge pull request #1643 from napalm-automation/eos_arbitrary_transport
eos: support arbitrary transport class
2 parents 8e38055 + 5b6d7aa commit dde6a59

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

napalm/eos/eos.py

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
# std libs
2222
import re
2323
import time
24+
import importlib
2425
import inspect
2526
import json
2627
import socket
@@ -34,7 +35,7 @@
3435

3536
# third party libs
3637
import pyeapi
37-
from pyeapi.eapilib import ConnectionError
38+
from pyeapi.eapilib import ConnectionError, EapiConnection
3839
from netmiko import ConfigInvalidException
3940

4041
# NAPALM base
@@ -105,7 +106,10 @@ def __init__(self, hostname, username, password, timeout=60, optional_args=None)
105106
- http
106107
- https
107108
- https_certs
109+
- A subclass of EapiConnection
110+
- a string that identifies a module and class that is a subclass of EapiConnection
108111
(from: https://github.com/arista-eosplus/pyeapi/blob/develop/pyeapi/client.py#L115)
112+
109113
transport is the preferred method
110114
* eos_transport (string): pyeapi transport, defaults to https
111115
eos_transport for backwards compatibility
@@ -141,15 +145,11 @@ def _process_optional_args(self, optional_args):
141145
self.transport_class = "ssh"
142146
init_args = ["port"]
143147
else:
144-
try:
145-
self.transport_class = pyeapi.client.TRANSPORTS[transport]
146-
# ([1:]) to omit self
147-
init_args = inspect.getfullargspec(self.transport_class.__init__)[0][1:]
148+
# Parse pyeapi transport class
149+
self.transport_class = self._parse_transport(transport)
150+
# ([1:]) to omit self
151+
init_args = inspect.getfullargspec(self.transport_class.__init__)[0][1:]
148152

149-
except KeyError:
150-
raise ConnectionException(
151-
"Unknown transport: {}".format(self.transport)
152-
)
153153
filter_args = ["host", "username", "password", "timeout", "lock_disable"]
154154

155155
if transport == "ssh":
@@ -166,6 +166,31 @@ def _process_optional_args(self, optional_args):
166166
if k in init_args and k not in filter_args
167167
}
168168

169+
def _parse_transport(self, transport):
170+
if inspect.isclass(transport) and issubclass(transport, EapiConnection):
171+
# Subclass of EapiConnection
172+
return transport
173+
elif "." in transport:
174+
# Try to resolve string import to module and getattr to class
175+
try:
176+
comps = transport.split(".")
177+
module = importlib.import_module(comps[0])
178+
for comp in comps[1:]:
179+
module = getattr(module, comp)
180+
if issubclass(module, EapiConnection):
181+
return module
182+
except ImportError:
183+
# String doesn't start with a module, fallthrough to pyeapi defined strings
184+
pass
185+
except AttributeError:
186+
# Error walking from module to class, fallthrough to pyeapi defined strings
187+
pass
188+
try:
189+
return pyeapi.client.TRANSPORTS[transport]
190+
except KeyError:
191+
# All methods failed, raise exception
192+
raise ConnectionException("Unknown transport: {}".format(transport))
193+
169194
def open(self):
170195
"""Implementation of NAPALM method open."""
171196
if self.transport == "ssh":

0 commit comments

Comments
 (0)