-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcisco_vpc.py
executable file
·155 lines (137 loc) · 5.63 KB
/
cisco_vpc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python
#
# @descr Checks VPC status for NXOS switches
#
# @author Johan Hedberg <[email protected]>
#
import argparse
import re
import sys
from lib.cnh_nm import STATE_OK, STATE_CRIT, STATE_WARN
from lib.cnh_nm import trigger_not_ok, check_if_ok, my_snmp_walk, my_snmp_get
from lib.cnh_nm import snmpresult_to_dict
# Argument parsing
parser = argparse.ArgumentParser(description='Check VPC status for NXOS switches')
parser.add_argument('-C', metavar='<community>', required=True,
help='SNMP Community')
parser.add_argument('-H', metavar='<host>', required=True,
help='Host to check')
args = parser.parse_args()
# These oids are for the overall status
oids = [
'CISCO-VPC-MIB::cVpcPeerKeepAliveStatus',
'CISCO-VPC-MIB::cVpcPeerKeepAliveMsgSendStatus',
'CISCO-VPC-MIB::cVpcPeerKeepAliveMsgRcvrStatus',
'CISCO-VPC-MIB::cVpcPeerKeepAliveVrfName',
'CISCO-VPC-MIB::cVpcRoleStatus',
'CISCO-VPC-MIB::cVpcDualActiveDetectionStatus'
]
# These are for host-link status
oids_host_link_status = [
'CISCO-VPC-MIB::cVpcStatusHostLinkIfIndex',
'CISCO-VPC-MIB::cVpcStatusHostLinkStatus',
'CISCO-VPC-MIB::cVpcStatusHostLinkConsistencyStatus',
'CISCO-VPC-MIB::cVpcStatusHostLinkConsistencyDetail'
]
oid_t_ifmib_ifname = 'IF-MIB::ifName.{}'
status = STATE_OK
statusstr = ""
# Check VPC general status and the status of peer-links
rawdata = my_snmp_walk(args, oids)
if not rawdata:
print "OK: Switch does not implement Cisco VPC, or does not have it enabled."
sys.exit(STATE_OK)
data = snmpresult_to_dict(rawdata)
vpc_domain_ids = []
for vpc_domain in data:
vpc_domain_ids.append(vpc_domain)
vpc_data = data[vpc_domain]
# 1 = primarySecondary, 2 = primary, 3 = secondaryPrimary, 4 = secondary, 5 = noneEstablished
if int(vpc_data['cVpcRoleStatus'].value) == 5:
status, statusstr = trigger_not_ok(
status,
statusstr,
STATE_CRIT,
'VPC Domain {} no peerlinks established'.format(vpc_domain))
continue # No point in checking further
# 1 = true, 2 = false
if int(vpc_data['cVpcDualActiveDetectionStatus'].value) == 1:
status, statusstr = trigger_not_ok(
status,
statusstr,
STATE_CRIT,
'VPC Domain {} Dual active detected!'.format(vpc_domain))
# 1 = disabled, 2 = alive, 3 = peerUnreachable, 4 = aliveButDomainIdDismatch, 5 = suspendedAsISSU
# 6 = suspendedAsDestIPUnreachable, 7 = suspendedAsVRFUnusable, 8 = misconfigured
vpc_pkstatus = int(vpc_data['cVpcPeerKeepAliveStatus'].value)
if vpc_pkstatus != 2:
vpc_pkerrors = {
1: { 'state': STATE_WARN, 'txt': 'peer-link is disabled' },
3: { 'state': STATE_CRIT, 'txt': 'peers are unreachable' }, # Will probably never be checked dueto cVpcRoleStatus above
4: { 'state': STATE_CRIT, 'txt': 'peer domain ID mismatch' },
5: { 'state': STATE_WARN, 'txt': 'peer-link suspended due to ongoing ISSU' },
6: { 'state': STATE_CRIT, 'txt': 'peer-link suspended as destination IP unreachable' },
7: { 'state': STATE_CRIT, 'txt': 'peer-link suspended as VRF () is unuable'.format(vpc_data['cVpcPeerKeepAliveVrfName'].value) },
8: { 'state': STATE_CRIT, 'txt': 'peer-link is misconfigured' }
}
status, statusstr = trigger_not_ok(
status,
statusstr,
vpc_pkerrors[vpc_pkstatus]['state'],
"VPC Domain {} {}".format(vpc_domain, vpc_pkerrors[vpc_pkstatus]['txt'])
)
# 1 = success, 2 = failure
if int(vpc_data['cVpcPeerKeepAliveMsgSendStatus'].value) != 1:
status, statusstr = trigger_not_ok(
status,
statusstr,
STATE_CRIT,
'VPC Domain {} Peer-Link MsgSendStatus failure'.format(vpc_domain)
)
# 1 = success, 2 = failure
if int(vpc_data['cVpcPeerKeepAliveMsgRcvrStatus'].value) != 1:
status, statusstr = trigger_not_ok(
status,
statusstr,
STATE_CRIT,
'VPC Domain {} Peer-Link MsgRcvrStatus failure'.format(vpc_domain)
)
# Check VPC HostLink status
rawdata = my_snmp_walk(args, oids_host_link_status)
regex = re.compile(r"^[0-9]+\.")
temp = []
for rd in rawdata: # Filter out the VPC Domain, doesn't matter here
rd.oid_index = regex.sub('', rd.oid_index)
temp.append(rd)
data = snmpresult_to_dict(rawdata)
for host_link in data:
hl_data = data[host_link]
snmp_ifname = my_snmp_get(args, oid_t_ifmib_ifname.format(hl_data['cVpcStatusHostLinkIfIndex'].value))
# 1 = down, 2 = downStar (forwarding via VPC host-link), 3 = up
hl_status = int(hl_data['cVpcStatusHostLinkStatus'].value)
if hl_status == 1:
status, statusstr = trigger_not_ok(
status,
statusstr,
STATE_CRIT,
'Host-link {} down'.format(snmp_ifname.value)
)
if hl_status == 2:
status, statusstr = trigger_not_ok(
status,
statusstr,
STATE_WARN,
'Host-link {} down but forwarding via VPC peer-link'.format(snmp_ifname.value)
)
# 1 = success, 2 = failed, 3 = notApplicable
if int(hl_data['cVpcStatusHostLinkConsistencyStatus'].value) == 2:
consistency_detail = hl_data['cVpcStatusHostLinkConsistencyDetail'].value
status, statusstr = trigger_not_ok(
status,
statusstr,
STATE_CRIT,
'Host-link {} inconsistent between VPC peers ({})'.format(snmp_ifname.value, consistency_detail)
)
check_if_ok(status, statusstr)
print "OK: VPC Status, Peer-Link status is OK"
sys.exit(STATE_OK)