Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 228 additions & 0 deletions ansible/library/snmp_facts.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,45 @@ 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 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"

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

self.lldpLocManAddrSubtype = dp + "1.0.8802.1.1.2.1.3.8.1.1" # + .man addr
self.lldpLocManAddr = dp + "1.0.8802.1.1.2.1.3.8.1.2" # + .man addr
self.lldpLocManAddrLen = dp + "1.0.8802.1.1.2.1.3.8.1.3" # + .man addr
self.lldpLocManAddrIfSubtype = dp + "1.0.8802.1.1.2.1.3.8.1.4" # + .man addr
self.lldpLocManAddrIfId = dp + "1.0.8802.1.1.2.1.3.8.1.5" # + .man addr
self.lldpLocManAddrOID = dp + "1.0.8802.1.1.2.1.3.8.1.6" # + .man addr

# From lldpRemTable
self.lldpRemTimeMark = dp + "1.0.8802.1.1.2.1.4.1.1.1" # + .ifindex
self.lldpRemLocalPortNum = dp + "1.0.8802.1.1.2.1.4.1.1.2" # + .ifindex
self.lldpRemIndex = dp + "1.0.8802.1.1.2.1.4.1.1.3" # + .ifindex
self.lldpRemChassisIdSubtype = dp + "1.0.8802.1.1.2.1.4.1.1.4" # + .ifindex
self.lldpRemChassisId = dp + "1.0.8802.1.1.2.1.4.1.1.5" # + .ifindex
self.lldpRemPortIdSubtype = dp + "1.0.8802.1.1.2.1.4.1.1.6" # + .ifindex
self.lldpRemPortId = dp + "1.0.8802.1.1.2.1.4.1.1.7" # + .ifindex
self.lldpRemPortDesc = dp + "1.0.8802.1.1.2.1.4.1.1.8" # + .ifindex
self.lldpRemSysName = dp + "1.0.8802.1.1.2.1.4.1.1.9" # + .ifindex
self.lldpRemSysDesc = dp + "1.0.8802.1.1.2.1.4.1.1.10" # + .ifindex
self.lldpRemSysCapSupported = dp + "1.0.8802.1.1.2.1.4.1.1.11" # + .ifindex
self.lldpRemSysCapEnabled = dp + "1.0.8802.1.1.2.1.4.1.1.12" # + .ifindex

# From lldpRemManAddrTable
self.lldpRemManAddrSubtype = dp + "1.0.8802.1.1.2.1.4.2.1.1" # + .ifindex + .man addr
self.lldpRemManAddr = dp + "1.0.8802.1.1.2.1.4.2.1.2" # + .ifindex + .man addr
self.lldpRemManAddrIfSubtype = dp + "1.0.8802.1.1.2.1.4.2.1.3" # + .ifindex + .man addr
self.lldpRemManAddrIfId = dp + "1.0.8802.1.1.2.1.4.2.1.4" # + .ifindex + .man addr
self.lldpRemManAddrOID = dp + "1.0.8802.1.1.2.1.4.2.1.5" # + .ifindex + .man addr

# From Dell Private MIB
self.ChStackUnitCpuUtil5sec = dp + "1.3.6.1.4.1.6027.3.10.1.2.9.1.2.1"

Expand Down Expand Up @@ -480,6 +519,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('.')[11:])
results['snmp_lldp']['lldpLocManAddrSubtype'] = current_val
if v.lldpLocManAddr in current_oid:
address = '.'.join(current_oid.split('.')[11:])
results['snmp_lldp']['lldpLocManAddr'] = current_val
if v.lldpLocManAddrLen in current_oid:
address = '.'.join(current_oid.split('.')[11:])
results['snmp_lldp']['lldpLocManAddrLen'] = current_val
if v.lldpLocManAddrIfSubtype in current_oid:
address = '.'.join(current_oid.split('.')[11:])
results['snmp_lldp']['lldpLocManAddrIfSubtype'] = current_val
if v.lldpLocManAddrIfId in current_oid:
address = '.'.join(current_oid.split('.')[11:])
results['snmp_lldp']['lldpLocManAddrIfId'] = current_val
if v.lldpLocManAddrOID in current_oid:
address = '.'.join(current_oid.split('.')[11:])
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.rsplit('.', 1)[-1])
results['snmp_interfaces'][ifIndex]['lldpRemTimeMark'] = current_val
if v.lldpRemLocalPortNum in current_oid:
ifIndex = int(current_oid.rsplit('.', 1)[-1])
results['snmp_interfaces'][ifIndex]['lldpRemLocalPortNum'] = current_val
if v.lldpRemIndex in current_oid:
ifIndex = int(current_oid.rsplit('.', 1)[-1])
results['snmp_interfaces'][ifIndex]['lldpRemIndex'] = current_val
if v.lldpRemChassisIdSubtype in current_oid:
ifIndex = int(current_oid.rsplit('.', 1)[-1])
results['snmp_interfaces'][ifIndex]['lldpRemChassisIdSubtype'] = current_val
if v.lldpRemChassisId in current_oid:
ifIndex = int(current_oid.rsplit('.', 1)[-1])
results['snmp_interfaces'][ifIndex]['lldpRemChassisId'] = current_val
if v.lldpRemPortIdSubtype in current_oid:
ifIndex = int(current_oid.rsplit('.', 1)[-1])
results['snmp_interfaces'][ifIndex]['lldpRemPortIdSubtype'] = current_val
if v.lldpRemPortId in current_oid:
ifIndex = int(current_oid.rsplit('.', 1)[-1])
results['snmp_interfaces'][ifIndex]['lldpRemPortId'] = current_val
if v.lldpRemPortDesc in current_oid:
ifIndex = int(current_oid.rsplit('.', 1)[-1])
results['snmp_interfaces'][ifIndex]['lldpRemPortDesc'] = current_val
if v.lldpRemSysName in current_oid:
ifIndex = int(current_oid.rsplit('.', 1)[-1])
results['snmp_interfaces'][ifIndex]['lldpRemSysName'] = current_val
if v.lldpRemSysDesc in current_oid:
ifIndex = int(current_oid.rsplit('.', 1)[-1])
results['snmp_interfaces'][ifIndex]['lldpRemSysDesc'] = current_val
if v.lldpRemSysCapSupported in current_oid:
ifIndex = int(current_oid.rsplit('.', 1)[-1])
results['snmp_interfaces'][ifIndex]['lldpRemSysCapSupported'] = current_val
if v.lldpRemSysCapEnabled in current_oid:
ifIndex = int(current_oid.rsplit('.', 1)[-1])
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('.')[11])
address = '.'.join(current_oid.split('.')[12:])
results['snmp_interfaces'][ifIndex]['lldpRemManAddrSubtype'] = current_val
if v.lldpRemManAddr in current_oid:
ifIndex = int(current_oid.split('.')[11])
address = '.'.join(current_oid.split('.')[12:])
results['snmp_interfaces'][ifIndex]['lldpRemManAddr'] = current_val
if v.lldpRemManAddrIfSubtype in current_oid:
ifIndex = int(current_oid.split('.')[11])
address = '.'.join(current_oid.split('.')[12:])
results['snmp_interfaces'][ifIndex]['lldpRemManAddrIfSubtype'] = current_val
if v.lldpRemManAddrIfId in current_oid:
ifIndex = int(current_oid.split('.')[11])
address = '.'.join(current_oid.split('.')[12:])
results['snmp_interfaces'][ifIndex]['lldpRemManAddrIfId'] = current_val
if v.lldpRemManAddrOID in current_oid:
ifIndex = int(current_oid.split('.')[11])
address = '.'.join(current_oid.split('.')[12:])
results['snmp_interfaces'][ifIndex]['lldpRemManAddrOID'] = current_val

errorIndication, errorStatus, errorIndex, varTable = cmdGen.nextCmd(
snmp_auth,
cmdgen.UdpTransportTarget((m_args['host'], 161)),
Expand Down
3 changes: 3 additions & 0 deletions ansible/roles/test/tasks/snmp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
112 changes: 112 additions & 0 deletions ansible/roles/test/tasks/snmp/lldp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# 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') }}" }
Copy link
Copy Markdown
Contributor

@qiluo-msft qiluo-msft Aug 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add one level indentation before 'and not'? #Closed

with_items:
- lldpLocChassisIdSubtype
- lldpLocChassisId
- lldpLocSysName
- lldpLocSysDesc

# Check if lldpLocManAddr 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') }}" }
Copy link
Copy Markdown
Contributor

@qiluo-msft qiluo-msft Aug 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same #Closed

with_items:
- lldpLocManAddrSubtype
- lldpLocManAddr
- lldpLocManAddrLen
- lldpLocManAddrIfSubtype
- lldpLocManAddrIfId
- lldpLocManAddrOID

# Check if lldpLocPortTable is present
- fail:
msg: "lldpLocPortTable data missing for interface {{ item.key }}"
when: "{{ item.value.description | match('^Ethernet') }}
and ( {{ item.value['lldpLocPortNum'] is not defined }}
Copy link
Copy Markdown
Contributor

@qiluo-msft qiluo-msft Aug 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same #Closed

or {{ item.value['lldpLocPortIdSubtype'] is not defined }}
or {{ item.value['lldpLocPortId'] is not defined }}
or {{ item.value['lldpLocPortDesc'] is not defined }} )"
with_dict: "{{ snmp_interfaces }}"

# 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 }}
Copy link
Copy Markdown
Contributor

@qiluo-msft qiluo-msft Aug 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same #Closed

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 * 0.8 }} > {{ active_intf | length }}" }

# 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 }}
Copy link
Copy Markdown
Contributor

@qiluo-msft qiluo-msft Aug 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same #Closed

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"
Copy link
Copy Markdown
Contributor

@qiluo-msft qiluo-msft Aug 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same #Closed


- name: Verify lldpRemManAddr is available on most interfaces
Copy link
Copy Markdown
Contributor

@qiluo-msft qiluo-msft Aug 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we test lldpRemManAddr is available on all interfaces? #Closed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taking into consideration that in lldp test we are satisfied with lldp data awailable on 80% of the interfaces, demanding more of the same data here is questionable.
https://github.com/Azure/sonic-mgmt/blob/master/ansible/roles/test/tasks/lldp.yml#L25
I think the intent was to prevent failures caused by testbed troubles - some VMs being down/not sending lldp...

assert: {that: "{{ minigraph_lldp_nei | length * 0.8 }} > {{ active_intf | length }}" }