def catalog_register(consul_url=None, token=None, **kwargs):
    '''
    Registers a new node, service, or check

    :param consul_url: The Consul server URL.
    :param dc: By default, the datacenter of the agent is queried;
               however, the dc can be provided using the "dc" parameter.
    :param node: The node to register.
    :param address: The address of the node.
    :param service: The service that will be registered.
    :param service_address: The address that the service listens on.
    :param service_port: The port for the service.
    :param service_id: A unique identifier for the service, if this is not
                       provided "name" will be used.
    :param service_tags: Any tags associated with the service.
    :param check: The name of the health check to register
    :param check_status: The initial status of the check,
                         must be one of unknown, passing, warning, or critical.
    :param check_service: The service that the check is performed against.
    :param check_id: Unique identifier for the service.
    :param check_notes: An opaque field that is meant to hold human-readable text.
    :return: Boolean & message of success or failure.

    CLI Example:

    .. code-block:: bash

        salt '*' consul.catalog_register node='node1' address='192.168.1.1' service='redis' service_address='127.0.0.1' service_port='8080' service_id='redis_server1'

    '''
    ret = {}
    data = {}
    data['NodeMeta'] = {}
    if not consul_url:
        consul_url = _get_config()
        if not consul_url:
            log.error('No Consul URL found.')
            ret['message'] = 'No Consul URL found.'
            ret['res'] = False
            return ret

    if 'datacenter' in kwargs:
        data['Datacenter'] = kwargs['datacenter']

    if 'node' in kwargs:
        data['Node'] = kwargs['node']
    else:
        ret['message'] = 'Required argument node argument is missing.'
        ret['res'] = False
        return ret

    if 'address' in kwargs:
        if isinstance(kwargs['address'], list):
            _address = kwargs['address'][0]
        else:
            _address = kwargs['address']
        data['Address'] = _address
    else:
        ret['message'] = 'Required argument address argument is missing.'
        ret['res'] = False
        return ret

    if 'ip_interfaces' in kwargs:
        data['TaggedAddresses'] = {}
        for k in kwargs['ip_interfaces']:
            if kwargs['ip_interfaces'].get(k):
                data['TaggedAddresses'][k] = kwargs['ip_interfaces'][k][0]

    if 'service' in kwargs:
        data['Service'] = {}
        data['Service']['Service'] = kwargs['service']

        if 'service_address' in kwargs:
            data['Service']['Address'] = kwargs['service_address']

        if 'service_port' in kwargs:
            data['Service']['Port'] = kwargs['service_port']

        if 'service_id' in kwargs:
            data['Service']['ID'] = kwargs['service_id']

        if 'service_tags' in kwargs:
            _tags = kwargs['service_tags']
            if not isinstance(_tags, list):
                _tags = [_tags]
            data['Service']['Tags'] = _tags

    if 'cpu' in kwargs:
        data['NodeMeta']['Cpu'] = kwargs['cpu']

    if 'num_cpus' in kwargs:
        data['NodeMeta']['Cpu_num'] = kwargs['num_cpus']

    if 'mem' in kwargs:
        data['NodeMeta']['Memory'] = kwargs['mem']

    if 'oscode' in kwargs:
        data['NodeMeta']['Os'] = kwargs['oscode']

    if 'osarch' in kwargs:
        data['NodeMeta']['Osarch'] = kwargs['osarch']

    if 'kernel' in kwargs:
        data['NodeMeta']['Kernel'] = kwargs['kernel']

    if 'kernelrelease' in kwargs:
        data['NodeMeta']['Kernelrelease'] = kwargs['kernelrelease']

    if 'localhost' in kwargs:
        data['NodeMeta']['localhost'] = kwargs['localhost']

    if 'nodename' in kwargs:
        data['NodeMeta']['nodename'] = kwargs['nodename']

    if 'os_family' in kwargs:
        data['NodeMeta']['os_family'] = kwargs['os_family']

    if 'lsb_distrib_description' in kwargs:
        data['NodeMeta']['lsb_distrib_description'] = kwargs['lsb_distrib_description']

    if 'master' in kwargs:
        data['NodeMeta']['master'] = kwargs['master']

    if 'check' in kwargs:
        data['Check'] = {}
        data['Check']['Name'] = kwargs['check']

        if 'check_status' in kwargs:
            if kwargs['check_status'] not in ('unknown', 'passing', 'warning', 'critical'):
                ret['message'] = 'Check status must be unknown, passing, warning, or critical.'
                ret['res'] = False
                return ret
            data['Check']['Status'] = kwargs['check_status']

        if 'check_service' in kwargs:
            data['Check']['ServiceID'] = kwargs['check_service']

        if 'check_id' in kwargs:
            data['Check']['CheckID'] = kwargs['check_id']

        if 'check_notes' in kwargs:
            data['Check']['Notes'] = kwargs['check_notes']

    function = 'catalog/register'
    res = _query(consul_url=consul_url,
                 function=function,
                 token=token,
                 method='PUT',
                 data=data)
    if res['res']:
        ret['res'] = True
        ret['message'] = ('Catalog registration '
                          'for {0} successful.'.format(kwargs['node']))
    else:
        ret['res'] = False
        ret['message'] = ('Catalog registration '
                          'for {0} failed.'.format(kwargs['node']))
    ret['data'] = data
    return ret