openconfig-lldp_cisco_xr

Reference path:

ttp://yang/openconfig-lldp_cisco_xr.txt


Required devices' commands output:

  • show lldp neighbors detail

Device output should contain device prompt, otherwise device hostname will not be extracted.

Returns result compatible with this subset of openconfig-lldp YANG model:

module: openconfig-lldp
  +--rw lldp
     +--rw config
     |  +--rw system-name?                  string
     +--rw interfaces
        +--rw interface* [name]
           +--rw name         
           +--ro neighbors
              +--ro neighbor* [id]
                 +--ro id              
                 +--ro state
                 |  +--ro system-name?               string
                 |  +--ro system-description?        string
                 |  +--ro chassis-id?                string
                 |  +--ro chassis-id-type?           oc-lldp-types:chassis-id-type
                 |  +--ro id?                        string
                 |  +--ro port-id?                   string
                 |  +--ro port-id-type?              oc-lldp-types:port-id-type
                 |  +--ro port-description?          string
                 |  +--ro management-address?        string
                 +--ro capabilities
                    +--ro capability* [name]
                       +--ro name        


Template Content
<doc>
Required devices' commands output:

 - show lldp neighbors detail

Device output should contain device prompt, otherwise device hostname will not be extracted.

Returns result compatible with this subset of 'openconfig-lldp'
YANG model:
'''
module: openconfig-lldp
  +--rw lldp
     +--rw config
     |  +--rw system-name?                  string
     +--rw interfaces
        +--rw interface* [name]
           +--rw name         
           +--ro neighbors
              +--ro neighbor* [id]
                 +--ro id              
                 +--ro state
                 |  +--ro system-name?               string
                 |  +--ro system-description?        string
                 |  +--ro chassis-id?                string
                 |  +--ro chassis-id-type?           oc-lldp-types:chassis-id-type
                 |  +--ro id?                        string
                 |  +--ro port-id?                   string
                 |  +--ro port-id-type?              oc-lldp-types:port-id-type
                 |  +--ro port-description?          string
                 |  +--ro management-address?        string
                 +--ro capabilities
                    +--ro capability* [name]
                       +--ro name        
'''                    
</doc>



<macro>
def process(data):
    """
    Function to process parsing results in a structure
    compatible with openconfig-lldp YANG module.

    Parsing results are a dictionary keyed by interface name, that 
    is done to combine multiple neighbors in a list under the 
    interface, while in opencofnig-lldp model structure under 
    "lldp.interfaces.inderface" must be a list.

    Moreover, neighbors must contain "id" key and use "state" key to
    store information about neighbor details.
    """
    ret = []

    for res_item in data:
        # transform dictionary of interfaces into a list
        ret_template = {
                "opencondig-lldp": {
                    "lldp": {
                        "interfaces": {"interface": []},
                        "config": {
                            "system-name": res_item.get("system_name", {}).get("hostname")
                        }
                    }
                }
        }
        interfaces = res_item.get("lldp", {}).get("interfaces", {}).get("inderface", {})
        for interface_name, interface_data in interfaces.items():

            # set neighbors IDs and form structure with "state" key
            neighbors = interface_data["neighbors"]["neighbor"]
            interface_data["neighbors"]["neighbor"] = []
            for id, neigbour in enumerate(neighbors, 1):
                interface_data["neighbors"]["neighbor"].append(
                    {
                        "id": id,
                        "state": {"id": id, **neigbour}
                    }            
                )

            # form final interface structure
            ret_template["opencondig-lldp"]["lldp"]["interfaces"]["interface"].append(
                {
                    "name": interface_name,
                    **interface_data
                }
            )
        ret.append(ret_template)

    return ret

def map_capabilities(data):
    """
    Function to map capabilities
    """
    ret = []

    mapper = {
        "B": {"name": "MAC_BRIDGE"},
        "R": {"name": "ROUTER"}
    }

    for code in data.get("codes", []):
        if code in mapper:
            ret.append(mapper[code])

    return {"capability": ret}
</macro>

<vars>
ifmap = {
    'ATM': ['^ATM', '^AT'],
    'BDI': ['^Bd', '^Bdi'],
    'EOBC': ['^EOBC', '^EO'],
    'Eth': ['^Ethernet', '^Eth', '^eth', r'^Et(?=\d)', r'^et(?=\d)'],
    'FE': ['^FastEthernet', '^FastEth', '^FastE', '^Fast', '^Fas', '^FE', '^Fa', '^fa'],
    'Fddi': ['^Fddi', '^FD'],
    '50GE': ['^FiftyGigabitEthernet', '^FiftyGigEthernet', '^FiftyGigEth', '^FiftyGigE', '^FI', '^Fi', '^fi'],
    '40GE': ['^FortyGigabitEthernet', '^FortyGigEthernet', '^FortyGigEth', '^FortyGigE', '^FortyGig', '^FGE', '^FO', '^Fo'],
    '400GE': ['^FourHundredGigabitEthernet', '^FourHundredGigEthernet', '^FourHundredGigEth', '^FourHundredGigE', '^FourHundredGig', '^F', '^f'],
    'GE': ['^GigabitEthernet', '^GigEthernet', '^GigEth', '^GigE', '^Gig', '^GE', '^Ge', '^ge', '^Gi', '^gi'],
    '100GE': ['^HundredGigabitEthernet', '^HundredGigEthernet', '^HundredGigEth', '^HundredGigE', '^HundredGig', '^Hu'],
    'Lo': ['^Loopback', '^loopback', '^Lo', '^lo'],
    'MFR': ['^MFR'], 
    'Ma': ['^Management_short'],
    'MGMT': ['^Management', '^Mgmt', '^mgmt', '^Ma'],
    'Multilink': ['^Multilink', '^Mu'],
    'POS': ['^POS', '^PO'],
    'LAG': ['^PortChannel', '^Port-channel', '^Port-Channel', '^port-channel', '^po', '^Po', "^Bundle-Ether", "^BE"],
    'Serial': ['^Serial', '^Se', '^S'],
    '10GE': ['^TenGigabitEthernet', '^TenGigEthernet', '^TenGigEth', '^TenGigE', '^TenGig', '^TeGig', '^Ten', '^Te', '^te'],
    'Tunnel': ['^Tunnel', '^Tun', '^Tu'],
    '25GE': ['^TwentyFiveGigabitEthernet', '^TwentyFiveGigEthernet', '^TwentyFiveGigEth', '^TwentyFiveGigE', '^TwentyFiveGig', '^Twe', '^TF', '^Tf', '^tf'],
    '2GE': ['^Tw', '^Two'],
    '200GE': ['^TwoHundredGigabitEthernet', '^TwoHundredGigEthernet', '^TwoHundredGigEth', '^TwoHundredGigE', '^TwoHundredGig', '^TH', '^Th', '^th'],
    'VLAN': ['^VLAN', '^V', '^Vl'],
    'Virtual-Access': ['^Virtual-Access', '^Vi'],
    'Virtual-Template': ['^Virtual-Template', '^Vt'],
    'WLAN': ['^Wlan-GigabitEthernet'],
    'nve': ['^n', '^nv', '^nve']
}
</vars>

<vars name="system_name">
hostname="gethostname"
</vars>

<group name="lldp.interfaces.inderface**.{{ name }}**">
##
##  Parses "show lldp neighbors detail" output
##
Local Interface: {{ name | resuball(ifmap) }}

<group name="neighbors.neighbor*">
Chassis id: {{ chassis-id | mac_eui }}
Port id: {{ port-id | resuball(ifmap) }}
Port Description: {{ port-description | re(".+") | default(None) }}
System Name: {{ system-name }}
  IPv4 address: {{ management-address | default(None) }}

<group name="_">
System Description: {{ _start_ }}
{{ system-description | _line_ | strip | joinmatches(" ") }}
Time remaining: {{ ignore }} seconds {{ _end_ }}
</group>

<group name="capabilities" macro="map_capabilities">
System Capabilities: {{ codes | split(",") }}
</group>

{{ port-id-type | set("INTERFACE_NAME") }}
{{ chassis-id-type | set("MAC_ADDRESS") }}
</group>
</group>

<output macro="process"/>
Back to top