Skip to content

thecloudhermit/sisqo

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sisqo – Cisco SSH automation library

Overview

Sisqo is a library for automating the management of Cisco devices via SSH.

Features

  • Runs on any UNIX-style platform that has vty support, with no dependencies on OpenSSH or SSH agents
  • OpenSSH-style ProxyCommand support, allowing the library to traverse jumpboxes
  • Supports SSH pubkey authentication with no dependency on the user's .ssh profile, complimenting the ProxyCommand feature by attempting both password-based and pubkey-based authentication at each hop
  • Complete support for VT100 series terminal emulation, guaranteeing that what you see on the command line will also be what you receive from this library
  • Automatically handles Cisco-style "more" pagination and prompt matching, allowing for seamless read()/write() semantics regardless of the target device's terminal settings
  • Provides special API support for enable authorization
  • Provides a fluid API for parsing running-config and startup-config into strongly typed hierarchical objects that can be traversed with regex-based searching
  • Tested against Cisco IOS, Catalyst, Nexus, ASA/PIX, and ASR series devices

Usage

To use the Sisqo library, you must have a recent version of the pip Python package manager. First, git clone this repository into a local directory. Open a shell at the repository path, and pip install -r requirements.txt to install Sisqo's runtime dependencies.

At this point, you may copy the Sisqo repository folder into your Python project and import Sisqo to begin using the library.

API Documentation

Example code:

from sys import exit

import sisqo

router = sisqo.SSH( host='router.example.com',
                    proxyCommand='ssh -W %h:%p jdoe@jumpbox.example.com' )

with router:

    if not router.authenticate(
        username='cisco',
        password='cisco',
        privateKeyFile='~/.ssh/id_rsa',
        privateKeyPassword='password123' ):
        
        exit( 1 )  # could not authenticate with the router

    if not router.enable( password='cisco' ):
    
        exit( 2 )  # could not enable on the router

    router.write( 'show version' )
    versionInformation = router.read()

    print( 'Router version:' )
    print( versionInformation )  # Cisco IOS Software, C2900 Software (C2900-UNIVERSALK9-M) ...

    runningConfig = router.showRunningConfig()

    bgpConfig = runningConfig.findChild( 'router bgp \d+' )

    bgpNeighbors = bgpConfig.findChildren( 'neighbor .+' )

    print( 'BGP neighbors of ASN %s:' %(bgpConfig.value.split()[2]) )  # BGP neighbors of ASN 12345:
    
    for neighbor in bgpNeighbors:
    
        ipAddress = neighbor.value.split()[1]
        print( ipAddress )  # 11.22.33.44

    router.write( 'write memory' )
    wrMemResult = router.read()
    
    if '[ok]' not in wrMemResult.lower():
    
        exit( 3 )  # could not save the running-config to the router

exit( 0 )

class SSH

Note: this class must be used as a context manager (using a "with" statement)

  • constructor ( host: str, port: int?, proxyCommand: str? )

    Creates an object that can be used to SSH into the provided host/port and issue commands. To proxy through a jumpbox, provide an OpenSSH-style proxyCommand.

  • readonly property host: str – hostname or IP address to SSH into

  • readonly property port: int – port number to SSH into

  • readonly property proxyCommand: str | None – SSH command used to connect to the jumpbox

  • method authenticate ( username: str, password: str?, privateKeyFile: str?, privateKeyPassword: str? ): bool

    Initiates an SSH connection to the target device, trying the specified private key and proxying through intermediate jumpboxes if necessary.

  • method read ( timeout: int?, promptRegex: str?, moreRegex: str?, stripPrompt: bool? ): str

    Reads from the target device up to the next prompt, with special handling for Cisco-style pagination. If a prompt cannot be matched in the output, the read operation returns after timeout seconds. The stripPrompt argument can be used to control whether or not the text of the prompt is returned as part of the read operation.

  • method write ( command: str , consumeEcho: bool? )

    Writes command to the target device. By default, this function expects the device to echo back command. If consumeEcho is True (the default), this function will implicitly consume the data that is echoed back. When responding to password prompts, you should set consumeEcho to False to avoid unintentionally consuming data.

    Warning: this function implicitly reads any previously unread data without returning it to the consumer.

  • method enable ( password: str ): bool

    Helper function to elevate privileges on a target device, with special handling for the "Password" prompt.

    Warning: enable is not supported on certain Cisco operating systems

  • method showRunningConfig ( ): Configuration

    Helper function to retrieve the target device's running-config and parse it into a Configuration object.

  • method showStartupConfig ( ): Configuration

    Helper function to retrieve the target device's startup-config and parse it into a Configuration object.

    Warning: startup-config is not supported on certain Cisco operating systems

class Configuration

Note: instances of this class are returned from SSH.showRunningConfig() and SSH.showStartupConfig()

  • constructor ( configString: str )

    Parses a Cisco configuration file configString into a hierarchical, searchable representation of configuration lines.

  • method findChild ( regex: str ): Line

    Searches the root node of the hierarchy for the first line that matches the provided regex.

  • method findChildren ( regex: str ): list[Line]

    Searches the root node of the hierarchy for lines that match the provided regex.

class Line

Note: instances of this class are returned from Configuration.findChild() and Configuration.findChildren()

  • constructor ( number: int, indent: str, value: str )

    Creates a strong representation of a single line of a Cisco configuration file

  • property parent: Line – hierarchical parent of this configuration line

  • property children: list[Line] – list of hierarchical children of this configuration line

  • readonly property value: str – text of the configuration line, stripped of indentation

  • readonly property lineNumber: int – line number from the original configuration text

  • readonly property indentation: int – indentation level of the configuration line

  • readonly property depth: int – depth of this line in the configuration hierarchy

  • method findChild ( regex: str ): Line

    Searches the children of this node for the first line that matches the provided regex and returns that line.

  • method findChildren ( regex: str ): list[Line]

    Searches the children of this node for lines that match the provided regex and returns a list of matching lines.

About

More friendly access to Cisco-style CLIs from Python

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Python 100.0%