def connectToDevice(deviceconfig): """ Parse device config data & open SSH connection """ print("Loading device configuration...") device = {} device["host"] = deviceconfig["address"] device["auth_username"] = deviceconfig["username"] device["auth_password"] = deviceconfig["password"] device["auth_strict_key"] = False device["timeout_socket"] = 10 device["timeout_ops"] = 10 try: device["port"] = deviceconfig["port"] except KeyError: pass if deviceconfig["type"] == "ios-xe": conn = IOSXEDriver(**device) elif deviceconfig["type"] == "nx-os": conn = NXOSDriver(**device) try: print(f"Attempting connection to {device['host']}") conn.open() print(f"Successfully connected to {device['host']}") except Exception as e: print(f"Failed connection to {device['host']}") print("Error message is: %s" % e) return None return conn
def test_pre_escalate(): with pytest.warns(UserWarning) as warn: conn = IOSXEDriver(host="localhost", comms_prompt_pattern="something", auth_secondary="") conn._pre_escalate(escalate_priv=conn.privilege_levels["privilege_exec"]) assert ( str(warn[1].message) == "\n***** Privilege escalation generally requires an `auth_secondary` password, but none is set! \nscrapli will try to escalate privilege without entering a password but may fail.\nSet an `auth_secondary` password if your device requires a password to increase privilege, otherwise ignore this message.\n***** Privilege escalation generally requires an `auth_secondary` password, but none is set! " )
def main(): """Simple example demonstrating adding transport options""" conn = IOSXEDriver(**MY_DEVICE) # with the transport options provided, we can extend the open command to include extra args print(conn.transport.open_cmd) # deleting the transport options we can see what the default open command would look like MY_DEVICE.pop("transport_options") del conn conn = IOSXEDriver(**MY_DEVICE) print(conn.transport.open_cmd)
def main(): """Simple example of connecting to an IOSXEDevice with the IOSXEDriver""" with IOSXEDriver(**MY_DEVICE) as conn: # Platform drivers will auto-magically handle disabling paging for you result = conn.send_command("show run") print(result.result)
def send_show(device, show_command): try: with IOSXEDriver(**device) as ssh: reply = ssh.send_command(show_command) return reply.result except ScrapliException as error: print(error, device["host"])
def send_cfg(device, cfg_commands): try: with IOSXEDriver(**device) as ssh: reply = ssh.send_configs(cfg_commands) return reply.result except ScrapliException as error: print(error, device["host"])
def main(): """Simple example demonstrating getting structured data via textfsm/ntc-templates""" with IOSXEDriver(**MY_DEVICE) as conn: # Platform drivers will auto-magically handle disabling paging for you result = conn.send_command("show run") print(result.result) print(result.genie_parse_output())
def test_non_sync_transport(): device = DEVICES["mock_cisco_iosxe"].copy() with pytest.raises(TransportPluginError) as exc: IOSXEDriver(transport="asyncssh", **device) assert ( str(exc.value) == "Attempting to use transport type asyncssh with a sync driver, must use a non-asyncio transport" )
def main(): """Simple example of configuring banners and macros on an IOSXEDevice""" conn = IOSXEDriver(**MY_DEVICE) conn.open() my_banner = """banner motd ^ This is my router, get outa here! I'm serious, you can't be in here! Go away! ^ """ # Because the banner "input mode" is basically like a text editor where we dont get the prompt # printed out between sending lines of banner config we need to use the `eager` mode to force # scrapli to blindly send the banner/macro lines without looking for the prompt in between each # line. You should *not* use eager unless you need to and know what you are doing as it # basically disables one of the core features that makes scrapli reliable! result = conn.send_config(config=my_banner, eager=True) print(result.result)
def main(): """ Example demonstrating handling authentication with ssh private key Make sure the key permissions are 0600! """ with IOSXEDriver(**MY_DEVICE) as conn: # Platform drivers will auto-magically handle disabling paging for you result = conn.send_command("show run") print(result.result)
def connect_cli(self, **kwargs): def to_telnet(cli, **kwargs): try: cli.close() except Exception: pass cli = False if self.device["port"] != 23: self.debug("Swiching to telnet") self.device["port"] = 23 self.device["transport"] = "telnet" cli = self.connect_cli(**kwargs) return cli cli = IOSXEDriver(**self.device, **kwargs) try: self.debug(f'Trying to connect via TCP/{self.device["port"]} ...') cli.open() except ScrapliAuthenticationFailed: self.debug( f'Incorrect username while connecting to the device via TCP/{self.device["port"]}' ) cli = to_telnet(cli, **kwargs) except ScrapliConnectionError: self.debug( f'Device closed connection on TCP/{self.device["port"]}') # raise cli = to_telnet(cli, **kwargs) except Exception: self.debug( f'Unknown error while connecting to the device via TCP/{self.device["port"]}' ) cli = to_telnet(cli, **kwargs) else: self.debug( f'Login successful while connecting to the device via TCP/{self.device["port"]}' ) return cli
def test_check_kwargs_comms_prompt_pattern(): with pytest.warns(UserWarning) as warn: conn = IOSXEDriver(host="localhost", comms_prompt_pattern="something") assert ( conn.comms_prompt_pattern == r"(^[a-z0-9.\-_@()/:]{1,63}>$)|(^[a-z0-9.\-_@/:]{1,63}#$)|(^[a-z0-9.\-_@/:]{1,63}\([a-z0-9.\-@/:\+]{" "0,32}\\)#$)") assert ( str(warn[0].message) == "\n***** `comms_prompt_pattern` found in kwargs! " "*****************************************\n`comms_prompt_pattern` is ignored (dropped) when using network " "drivers. If you wish to modify the patterns for any network driver sub-classes, please do so by modifying " "or providing your own `privilege_levels`.\n***** `comms_prompt_pattern` found in kwargs! " "*****************************************")
def main(): """Simple example of configuring banners and macros on an IOSXEDevice""" conn = IOSXEDriver(**MY_DEVICE) conn.open() my_banner = """This is my router, get outa here! I'm serious, you can't be in here! Go away! """ # the overall pattern/process is that we must use send_interactive as this is an "interactive" # style command/input because the prompt changes and relies on a human to understand what is # going on. this whole operation is completed by the `send_interactive` method, but we break it # up here so its easier to understand what is going on. first we have a "start" point -- where # we send the actual command that kicks things off -- in this case "banner motd ^" -- we need to # tell scrapli what to expect so it knows there is success; "Enter TEXT message." in this # exmaple. We set the "hidden input" to `True` because this forces scrapli to not try to read # the inputs back off the channel -- we can't read the inputs because they are interrupted by # the prompt of enter your text blah blah. banner_start = ("banner motd ^", "Enter TEXT message.", True) # next we can simply create an "event" for each line of the banner we want to send, we dont # need to set the "hidden_prompt" value to `True` here because scrapli can simply read the # inputs off the channel normally as there is no prompts/inputs from the device banner_lines = [(line, "\n") for line in my_banner.splitlines()] # then we need to "end" our interactive event and ensure scrapli knows how to find the prompt # that we'll be left at at the end of this operation. note that you could just capture the # config mode prompt via `get_prompt` if you wanted and pass that value here, but we'll set it # manually for this example banner_end = ("^", "csr1000v(config)#", True) # finally we need to add all these sections up into a single list of tuples so that we can pass # this to the `send_interactive` method -- note the `*` in front of the `banner_lines` argument # we "unpack" the tuples from the list into this final list object banner_events = [banner_start, *banner_lines, banner_end] result = conn.send_interactive(interact_events=banner_events, privilege_level="configuration") print(result.result) # Note: csr1000v (at least the version scrapli is regularly tested with does not support macros # the following has been tested and works on a 3560 switch my_macro = """# description desc this_is_a_neat_macro # do a thing power inline never """ macro_start = ("macro name my_macro", "Enter macro commands one per line.", True) macro_lines = [(line, "\n", True) for line in my_macro.splitlines()] macro_end = ("@", "csr1000v(config)#", True) macro_events = [macro_start, *macro_lines, macro_end] result = conn.send_interactive(interact_events=macro_events, privilege_level="configuration") print(result.result)
from scrapli.driver.core import IOSXEDriver # setting `ssh_config_file` to True makes scrapli check in ~/.ssh/ and /etc/ssh/ for a file # named "config", you can also just pass a path to a file of your choosing args = { "host": "172.18.0.11", "auth_strict_key": False, "ssh_config_file": True } with IOSXEDriver(**args) as conn: # Platform drivers will auto-magically handle disabling paging for you result = conn.send_command("show run") print(result.result)
f"{Path(__file__).resolve().parents[0]}/ssh_config_file_and_key_auth.log", level=logging.DEBUG, ) logger = logging.getLogger("scrapli") args = { "host": device["host"], "port": device["port"], "ssh_config_file": True, "auth_strict_key": False, "keepalive_interval": device["keepalive_interval"], "transport": device["transport"], "keepalive": device["keepalive"], } conn = IOSXEDriver(**args) conn.open() print("***** Get Prompt:") print(conn.get_prompt()) print("***** Show run | i hostname:") result = conn.send_commands("show run | i hostname") print(result, result[0].result) print("***** Clear logging buffer:") interact = [("clear logg", "Clear logging buffer [confirm]"), ("", "3560CX#")] result = conn.send_interactive(interact) print(result, result[0].result) print("***** Disable Paging:")
def main(): """Example demonstrating basic logging with scrapli""" conn = IOSXEDriver(**MY_DEVICE) conn.open() print(conn.get_prompt()) print(conn.send_command("show run | i hostname").result)
show_default_route_raw = conn.send_command( "show run | include ip route 0.0.0.0 0.0.0.0") default_gateway = show_default_route_raw.result.strip( "ip route 0.0.0.0 0.0.0.0 ") else: show_default_gateway_raw = conn.send_command( "show run | include ip default-gateway") if "ip default-gateway" in show_default_gateway_raw.result: default_gateway = show_default_gateway_raw.result.strip( "ip default-gateway ") else: default_gateway = input("Please enter the layer 3 device") print(default_gateway) for device in device_list_raw.splitlines(): my_device = { "host": device, "auth_username": username, "auth_password": password, "auth_strict_key": False, "transport": "paramiko", } conn = IOSXEDriver(**my_device) conn.open() show_gateway() #except ScrapliAuthenticationFailed: # print("Authentication Failed")
from scrapli.driver.core import IOSXEDriver device = { "host": "ios-xe-mgmt-latest.cisco.com", "auth_username": "******", "auth_password": "******", "port": 8181, "auth_strict_key": False, } conn = IOSXEDriver(**device) conn.open() response = conn.send_command("show interface Gi3 description") print("*" * 100) print(response.result) conn.send_configs( ["interface GigabitEthernet3", "description Configured by Scrapli"]) response = conn.send_command("show interface Gi3 description") print("*" * 100) print(response.result)
from scrapli.driver.core import IOSXEDriver my_device = { "host": "172.18.0.11", "auth_username": "******", "auth_password": "******", "auth_strict_key": False, } conn = IOSXEDriver(**my_device) conn.open() response = conn.send_command("show run") print(response.result)
if __name__ == '__main__': devices = [{ 'host': 'ios-xe-mgmt-latest.cisco.com', 'auth_username': '******', 'auth_password': '******', 'auth_strict_key': False }, { 'host': 'ios-xe-mgmt.cisco.com', 'auth_username': '******', 'auth_password': '******', 'port': 8181, 'ssh_config_file': '~/.ssh/config', # "transport_options": {"open_cmd": ["-o", "KexAlgorithms=+diffie-hellman-group14-sha1"]}, 'auth_strict_key': False }, { 'host': 'sbx-iosxr-mgmt.cisco.com', 'auth_username': '******', 'auth_password': '******', 'port': 8181, 'auth_strict_key': False }] for i in devices: cmd = '' if 'xe' in i['host']: cmd = CiscoScrape(IOSXEDriver(**i), 'switch').write() elif 'xr' in i['host']: cmd = CiscoScrape(IOSXRDriver(**i), 'router').write() print(cmd)
import logging import time from pathlib import Path from device_info import iosxe_device from scrapli.driver.core import IOSXEDriver logging.basicConfig( filename=f"{Path(__file__).resolve().parents[0]}/iosxe_driver.log", level=logging.DEBUG ) logger = logging.getLogger("scrapli") conn = IOSXEDriver(**iosxe_device) conn.open() print("***** Get Prompt:") prompt = conn.get_prompt() print(prompt) print("***** Show run | i hostname:") result = conn.send_command("show run | i hostname") print(result, result.result) print("***** Clear logging buffer:") interact = [("clear logg", "Clear logging buffer [confirm]"), ("", prompt)] result = conn.send_interactive(interact) print(result, result.result) print("***** Show run:") result = conn.send_command("show run")
def gather_info(device, path): data = dict() conn = IOSXEDriver(**device) conn.open() # выполняем необходимые команды show_version = conn.send_command("show version") config = conn.send_command("show running-config") show_cdp = conn.send_command("show cdp neighbors") conn.send_configs(NTP_COMMANDS) show_ntp = conn.send_command("show ntp status") conn.close() # записываем инфу для вывода data["hostname"] = re.search(r"\s*(\S+)\s+uptime\s+is", show_version.result).group(1) data["model"] = re.search(r"[Cc]isco\s+(\S+)\s+\(", show_version.result).group(1) data["software"] = re.search(r".*Software\s+\((?P<package>\S+)\),\s+Version\s+(?P<version>\S+),\s+", show_version.result).groupdict() # выяснем NPE или PE if re.search(r"NPE", data["software"]["package"]): data["payload"] = "NPE" else: data["payload"] = "PE" # делаем бэкап backup_path = os.path.join(path, 'backups') now = datetime.datetime.now() if not os.path.exists(backup_path): os.mkdir(backup_path) with open(f"{backup_path}/{data['hostname']}-{now.strftime('%Y_%m_%d-%H_%M_%S')}.conf", "w") as input: input.write(config.result) # проверяем cdp if re.search(r"cdp\s+is\s+not\s+enabled", show_cdp.result, re.IGNORECASE): data["cdp_status"] = "CDP is OFF" data["cdp_peers"] = "0 peers" else: data["cdp_status"] = "CDP is ON" peers = re.search(r"total\s+cdp\s+entries\s+displayed\s*:\s*(\d+)", show_cdp.result, re.IGNORECASE) data["cdp_peers"] = f"{peers.group(1)} peers" # проверяем ntp if re.search(r"clock\s+is\s+unsynch", show_ntp.result, re.IGNORECASE): data["ntp_status"] = "Clock not Sync" elif re.search(r"clock\s+is\s+synch", show_ntp.result, re.IGNORECASE): data["ntp_status"] = "Clock in Sync" elif re.search(r"ntp\s+is\s+not\s+enabled", show_ntp.result, re.IGNORECASE): data["ntp_status"] = "Clock not Sync" print(f"{data['hostname']}|{data['model']}|{data['software']['package']} {data['software']['version']}|{data['payload']}|{data['cdp_status']}, {data['cdp_peers']}|{data['ntp_status']}")
from scrapli.driver.core import IOSXEDriver device = { "host": "ios-xe-mgmt-latest.cisco.com", "auth_username": "******", "auth_password": "******", "port": 8181, "auth_strict_key": False, } conn = IOSXEDriver(**device) conn.open() responses = conn.send_commands(["show version", "show ip int brief"]) for response in responses: print("RESPONSE") print("*" * 100) print(response.result) conn.close()
def main(): """Example demonstrating handling authentication/connection settings via ssh config file""" with IOSXEDriver(**MY_DEVICE) as conn: result = conn.send_command("show run") print(result.result)
from scrapli.driver.core import IOSXEDriver switch = { "host": "172.16.100.168", "auth_username": "******", "auth_password": "******", "auth_strict_key": False } cli = IOSXEDriver(**switch) cli.open() sh_int = cli.send_command("show ip ospf int brief") print(sh_int.result)
import logging from scrapli.driver.core import IOSXEDriver logging.basicConfig(filename="scrapli.log", level=logging.DEBUG) logger = logging.getLogger("scrapli") args = { "host": "172.18.0.11", "auth_username": "******", "auth_password": "******", "auth_strict_key": False, } conn = IOSXEDriver(**args) conn.open() print(conn.get_prompt()) print(conn.send_command("show run | i hostname").result)
devices = [{ "host": "ios-xe-mgmt-latest.cisco.com", "auth_username": "******", "auth_password": "******", "auth_strict_key": False }, { "host": "sbx-iosxr-mgmt.cisco.com", "auth_username": "******", "auth_password": "******", "port": 8181, "auth_strict_key": False }] os.system("clear") conn_XE = IOSXEDriver(**devices[0]) conn_XE.open() response = conn_XE.send_command("show ip int brief") print("RESPONSE") print("*" * 100) print(response.result) conn_XE.close() conn_XR = IOSXRDriver(**devices[1]) conn_XR.open() response = conn_XR.send_command("show ip int brief") print("RESPONSE") print("*" * 100) # print(response.result) # print(re.findall("Giga.+", response.result))
from scrapli.driver.core import IOSXEDriver import re import os os.system("clear") device = { "host": "ios-xe-mgmt-latest.cisco.com", "auth_username": "******", "auth_password": "******", "auth_strict_key": False } conn = IOSXEDriver(**device) conn.open() responses = conn.send_command("show version") # print(responses.result) # print(re.findall("Compiled.+", responses.result)) # responses = conn.send_commands(["show version", "show ip int brief"]) # for response in responses: # print(response.result) # conn.close() shver_parsed = responses.genie_parse_output() # print(shver_parsed) hostname = shver_parsed['version']['hostname'] platform = shver_parsed['version']['platform']
from scrapli.driver.core import IOSXEDriver switch = { "host": "192.168.65.137", "auth_username": "******", "auth_password": "******", "auth_strict_key": False } cli = IOSXEDriver(**switch) cli.open() sh_int = cli.send_command("show interface") print(sh_int.output)
# note that because cls is typed `GenericDriver` mypy/IDE will not like this, but it does work # because yay python :) (assuming the driver you use is a NetworkDriver of course) cls.acquire_priv("configuration") cls.channel.send_return() def callback_two(cls: GenericDriver, read_output: str): """Callback that enters runs a silly command""" print(f"previous read output : {read_output}") r = cls.send_command("do show run | i hostname") print(f"result: {r.result}") if __name__ == "__main__": with IOSXEDriver(**device) as conn: callbacks = [ ReadCallback( contains="rtr1#", callback=callback_one, name="enter config mode callback", case_insensitive=False, ), ReadCallback( contains_re=r"^rtr1\(config\)#", callback=callback_two, complete=True, ), ] conn.read_callback(callbacks=callbacks, initial_input="show run | i hostname")