Core condoor components

Init file for condoor.

Connection class

class Connection(name, urls=[], log_dir=None, log_level=10, log_session=True)[source]

Connection class providing the condoor API.

Main API class providing the basic API to the physical devices. It implements the following methods:

  • connect
  • reconnect
  • disconnect
  • send
  • reload
  • enable
  • run_fsm
__init__(name, urls=[], log_dir=None, log_level=10, log_session=True)[source]

Initialize the condoor.Connection object.

Args:

name (str): The connection name.

urls (str or list): This argument may be a string or list of strings or list of list of strings.

When urls type is string it must be valid URL in the following format:

urls = "<protocol>://<user>:<password>@<host>:<port>/<enable_password>

Example:

urls = "telnet://cisco:cisco@192.168.1.1"

The <port> can be omitted and default port for protocol will be used. When urls type is list of strings it can provide multiple intermediate hosts (jumphosts) with their credentials before making the final connection the target device. Example:

urls = ["ssh://admin:secretpass@jumphost", "telnet://cisco:cisco@192.168.1.1"]

urls = ["ssh://admin:pass@jumphost1", "ssh://admin:pass@jumphost2",
        "telnet://cisco:cisco@192.168.1.1"]

The urls can be list of list of strings. In this case the multiple connection chains can be provided to the target device. This is used when device has two processor cards with console connected to both of them. Example:

urls = [["ssh://admin:pass@jumphost1", "telnet://cisco:cisco@termserv:2001"],
        ["ssh://admin:pass@jumphost1", "telnet://cisco:cisco@termserv:2002"]]
log_dir (str): The path to the directory when session.log and condoor.log is stored. If None
the condoor log and session log is redirected to stdout

log_level (int): The condoor logging level.

log_session (Bool): If True the terminal session is logged.

connect(logfile=None, force_discovery=False, tracefile=None)[source]

Connect to the device.

Args:
logfile (file): Optional file descriptor for session logging. The file must be open for write.
The session is logged only if log_session=True was passed to the constructor. If None then the default session.log file is created in log_dir.

force_discovery (Bool): Optional. If True the device discover process will start after getting connected.

Raises:
ConnectionError: If the discovery method was not called first or there was a problem with getting
the connection.

ConnectionAuthenticationError: If the authentication failed.

ConnectionTimeoutError: If the connection timeout happened.

reconnect(logfile=None, max_timeout=360, force_discovery=False, tracefile=None, retry=True)[source]

Reconnect to the device.

It can be called when after device reloads or the session was disconnected either by device or jumphost. If multiple jumphosts are used then reconnect starts from the last valid connection.

Args:
logfile (file): Optional file descriptor for session logging. The file must be open for write.
The session is logged only if log_session=True was passed to the constructor. It the parameter is None the default session.log file is created in log_dir.
max_timeout (int): This is the maximum amount of time during the session tries to reconnect. It may take
longer depending on the TELNET or SSH default timeout.

force_discovery (Bool): Optional. If True the device discover process will start after getting connected.

tracefile (file): Optional file descriptor for condoor logging. The file must be open for write.
It the parameter is None the default condoor.log file is created in log_dir.

retry (bool): Optional parameter causing the connnection to retry until timeout

Raises:
ConnectionError: If the discovery method was not called first or there was a problem with getting
the connection.

ConnectionAuthenticationError: If the authentication failed.

ConnectionTimeoutError: If the connection timeout happened.

disconnect()[source]

Disconnect the session from the device and all the jumphosts in the path.

reload(reload_timeout=300, save_config=True, no_reload_cmd=False)[source]

Reload the device and wait for device to boot up.

Returns False if reload was not successful.

send(cmd='', timeout=300, wait_for_string=None, password=False)[source]

Send the command to the device and return the output.

Args:

cmd (str): Command string for execution. Defaults to empty string. timeout (int): Timeout in seconds. Defaults to 300 sec (5 min) wait_for_string (str): This is optional string that driver waits for after command execution. If none the detected prompt will be used. password (bool): If true cmd representing password is not logged

and condoor waits for noecho.
Returns:
A string containing the command output.
Raises:
ConnectionError: General connection error during command execution CommandSyntaxError: Command syntax error or unknown command. CommandTimeoutError: Timeout during command execution
enable(enable_password=None)[source]

Change the device mode to privileged.

If device does not support privileged mode the the informational message to the log will be posted.

Args:
enable_password (str): The privileged mode password. This is optional parameter. If password is not
provided but required the password from url will be used. Refer to condoor.Connection
run_fsm(name, command, events, transitions, timeout, max_transitions=20)[source]

Instantiate and run the Finite State Machine for the current device connection.

Here is the example of usage:

test_dir = "rw_test"
dir = "disk0:" + test_dir
REMOVE_DIR = re.compile(re.escape("Remove directory filename [{}]?".format(test_dir)))
DELETE_CONFIRM = re.compile(re.escape("Delete {}/{}[confirm]".format(filesystem, test_dir)))
REMOVE_ERROR = re.compile(re.escape("%Error Removing dir {} (Directory doesnot exist)".format(test_dir)))

command = "rmdir {}".format(dir)
events = [device.prompt, REMOVE_DIR, DELETE_CONFIRM, REMOVE_ERROR, pexpect.TIMEOUT]
transitions = [
    (REMOVE_DIR, [0], 1, send_newline, 5),
    (DELETE_CONFIRM, [1], 2, send_newline, 5),
    # if dir does not exist initially it's ok
    (REMOVE_ERROR, [0], 2, None, 0),
    (device.prompt, [2], -1, None, 0),
    (pexpect.TIMEOUT, [0, 1, 2], -1, error, 0)

]
if not conn.run_fsm("DELETE_DIR", command, events, transitions, timeout=5):
    return False

This FSM tries to remove directory from disk0:

Args:
name (str): Name of the state machine used for logging purposes. Can’t be None command (str): The command sent to the device before FSM starts events (list): List of expected strings or pexpect.TIMEOUT exception expected from the device. transitions (list): List of tuples in defining the state machine transitions. timeout (int): Default timeout between states in seconds. max_transitions (int): Default maximum number of transitions allowed for FSM.

The transition tuple format is as follows:

(event, [list_of_states], next_state, action, timeout)

Where:

  • event (str): string from the events list which is expected to be received from device.
  • list_of_states (list): List of FSM states that triggers the action in case of event occurrence.
  • next_state (int): Next state for FSM transition.
  • action (func): function to be executed if the current FSM state belongs to list_of_states and the event occurred. The action can be also None then FSM transits to the next state without any action. Action can be also the exception, which is raised and FSM stops.

The example action:

def send_newline(ctx):
    ctx.ctrl.sendline()
    return True

def error(ctx):
    ctx.message = "Filesystem error"
    return False

def readonly(ctx):
    ctx.message = "Filesystem is readonly"
    return False

The ctx object description refer to condoor.fsm.FSM.

If the action returns True then the FSM continues processing. If the action returns False then FSM stops and the error message passed back to the ctx object is posted to the log.

The FSM state is the integer number. The FSM starts with initial state=0 and finishes if the next_state is set to -1.

If action returns False then FSM returns False. FSM returns True if reaches the -1 state.

discovery(logfile=None, tracefile=None)[source]

Discover the device details.

This method discover several device attributes.

Args:
logfile (file): Optional file descriptor for session logging. The file must be open for write.
The session is logged only if log_session=True was passed to the constructor. It the parameter is not passed then the default session.log file is created in log_dir.
family

Return the string representing hardware platform family.

For example: ASR9K, ASR900, NCS6K, etc.

platform

Return the string representing hardware platform model.

For example: ASR-9010, ASR922, NCS-4006, etc.

os_type

Return the string representing the target device OS type.

For example: IOS, XR, eXR. If not detected returns None

os_version

Return the string representing the target device OS version.

For example 5.3.1. If not detected returns None

hostname

Return target device hostname.

prompt

Return target device prompt.

is_connected

Return if target device is connected.

is_discovered

Return if target device is discovered.

is_console

Return if target device is connected via console.

mode

Return the sting representing the current device mode.

For example: Calvados, Windriver, Rommon.

name

Return the chassis name.

description

Return the chassis description.

pid

Return the chassis PID.

vid

Return the chassis VID.

sn

Return the chassis SN.

udi

Return the dict representing the udi hardware record.

Example:

{
'description': 'ASR-9904 AC Chassis',
'name': 'Rack 0',
'pid': 'ASR-9904-AC',
'sn': 'FOX1830GT5W ',
'vid': 'V01'
}
device_info

Return the dict representing the target device info record.

Example:

{
'family': 'ASR9K',
'os_type': 'eXR',
'os_version': '6.1.0.06I',
'platform': 'ASR-9904'
}
description_record

Return dict describing condoor.Connection object.

Example:

{'connections': [{'chain': [{'driver_name': 'eXR',
                 'family': 'ASR9K',
                 'hostname': 'vkg3',
                 'is_console': True,
                 'is_target': True,
                 'mode': 'global',
                 'os_type': 'eXR',
                 'os_version': '6.1.2.06I',
                 'platform': 'ASR-9904',
                 'prompt': 'RP/0/RSP0/CPU0:vkg3#',
                 'udi': {'description': 'ASR-9904 AC Chassis',
                         'name': 'Rack 0',
                         'pid': 'ASR-9904-AC',
                         'sn': 'FOX2024GKDE ',
                         'vid': 'V01'}}]},
     {'chain': [{'driver_name': 'generic',
                 'family': None,
                 'hostname': '172.27.41.52:2045',
                 'is_console': None,
                 'is_target': True,
                 'mode': None,
                 'os_type': None,
                 'os_version': None,
                 'platform': None,
                 'prompt': None,
                 'udi': None}]}],
'last_chain': 0}