diff --git a/ansible/library/snmp_facts.py b/ansible/library/snmp_facts.py index 85ce82a9dd0..885f0a74d29 100644 --- a/ansible/library/snmp_facts.py +++ b/ansible/library/snmp_facts.py @@ -141,6 +141,47 @@ def __init__(self,dotprefix=False): self.ipAdEntIfIndex = dp + "1.3.6.1.2.1.4.20.1.2" self.ipAdEntNetMask = dp + "1.3.6.1.2.1.4.20.1.3" + # From LLDP-MIB: lldpLocalSystemData + self.lldpLocChassisIdSubtype = dp + "1.0.8802.1.1.2.1.3.1" + self.lldpLocChassisId = dp + "1.0.8802.1.1.2.1.3.2" + self.lldpLocSysName = dp + "1.0.8802.1.1.2.1.3.3" + self.lldpLocSysDesc = dp + "1.0.8802.1.1.2.1.3.4" + + # From LLDP-MIB: lldpLocPortTable + self.lldpLocPortNum = dp + "1.0.8802.1.1.2.1.3.7.1.1" # + .ifindex + self.lldpLocPortIdSubtype = dp + "1.0.8802.1.1.2.1.3.7.1.2" # + .ifindex + self.lldpLocPortId = dp + "1.0.8802.1.1.2.1.3.7.1.3" # + .ifindex + self.lldpLocPortDesc = dp + "1.0.8802.1.1.2.1.3.7.1.4" # + .ifindex + + # From LLDP-MIB: lldpLocManAddrTables + self.lldpLocManAddrSubtype = dp + "1.0.8802.1.1.2.1.3.8.1.1" # + .subtype + .man addr + self.lldpLocManAddr = dp + "1.0.8802.1.1.2.1.3.8.1.2" # + .subtype + .man addr + self.lldpLocManAddrLen = dp + "1.0.8802.1.1.2.1.3.8.1.3" # + .subtype + .man addr + self.lldpLocManAddrIfSubtype = dp + "1.0.8802.1.1.2.1.3.8.1.4" # + .subtype + .man addr + self.lldpLocManAddrIfId = dp + "1.0.8802.1.1.2.1.3.8.1.5" # + .subtype + .man addr + self.lldpLocManAddrOID = dp + "1.0.8802.1.1.2.1.3.8.1.6" # + .subtype + .man addr + + # From LLDP-MIB: lldpRemTable + self.lldpRemTimeMark = dp + "1.0.8802.1.1.2.1.4.1.1.1" # + .time mark + .ifindex + .rem index + self.lldpRemLocalPortNum = dp + "1.0.8802.1.1.2.1.4.1.1.2" # + .time mark + .ifindex + .rem index + self.lldpRemIndex = dp + "1.0.8802.1.1.2.1.4.1.1.3" # + .time mark + .ifindex + .rem index + self.lldpRemChassisIdSubtype = dp + "1.0.8802.1.1.2.1.4.1.1.4" # + .time mark + .ifindex + .rem index + self.lldpRemChassisId = dp + "1.0.8802.1.1.2.1.4.1.1.5" # + .time mark + .ifindex + .rem index + self.lldpRemPortIdSubtype = dp + "1.0.8802.1.1.2.1.4.1.1.6" # + .time mark + .ifindex + .rem index + self.lldpRemPortId = dp + "1.0.8802.1.1.2.1.4.1.1.7" # + .time mark + .ifindex + .rem index + self.lldpRemPortDesc = dp + "1.0.8802.1.1.2.1.4.1.1.8" # + .time mark + .ifindex + .rem index + self.lldpRemSysName = dp + "1.0.8802.1.1.2.1.4.1.1.9" # + .time mark + .ifindex + .rem index + self.lldpRemSysDesc = dp + "1.0.8802.1.1.2.1.4.1.1.10" # + .time mark + .ifindex + .rem index + self.lldpRemSysCapSupported = dp + "1.0.8802.1.1.2.1.4.1.1.11" # + .time mark + .ifindex + .rem index + self.lldpRemSysCapEnabled = dp + "1.0.8802.1.1.2.1.4.1.1.12" # + .time mark + .ifindex + .rem index + + # From LLDP-MIB: lldpRemManAddrTable + self.lldpRemManAddrSubtype = dp + "1.0.8802.1.1.2.1.4.2.1.1" # + .time mark + .ifindex + .rem index + .addr_subtype + .man addr + self.lldpRemManAddr = dp + "1.0.8802.1.1.2.1.4.2.1.2" # + .time mark + .ifindex + .rem index + .addr_subtype + .man addr + self.lldpRemManAddrIfSubtype = dp + "1.0.8802.1.1.2.1.4.2.1.3" # + .time mark + .ifindex + .rem index + .addr_subtype + .man addr + self.lldpRemManAddrIfId = dp + "1.0.8802.1.1.2.1.4.2.1.4" # + .time mark + .ifindex + .rem index + .addr_subtype + .man addr + self.lldpRemManAddrOID = dp + "1.0.8802.1.1.2.1.4.2.1.5" # + .time mark + .ifindex + .rem index + .addr_subtype + .man addr + # From Dell Private MIB self.ChStackUnitCpuUtil5sec = dp + "1.3.6.1.4.1.6027.3.10.1.2.9.1.2.1" @@ -480,6 +521,195 @@ def main(): if current_oid == v.ChStackUnitCpuUtil5sec: results['ansible_ChStackUnitCpuUtil5sec'] = decode_type(module, current_oid, val) + errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd( + snmp_auth, + cmdgen.UdpTransportTarget((m_args['host'], 161)), + cmdgen.MibVariable(p.lldpLocChassisIdSubtype,), + cmdgen.MibVariable(p.lldpLocChassisId,), + cmdgen.MibVariable(p.lldpLocSysName,), + cmdgen.MibVariable(p.lldpLocSysDesc,), + ) + + if errorIndication: + module.fail_json(msg=str(errorIndication) + ' querying lldp local system infomation.') + + for oid, val in varBinds: + current_oid = oid.prettyPrint() + current_val = val.prettyPrint() + if current_oid == v.lldpLocChassisIdSubtype: + results['snmp_lldp']['lldpLocChassisIdSubtype'] = current_val + elif current_oid == v.lldpLocChassisId: + results['snmp_lldp']['lldpLocChassisId'] = current_val + elif current_oid == v.lldpLocSysName: + results['snmp_lldp']['lldpLocSysName'] = current_val + elif current_oid == v.lldpLocSysDesc: + results['snmp_lldp']['lldpLocSysDesc'] = current_val + + errorIndication, errorStatus, errorIndex, varTable = cmdGen.nextCmd( + snmp_auth, + cmdgen.UdpTransportTarget((m_args['host'], 161)), + cmdgen.MibVariable(p.lldpLocPortNum,), + cmdgen.MibVariable(p.lldpLocPortIdSubtype,), + cmdgen.MibVariable(p.lldpLocPortId,), + cmdgen.MibVariable(p.lldpLocPortDesc,), + ) + + if errorIndication: + module.fail_json(msg=str(errorIndication) + ' querying lldpLocPortTable counters') + + for varBinds in varTable: + for oid, val in varBinds: + current_oid = oid.prettyPrint() + current_val = val.prettyPrint() + if v.lldpLocPortNum in current_oid: + ifIndex = int(current_oid.rsplit('.', 1)[-1]) + results['snmp_interfaces'][ifIndex]['lldpLocPortNum'] = current_val + if v.lldpLocPortIdSubtype in current_oid: + ifIndex = int(current_oid.rsplit('.', 1)[-1]) + results['snmp_interfaces'][ifIndex]['lldpLocPortIdSubtype'] = current_val + if v.lldpLocPortId in current_oid: + ifIndex = int(current_oid.rsplit('.', 1)[-1]) + results['snmp_interfaces'][ifIndex]['lldpLocPortId'] = current_val + if v.lldpLocPortDesc in current_oid: + ifIndex = int(current_oid.rsplit('.', 1)[-1]) + results['snmp_interfaces'][ifIndex]['lldpLocPortDesc'] = current_val + + errorIndication, errorStatus, errorIndex, varTable = cmdGen.nextCmd( + snmp_auth, + cmdgen.UdpTransportTarget((m_args['host'], 161)), + cmdgen.MibVariable(p.lldpLocManAddrSubtype,), + cmdgen.MibVariable(p.lldpLocManAddr,), + cmdgen.MibVariable(p.lldpLocManAddrLen,), + cmdgen.MibVariable(p.lldpLocManAddrIfSubtype,), + cmdgen.MibVariable(p.lldpLocManAddrIfId,), + cmdgen.MibVariable(p.lldpLocManAddrOID,), + ) + + if errorIndication: + module.fail_json(msg=str(errorIndication) + ' querying lldpLocPortTable counters') + + for varBinds in varTable: + for oid, val in varBinds: + current_oid = oid.prettyPrint() + current_val = val.prettyPrint() + if v.lldpLocManAddrSubtype in current_oid: + address = '.'.join(current_oid.split('.')[13:]) + results['snmp_lldp']['lldpLocManAddrSubtype'] = current_val + if v.lldpLocManAddr in current_oid: + address = '.'.join(current_oid.split('.')[13:]) + results['snmp_lldp']['lldpLocManAddr'] = current_val + if v.lldpLocManAddrLen in current_oid: + address = '.'.join(current_oid.split('.')[13:]) + results['snmp_lldp']['lldpLocManAddrLen'] = current_val + if v.lldpLocManAddrIfSubtype in current_oid: + address = '.'.join(current_oid.split('.')[13:]) + results['snmp_lldp']['lldpLocManAddrIfSubtype'] = current_val + if v.lldpLocManAddrIfId in current_oid: + address = '.'.join(current_oid.split('.')[13:]) + results['snmp_lldp']['lldpLocManAddrIfId'] = current_val + if v.lldpLocManAddrOID in current_oid: + address = '.'.join(current_oid.split('.')[13:]) + results['snmp_lldp']['lldpLocManAddrOID'] = current_val + + errorIndication, errorStatus, errorIndex, varTable = cmdGen.nextCmd( + snmp_auth, + cmdgen.UdpTransportTarget((m_args['host'], 161)), + cmdgen.MibVariable(p.lldpRemTimeMark,), + cmdgen.MibVariable(p.lldpRemLocalPortNum,), + cmdgen.MibVariable(p.lldpRemIndex,), + cmdgen.MibVariable(p.lldpRemChassisIdSubtype,), + cmdgen.MibVariable(p.lldpRemChassisId,), + cmdgen.MibVariable(p.lldpRemPortIdSubtype,), + cmdgen.MibVariable(p.lldpRemPortId,), + cmdgen.MibVariable(p.lldpRemPortDesc,), + cmdgen.MibVariable(p.lldpRemSysName,), + cmdgen.MibVariable(p.lldpRemSysDesc,), + cmdgen.MibVariable(p.lldpRemSysCapSupported,), + cmdgen.MibVariable(p.lldpRemSysCapEnabled,), + ) + + if errorIndication: + module.fail_json(msg=str(errorIndication) + ' querying lldpLocPortTable counters') + + for varBinds in varTable: + for oid, val in varBinds: + current_oid = oid.prettyPrint() + current_val = val.prettyPrint() + if v.lldpRemTimeMark in current_oid: + ifIndex = int(current_oid.split('.')[12]) + results['snmp_interfaces'][ifIndex]['lldpRemTimeMark'] = current_val + if v.lldpRemLocalPortNum in current_oid: + ifIndex = int(current_oid.split('.')[12]) + results['snmp_interfaces'][ifIndex]['lldpRemLocalPortNum'] = current_val + if v.lldpRemIndex in current_oid: + ifIndex = int(current_oid.split('.')[12]) + results['snmp_interfaces'][ifIndex]['lldpRemIndex'] = current_val + if v.lldpRemChassisIdSubtype in current_oid: + ifIndex = int(current_oid.split('.')[12]) + results['snmp_interfaces'][ifIndex]['lldpRemChassisIdSubtype'] = current_val + if v.lldpRemChassisId in current_oid: + ifIndex = int(current_oid.split('.')[12]) + results['snmp_interfaces'][ifIndex]['lldpRemChassisId'] = current_val + if v.lldpRemPortIdSubtype in current_oid: + ifIndex = int(current_oid.split('.')[12]) + results['snmp_interfaces'][ifIndex]['lldpRemPortIdSubtype'] = current_val + if v.lldpRemPortId in current_oid: + ifIndex = int(current_oid.split('.')[12]) + results['snmp_interfaces'][ifIndex]['lldpRemPortId'] = current_val + if v.lldpRemPortDesc in current_oid: + ifIndex = int(current_oid.split('.')[12]) + results['snmp_interfaces'][ifIndex]['lldpRemPortDesc'] = current_val + if v.lldpRemSysName in current_oid: + ifIndex = int(current_oid.split('.')[12]) + results['snmp_interfaces'][ifIndex]['lldpRemSysName'] = current_val + if v.lldpRemSysDesc in current_oid: + ifIndex = int(current_oid.split('.')[12]) + results['snmp_interfaces'][ifIndex]['lldpRemSysDesc'] = current_val + if v.lldpRemSysCapSupported in current_oid: + ifIndex = int(current_oid.split('.')[12]) + results['snmp_interfaces'][ifIndex]['lldpRemSysCapSupported'] = current_val + if v.lldpRemSysCapEnabled in current_oid: + ifIndex = int(current_oid.split('.')[12]) + results['snmp_interfaces'][ifIndex]['lldpRemSysCapEnabled'] = current_val + + errorIndication, errorStatus, errorIndex, varTable = cmdGen.nextCmd( + snmp_auth, + cmdgen.UdpTransportTarget((m_args['host'], 161)), + cmdgen.MibVariable(p.lldpRemManAddrSubtype,), + cmdgen.MibVariable(p.lldpRemManAddr,), + cmdgen.MibVariable(p.lldpRemManAddrIfSubtype,), + cmdgen.MibVariable(p.lldpRemManAddrIfId,), + cmdgen.MibVariable(p.lldpRemManAddrOID,), + ) + + if errorIndication: + module.fail_json(msg=str(errorIndication) + ' querying lldpLocPortTable counters') + + for varBinds in varTable: + for oid, val in varBinds: + current_oid = oid.prettyPrint() + current_val = val.prettyPrint() + if v.lldpRemManAddrSubtype in current_oid: + ifIndex = int(current_oid.split('.')[12]) + address = '.'.join(current_oid.split('.')[16:]) + results['snmp_interfaces'][ifIndex]['lldpRemManAddrSubtype'] = current_val + if v.lldpRemManAddr in current_oid: + ifIndex = int(current_oid.split('.')[12]) + address = '.'.join(current_oid.split('.')[16:]) + results['snmp_interfaces'][ifIndex]['lldpRemManAddr'] = current_val + if v.lldpRemManAddrIfSubtype in current_oid: + ifIndex = int(current_oid.split('.')[12]) + address = '.'.join(current_oid.split('.')[16:]) + results['snmp_interfaces'][ifIndex]['lldpRemManAddrIfSubtype'] = current_val + if v.lldpRemManAddrIfId in current_oid: + ifIndex = int(current_oid.split('.')[12]) + address = '.'.join(current_oid.split('.')[16:]) + results['snmp_interfaces'][ifIndex]['lldpRemManAddrIfId'] = current_val + if v.lldpRemManAddrOID in current_oid: + ifIndex = int(current_oid.split('.')[12]) + address = '.'.join(current_oid.split('.')[16:]) + results['snmp_interfaces'][ifIndex]['lldpRemManAddrOID'] = current_val + errorIndication, errorStatus, errorIndex, varTable = cmdGen.nextCmd( snmp_auth, cmdgen.UdpTransportTarget((m_args['host'], 161)), diff --git a/ansible/roles/test/tasks/snmp.yml b/ansible/roles/test/tasks/snmp.yml index deebf82b4e0..4184fd64f30 100644 --- a/ansible/roles/test/tasks/snmp.yml +++ b/ansible/roles/test/tasks/snmp.yml @@ -22,4 +22,7 @@ - name: include snmp PSU test include: roles/test/tasks/snmp/psu.yml + + - name: include snmp lldp test + include: roles/test/tasks/snmp/lldp.yml when: testcase_name is defined diff --git a/ansible/roles/test/tasks/snmp/lldp.yml b/ansible/roles/test/tasks/snmp/lldp.yml new file mode 100644 index 00000000000..ac575a04fdf --- /dev/null +++ b/ansible/roles/test/tasks/snmp/lldp.yml @@ -0,0 +1,115 @@ +# Test checks for ieee802_1ab MIBs: +# - lldpLocalSystemData 1.0.8802.1.1.2.1.3 +# - lldpLocPortTable 1.0.8802.1.1.2.1.3.7 +# - lldpLocManAddrTable 1.0.8802.1.1.2.1.3.8 +# +# - lldpRemTable 1.0.8802.1.1.2.1.4.1 +# - lldpRemManAddrTable 1.0.8802.1.1.2.1.4.2 +# +# For local data check if every OID has value +# For remote values check for availability for +# at least 80% of minigraph neighbors +# (similar to lldp test) + + +# Gather facts with SNMP version 2 +- name: Gathering basic snmp facts about the device + snmp_facts: host={{ ansible_host }} version=v2c community={{ snmp_rocommunity }} + connection: local + +- name: Print SNMP LLDP information + debug: msg="{{ snmp_lldp }}" + +# Check if lldpLocalSysData is present + +- name: "Verify {{ item }} is defined" + assert: { that: "{{ snmp_lldp[item] is defined }} + and not {{ snmp_lldp[item] | search('No Such Object currently exists') }}" } + with_items: + - lldpLocChassisIdSubtype + - lldpLocChassisId + - lldpLocSysName + - lldpLocSysDesc + +- set_fact: + snmp_ports: "{{ snmp_ports|default({}) | combine({ item.key : item.value}) }}" + when: "{{ item.value.name is defined }} + and {{ item.value['name'].find('Ethernet') != -1 }}" + with_dict: "{{ snmp_interfaces }}" + +# Check if lldpLocPortTable is present for all ports +- name: "Verify lldpLocPortTable is present" + assert: { that: "{{ item.value['lldpLocPortNum'] is defined }} + and {{ item.value['lldpLocPortIdSubtype'] is defined }} + and {{ item.value['lldpLocPortId'] is defined }} + and {{ item.value['lldpLocPortDesc'] is defined }}" } + with_dict: "{{ snmp_ports }}" + +# Check if lldpLocManAddrTable is present +- name: "Verify {{ item }} is defined" + assert: { that: "{{ snmp_lldp[item] is defined }} + and not {{ snmp_lldp[item] | search('No Such Object currently exists') }}" } + with_items: + - lldpLocManAddrSubtype + - lldpLocManAddr + - lldpLocManAddrLen + - lldpLocManAddrIfSubtype + - lldpLocManAddrIfId + - lldpLocManAddrOID + +# Check if lldpRemTable is present +- set_fact: + active_intf: [] + +- name: find minigraph lldp neighbor + set_fact: + minigraph_lldp_nei: "{{ minigraph_lldp_nei|default({}) | combine({ item.key : item.value}) }}" + when: "'server' not in item.value['name'] | lower" + with_dict: minigraph_neighbors + +- name: Create list of ports with lldpRemTable data + when: "{{ item.value['lldpRemTimeMark'] is defined }} + and {{ item.value['lldpRemLocalPortNum'] is defined }} + and {{ item.value['lldpRemIndex'] is defined }} + and {{ item.value['lldpRemChassisIdSubtype'] is defined }} + and {{ item.value['lldpRemChassisId'] is defined }} + and {{ item.value['lldpRemPortIdSubtype'] is defined }} + and {{ item.value['lldpRemPortId'] is defined }} + and {{ item.value['lldpRemPortDesc'] is defined }} + and {{ item.value['lldpRemSysName'] is defined }} + and {{ item.value['lldpRemSysDesc'] is defined }} + and {{ item.value['lldpRemSysCapSupported'] is defined }} + and {{ item.value['lldpRemSysCapEnabled'] is defined }}" + set_fact: + active_intf: "{{ active_intf + [item] }}" + with_dict: "{{ snmp_interfaces }}" + +- debug: + msg: "Found {{ active_intf | length }} Ifs with lldpRemTable data\n + Minigraph contains {{ minigraph_lldp_nei | length }} neighbors" + +- name: Verify lldpRemTable is available on most interfaces + assert: {that: "{{ minigraph_lldp_nei | length }} > {{ active_intf | length * 0.8 }}" } + + +# Check if lldpRemManAddrTable is present +- set_fact: + active_intf: [] + +- name: Create list of ports with lldpRemManAddr data + when: "{{ item.value['lldpRemManAddrSubtype'] is defined }} + and {{ item.value['lldpRemManAddr'] is defined }} + and {{ item.value['lldpRemManAddr'] is defined }} + and {{ item.value['lldpRemManAddrIfSubtype'] is defined }} + and {{ item.value['lldpRemManAddrIfId'] is defined }} + and {{ item.value['lldpRemManAddrOID'] is defined }}" + set_fact: + active_intf: "{{ active_intf + [item] }}" + with_dict: "{{ snmp_interfaces }}" + +- debug: + msg: "Found {{ active_intf | length }} Ifs with lldpRemManAddr data\n + Minigraph contains {{ minigraph_lldp_nei | length }} neighbors" + +- name: Verify lldpRemManAddr is available on most interfaces + assert: {that: "{{ minigraph_lldp_nei | length }} > {{ active_intf | length * 0.8 }}" } \ No newline at end of file