Open a Jaide session with the device.

    To open a Jaide session to the device, and run the appropriate function
    against the device. Arguments for the downstream function are passed
    through.

    @param ip: String of the IP or hostname of the device to connect to.
    @type ip: str
    @param username: The string username used to connect to the device.
    @type useranme: str
    @param password: The string password used to connect to the device.
    @type password: str
    @param function: The downstream jaide.wrap function we'll be handing
                   | off the jaide.Jaide() object to execute the command
                   | once we've established the connection.
    @type function: function pointer.
    @param args: The arguments that we will hand off to the downstream
               | function.
    @type args: list
    @param write: If set, it would be a tuple that we pass back as part of
                | our return statement, so that any callback function
                | can know how and where to put the output from the device.
    @type write: False or tuple.
    @param conn_timeout: Sets the connection timeout value. This is how
                       | we'll wait when connecting before classifying
                       | the device unreachable.
    @type conn_timeout: int
    @param sess_timeout: Sets the session timeout value. A higher value may
                       | be desired for long running commands, such as
                       | 'request system snapshot slice alternate'
    @type sess_timeout: int
    @param port: The port to connect to the device on. Defaults to 22.
    @type port: int

    @returns: We could return either just a string of the output from the
            | device, or a tuple containing the information needed to write
            | to a file and the string output from the device.
    @rtype: Tuple or str

def open_connection(ip, username, password, function, args, write=False,
                    conn_timeout=5, sess_timeout=300, port=22):
    """ Open a Jaide session with the device.

    To open a Jaide session to the device, and run the appropriate function
    against the device. Arguments for the downstream function are passed
    through.

    @param ip: String of the IP or hostname of the device to connect to.
    @type ip: str
    @param username: The string username used to connect to the device.
    @type useranme: str
    @param password: The string password used to connect to the device.
    @type password: str
    @param function: The downstream jaide.wrap function we'll be handing
                   | off the jaide.Jaide() object to execute the command
                   | once we've established the connection.
    @type function: function pointer.
    @param args: The arguments that we will hand off to the downstream
               | function.
    @type args: list
    @param write: If set, it would be a tuple that we pass back as part of
                | our return statement, so that any callback function
                | can know how and where to put the output from the device.
    @type write: False or tuple.
    @param conn_timeout: Sets the connection timeout value. This is how
                       | we'll wait when connecting before classifying
                       | the device unreachable.
    @type conn_timeout: int
    @param sess_timeout: Sets the session timeout value. A higher value may
                       | be desired for long running commands, such as
                       | 'request system snapshot slice alternate'
    @type sess_timeout: int
    @param port: The port to connect to the device on. Defaults to 22.
    @type port: int

    @returns: We could return either just a string of the output from the
            | device, or a tuple containing the information needed to write
            | to a file and the string output from the device.
    @rtype: Tuple or str
    """
    # start with the header line on the output.
    output = color('=' * 50 + '\nResults from device: %s\n' % ip, 'yel')
    try:
        # create the Jaide session object for the device.
        conn = Jaide(ip, username, password, connect_timeout=conn_timeout,
                     session_timeout=sess_timeout, port=port)
        if write is not False:
            return write, output + function(conn, *args)
        else:
            return output + function(conn, *args)
    except errors.SSHError:
        output += color('Unable to connect to port %s on device: %s\n' %
                        (str(port), ip), 'red')
    except errors.AuthenticationError:  # NCClient auth failure
        output += color('Authentication failed for device: %s' % ip, 'red')
    except AuthenticationException:  # Paramiko auth failure
        output += color('Authentication failed for device: %s' % ip, 'red')
    except SSHException as e:
        output += color('Error connecting to device: %s\nError: %s' %
                        (ip, str(e)), 'red')
    except socket.timeout:
        output += color('Timeout exceeded connecting to device: %s' % ip, 'red')
    except socket.gaierror:
        output += color('No route to host, or invalid hostname: %s' % ip, 'red')
    except socket.error:
        output += color('The device refused the connection on port %s, or '
                        'no route to host.' % port, 'red')
    if write is not False:
        return write, output
    else:
        return output