Execute a commit against the device.

    Purpose: This function will send set commands to a device, and commit
           | the changes. Options exist for confirming, comments,
           | synchronizing, checking, blank commits, or delaying to a later
           | time/date.

    @param jaide: The jaide connection to the device.
    @type jaide: jaide.Jaide object
    @param commands: String containing the set command to be sent to the
                   | device. It can be a python list of strings, a single set
                   | command, a comma separated string of commands, or a
                   | string filepath pointing to a file with set commands
                   | on each line.
    @type commands: str or list
    @param check: A bool set to true to only run a commit check, and not
                | commit any changes. Useful for checking syntax of set
                | commands.
    @type check: bool
    @param sync: A bool set to true to sync the commit across both REs.
    @type sync: bool
    @param comment: A string that will be logged to the commit log
                  | describing the commit.
    @type comment: str
    @param confirm: An integer of seconds to commit confirm for.
    @type confirm: int
    @param at_time: A string containing the time or time and date of when
                  | the commit should happen. Junos is expecting one of two
                  | formats:
                  | A time value of the form hh:mm[:ss] (hours, minutes,
                  |     and optionally seconds)
                  | A date and time value of the form yyyy-mm-dd hh:mm[:ss]
                  |     (year, month, date, hours, minutes, and optionally
                  |      seconds)
    @type at_time: str
    @param blank: A bool set to true to only make a blank commit. A blank
                | commit makes a commit, but doesn't have any set commands
                | associated with it, so no changes are made, but a commit
                | does happen.
    @type blank: bool

    @returns: The output from the device.
    @rtype: str

def commit(jaide, commands, check, sync, comment, confirm, at_time, blank):
    """ Execute a commit against the device.

    Purpose: This function will send set commands to a device, and commit
           | the changes. Options exist for confirming, comments,
           | synchronizing, checking, blank commits, or delaying to a later
           | time/date.

    @param jaide: The jaide connection to the device.
    @type jaide: jaide.Jaide object
    @param commands: String containing the set command to be sent to the
                   | device. It can be a python list of strings, a single set
                   | command, a comma separated string of commands, or a
                   | string filepath pointing to a file with set commands
                   | on each line.
    @type commands: str or list
    @param check: A bool set to true to only run a commit check, and not
                | commit any changes. Useful for checking syntax of set
                | commands.
    @type check: bool
    @param sync: A bool set to true to sync the commit across both REs.
    @type sync: bool
    @param comment: A string that will be logged to the commit log
                  | describing the commit.
    @type comment: str
    @param confirm: An integer of seconds to commit confirm for.
    @type confirm: int
    @param at_time: A string containing the time or time and date of when
                  | the commit should happen. Junos is expecting one of two
                  | formats:
                  | A time value of the form hh:mm[:ss] (hours, minutes,
                  |     and optionally seconds)
                  | A date and time value of the form yyyy-mm-dd hh:mm[:ss]
                  |     (year, month, date, hours, minutes, and optionally
                  |      seconds)
    @type at_time: str
    @param blank: A bool set to true to only make a blank commit. A blank
                | commit makes a commit, but doesn't have any set commands
                | associated with it, so no changes are made, but a commit
                | does happen.
    @type blank: bool

    @returns: The output from the device.
    @rtype: str
    """
    # set the commands to do nothing if the user wants a blank commit.
    if blank:
        commands = 'annotate system ""'
    output = ""
    # add show | compare output
    if commands != "":
        output += color("show | compare:\n", 'yel')
        try:
            output += color_diffs(jaide.compare_config(commands)) + '\n'
        except RPCError as e:
            output += color("Could not get config comparison results before"
                            " committing due to the following error:\n%s" %
                            str(e))
    # If they just want to validate the config, without committing
    if check:
        output += color("Commit check results from: %s\n" % jaide.host, 'yel')
        try:
            output += jaide.commit_check(commands) + '\n'
        except RPCError:
            output += color("Uncommitted changes left on the device or someone"
                            " else is in edit mode, couldn't lock the "
                            "candidate configuration.\n", 'red')
        except:
            output += color("Failed to commit check on device %s for an "
                            "unknown reason.\n" % jaide.host, 'red')
    # Actually make a commit
    else:
        output += color("Attempting to commit on device: %s\n" % jaide.host,
                        'yel')
        try:
            results = jaide.commit(confirmed=confirm, comment=comment,
                                   at_time=at_time, synchronize=sync,
                                   commands=commands)
        except RPCError as e:
            output += color('Commit could not be completed on this device, due'
                            ' to the following error(s):\n' + str(e), 'red')
        # Jaide command succeeded, parse results
        else:
            if 'commit complete' in results:
                output += results.split('commit complete')[0] + '\n'
                output += color('Commit complete on device: %s\n' % jaide.host)
                if confirm:
                    output += color('Commit confirm will rollback in %s '
                                    'minutes unless you commit again.\n' %
                                    str(confirm/60))
            elif 'commit at' in results:
                output += results.split('commit at will be executed at')[0]
                output += color('Commit staged to happen at: %s\n' % at_time)
            else:
                if 'failed' in results:
                    output += (results.replace('failed', color('failed',
                               'red')))
                if 'red' in results:
                    output += (results.replace('red', color('red',
                               'red')))
                output += color('Commit Failed on device: %s\n' % jaide.host,
                                'red')
    return output