Manages a node of a given bigip device.  If the node does not exist it will be created, otherwise,
    only the properties which are different than the existing will be updated.

    hostname
        The host/address of the bigip device
    username
        The iControl REST username
    password
        The iControl REST password
    name
        The name of the node to manage.
    address
        The address of the node
    connection_limit
        [integer]
    description
        [string]
    dynam
        c_ratio:        [integer]
    logging
        [enabled | disabled]
    monitor
        [[name] | none | default]
    rate_limit
        [integer]
    ratio
        [integer]
    session
        [user-enabled | user-disabled]
    node_state (state)
        [user-down | user-up ]

def manage_node(hostname, username, password, name, address,
                connection_limit=None,
                description=None,
                dynamic_ratio=None,
                logging=None,
                monitor=None,
                rate_limit=None,
                ratio=None,
                session=None,
                node_state=None):
    '''
    Manages a node of a given bigip device.  If the node does not exist it will be created, otherwise,
    only the properties which are different than the existing will be updated.

    hostname
        The host/address of the bigip device
    username
        The iControl REST username
    password
        The iControl REST password
    name
        The name of the node to manage.
    address
        The address of the node
    connection_limit
        [integer]
    description
        [string]
    dynam
        c_ratio:        [integer]
    logging
        [enabled | disabled]
    monitor
        [[name] | none | default]
    rate_limit
        [integer]
    ratio
        [integer]
    session
        [user-enabled | user-disabled]
    node_state (state)
        [user-down | user-up ]
    '''

    ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}

    if __opts__['test']:
        return _test_output(ret, 'manage', params={
            'hostname': hostname,
            'username': username,
            'password': password,
            'name': name,
            'address': address,
            'connection_limit': connection_limit,
            'description': description,
            'dynamic_ratio': dynamic_ratio,
            'logging': logging,
            'monitor': monitor,
            'rate_limit': rate_limit,
            'ratio': ratio,
            'session': session,
            'state:': node_state
        }
        )

    #is this node currently configured?
    existing = __salt__['bigip.list_node'](hostname, username, password, name)

    # if it exists by name
    if existing['code'] == 200:

        # ensure the address is the same, we don't want to modify a different node than what
        # we think we are managing
        if existing['content']['address'] != address:
            ret['result'] = False
            ret['comment'] = 'A node with this name exists but the address does not match.'

        modified = __salt__['bigip.modify_node'](hostname=hostname,
                                                 username=username,
                                                 password=password,
                                                 name=name,
                                                 connection_limit=connection_limit,
                                                 description=description,
                                                 dynamic_ratio=dynamic_ratio,
                                                 logging=logging,
                                                 monitor=monitor,
                                                 rate_limit=rate_limit,
                                                 ratio=ratio,
                                                 session=session,
                                                 state=node_state)

        #was the modification successful?
        if modified['code'] == 200:
            ret = _check_for_changes('Node', ret, existing, modified)
        else:
            ret = _load_result(modified, ret)

    # not found, attempt to create it
    elif existing['code'] == 404:

        new = __salt__['bigip.create_node'](hostname, username, password, name, address)

        # were we able to create it?
        if new['code'] == 200:
            # try modification

            modified = __salt__['bigip.modify_node'](hostname=hostname,
                                                     username=username,
                                                     password=password,
                                                     name=name,
                                                     connection_limit=connection_limit,
                                                     description=description,
                                                     dynamic_ratio=dynamic_ratio,
                                                     logging=logging,
                                                     monitor=monitor,
                                                     rate_limit=rate_limit,
                                                     ratio=ratio,
                                                     session=session,
                                                     state=node_state)
            #was the modification successful?
            if modified['code'] == 200:

                ret['result'] = True
                ret['comment'] = 'Node was created and enforced to the desired state.  Note: Only parameters specified ' \
                                 'were enforced.  See changes for details.'
                ret['changes']['old'] = {}
                ret['changes']['new'] = modified['content']

            # roll it back
            else:

                deleted = __salt__['bigip.delete_node'](hostname, username, password, name)
                # did we get rid of it?
                if deleted['code'] == 200:
                    ret['comment'] = 'Node was successfully created but an error occurred during modification. ' \
                                     'The creation of the node has been rolled back. Message is as follows:\n' \
                                     '{message}'.format(message=modified['content']['message'])
                # something bad happened
                else:
                    ret['comment'] = 'Node was successfully created but an error occurred during modification. ' \
                                     'The creation of the node was not able to be rolled back. Message is as follows:' \
                                     '\n {message}\n{message_two}'.format(message=modified['content']['message'],
                                                                          message_two=deleted['content']['message'])

        # unable to create it
        else:
            ret = _load_result(new, ret)
    # an error occurred
    else:
        ret = _load_result(existing, ret)

    return ret