2121# std libs
2222import re
2323import time
24+ import importlib
2425import inspect
2526import json
2627import socket
3435
3536# third party libs
3637import pyeapi
37- from pyeapi .eapilib import ConnectionError
38+ from pyeapi .eapilib import ConnectionError , EapiConnection
3839from 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