Search in the MAC Address tables, using the following mine functions:

    - net.mac

    Optional arguments:

    device
        Return interface data from a certain device only.

    interface
        Return data selecting by interface name.

    mac
        Search using a specific MAC Address.

    vlan
        Search using a VLAN ID.

    display: ``True``
        Display on the screen or return structured object? Default: ``True``, will return on the CLI.

    CLI Example:

    .. code-block:: bash

        $ sudo salt-run net.findmac mac=8C:60:0F:78:EC:41

    Output Example:

    .. code-block:: text

        MAC Address(es)
        _____________________________________________________________________________________________
        |    Device    | Interface |        MAC        | VLAN | Static | Active | Moves | Last move |
        _____________________________________________________________________________________________
        | edge01.bjm01 |  ae0.171  | 8C:60:0F:78:EC:41 | 171  | False  |  True  |   0   |    0.0    |
        _____________________________________________________________________________________________

def findmac(device=None, mac=None, interface=None, vlan=None, display=_DEFAULT_DISPLAY):
    '''
    Search in the MAC Address tables, using the following mine functions:

    - net.mac

    Optional arguments:

    device
        Return interface data from a certain device only.

    interface
        Return data selecting by interface name.

    mac
        Search using a specific MAC Address.

    vlan
        Search using a VLAN ID.

    display: ``True``
        Display on the screen or return structured object? Default: ``True``, will return on the CLI.

    CLI Example:

    .. code-block:: bash

        $ sudo salt-run net.findmac mac=8C:60:0F:78:EC:41

    Output Example:

    .. code-block:: text

        MAC Address(es)
        _____________________________________________________________________________________________
        |    Device    | Interface |        MAC        | VLAN | Static | Active | Moves | Last move |
        _____________________________________________________________________________________________
        | edge01.bjm01 |  ae0.171  | 8C:60:0F:78:EC:41 | 171  | False  |  True  |   0   |    0.0    |
        _____________________________________________________________________________________________
    '''
    labels = {
        'device': 'Device',
        'interface': 'Interface',
        'mac': 'MAC',
        'vlan': 'VLAN',
        'static': 'Static',
        'active': 'Active',
        'moves': 'Moves',
        'last_move': 'Last Move'
    }
    rows = []

    all_mac = _get_mine('net.mac')

    title = "MAC Address(es)"
    if device:
        title += ' on device {device}'.format(device=device)
    if interface:
        title += ' on interface {interf}'.format(interf=interface)
    if vlan:
        title += ' on VLAN {vlan}'.format(vlan=vlan)

    if device:
        all_mac = {device: all_mac.get(device)}

    for device, device_mac in six.iteritems(all_mac):
        if not device_mac:
            continue
        if not device_mac.get('result', False):
            continue
        mac_table = device_mac.get('out', [])
        for mac_entry in mac_table:
            if ((mac and    # pylint: disable=too-many-boolean-expressions
                napalm_helpers.convert(napalm_helpers.mac, mac_entry.get('mac', '')) ==
                napalm_helpers.convert(napalm_helpers.mac, mac)) or
                (interface and interface in mac_entry.get('interface', '')) or
               (vlan and six.text_type(mac_entry.get('vlan', '')) == six.text_type(vlan))):
                rows.append({
                    'device': device,
                    'interface': mac_entry.get('interface'),
                    'mac': napalm_helpers.convert(napalm_helpers.mac, mac_entry.get('mac')),
                    'vlan': mac_entry.get('vlan'),
                    'static': mac_entry.get('static'),
                    'active': mac_entry.get('active'),
                    'moves': mac_entry.get('moves'),
                    'last_move': mac_entry.get('last_move')
                })

    return _display_runner(rows, labels, title, display=display)