Skip to content

Commit 098cd34

Browse files
author
Carl Chang
committed
add respect important option
add color to status text fix issues of StatusWarning
1 parent 4312de7 commit 098cd34

File tree

2 files changed

+88
-65
lines changed

2 files changed

+88
-65
lines changed

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

check_snmp.py

Lines changed: 76 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77

88

99
_parser = argparse.ArgumentParser()
10+
_parser.add_argument('-r', help='Respect properties marked as important when other results contain errors.', action='store_true')
1011
_parser.add_argument('host', help='The host to connect to.')
1112
_args = _parser.parse_args()
1213
Host = _args.host
14+
RespectImp = _args.r
15+
1316

1417
# get base folder
1518
os.chdir(os.path.dirname(os.path.realpath(__file__)))
@@ -20,47 +23,47 @@
2023
'mib_dir': 'mibs/default:mibs/iana:mibs/ietf:mibs/dell',
2124
'mib': 'IDRAC-MIB-SMIv2',
2225
'oids': OrderedDict([
23-
('globalSystemStatus', 'Overall system status'),
24-
('systemStateProcessorDeviceStatusCombined', 'Processor status'),
25-
('memoryDeviceStatus', 'Memory status'),
26-
('physicalDiskState', 'Physical disk status'),
27-
('virtualDiskState', 'Virtual disk status'),
28-
('controllerComponentStatus', 'Storage controller status'),
29-
('coolingUnitStatus', 'Cooling status'),
30-
('temperatureProbeStatus', 'Temperature status'),
31-
('powerSupplyStatus', 'Power supply status'),
32-
('systemStateBatteryStatusCombined', 'Battery status'),
26+
('globalSystemStatus', {'description': 'Overall system status', 'important': True}),
27+
('systemStateProcessorDeviceStatusCombined', {'description': 'Processor status'}),
28+
('memoryDeviceStatus', {'description': 'Memory status'}),
29+
('physicalDiskState', {'description': 'Physical disk status'}),
30+
('virtualDiskState', {'description': 'Virtual disk status'}),
31+
('controllerComponentStatus', {'description': 'Storage controller status'}),
32+
('coolingUnitStatus', {'description': 'Cooling status'}),
33+
('temperatureProbeStatus', {'description': 'Temperature status'}),
34+
('powerSupplyStatus', {'description': 'Power supply status'}),
35+
('systemStateBatteryStatusCombined', {'description': 'Battery status'}),
3336
])
3437
},
3538
'hpe': {
3639
'mib_dir': 'mibs/default:mibs/iana:mibs/ietf:mibs/hpe',
3740
'mib': 'CPQSINFO-MIB:CPQHLTH-MIB:CPQIDA-MIB',
3841
'oids': OrderedDict([
39-
('cpqHeMibCondition', 'Overall system status'),
40-
('cpqHeResilientMemCondition', 'Memory status'),
41-
('cpqDaPhyDrvCondition', 'Physical disk status'),
42-
('cpqDaMibCondition', 'Virtual disk status'),
43-
('cpqDaCntlrCondition', 'Storage controller status'),
44-
('cpqHeThermalSystemFanStatus', 'Cooling status'),
45-
('cpqHeThermalTempStatus', 'Temperature status'),
46-
('cpqHeFltTolPowerSupplyCondition', 'Power supply status'),
47-
('cpqHeEventLogCondition', 'Integrated Management Log status'),
42+
('cpqHeMibCondition', {'description': 'Overall system status', 'important': True}),
43+
('cpqHeResilientMemCondition', {'description': 'Memory status'}),
44+
('cpqDaPhyDrvCondition', {'description': 'Physical disk status'}),
45+
('cpqDaMibCondition', {'description': 'Virtual disk status'}),
46+
('cpqDaCntlrCondition', {'description': 'Storage controller status'}),
47+
('cpqHeThermalSystemFanStatus', {'description': 'Cooling status'}),
48+
('cpqHeThermalTempStatus', {'description': 'Temperature status'}),
49+
('cpqHeFltTolPowerSupplyCondition', {'description': 'Power supply status'}),
50+
('cpqHeEventLogCondition', {'description': 'Integrated Management Log status'}),
4851
])
4952
}
5053
}
5154
StatusOK = ('ok', 'true', 'yes', 'on', 'online', 'spunup', 'full', 'ready', 'enabled', 'presence', 'non-raid', 'nonraid', 0)
52-
StatusWarning = ('noncritical')
55+
StatusWarning = ('noncritical', 'removed', 'foreign', 'offline')
5356
StatusCritical = ('fail', 'failed', 'critical', 'nonrecoverable', 'notredundant', 'lost', 'degraded', 'redundancyoffline')
5457
StatusMap = {
55-
0: {'status': 'ok', 'color': '\033[32m{}\033[00m'}, # green
56-
1: {'status': 'warning', 'color': '\033[33m{}\033[00m'}, # orange
57-
2: {'status': 'critical', 'color': '\033[31m{}\033[00m'}, # red
58-
3: {'status': 'unknown', 'color': '\033[37m{}\033[00m'}, # lightgrey
58+
0: {'status': 'ok', 'color': '\033[32m{}\033[00m', 'severity': 0}, # green
59+
1: {'status': 'warning', 'color': '\033[33m{}\033[00m', 'severity': 2}, # orange
60+
2: {'status': 'critical', 'color': '\033[31m{}\033[00m', 'severity': 3}, # red
61+
3: {'status': 'unknown', 'color': '\033[37m{}\033[00m', 'severity': 1}, # lightgrey
5962
}
6063

6164
SnmpCommand = NamedTuple('SnmpCommand', [('command', str), ('host', str), ('oid', str), ('mib_dir', str), ('mib', str), ('value_only', bool)])
6265
SnmpResult = NamedTuple('SnmpResult', [('stdout', str), ('stderr', str)])
63-
CombinedStatus = NamedTuple('CombinedStatus', [('ok', int), ('warning', int), ('critical', int), ('unknown', int)])
66+
CombinedStatus = NamedTuple('CombinedStatus', [('code', int), ('formatted', str)])
6467

6568

6669
def run(cmd: SnmpCommand) -> SnmpResult:
@@ -80,44 +83,48 @@ def print_and_exit(msg: str, code: int):
8083
sys.exit(code)
8184

8285

83-
def status_converter(status: any) -> str:
86+
def status_converter(status: any) -> int:
8487
if status in StatusOK:
85-
return 'ok'
88+
return 0 # ok
8689
elif status in StatusWarning:
87-
return 'warning'
90+
return 1 # warning
8891
elif status in StatusCritical:
89-
return 'critical'
92+
return 2 # critical
9093
else:
91-
return 'unknown'
94+
return 3 # unknown
9295

9396

9497
def multi_status_converter(status_str: str) -> CombinedStatus:
95-
ok, warning, critical, unknown = 0, 0, 0, 0
98+
combined, formatted = 0, ''
9699
for s in status_str.splitlines():
97-
status = status_converter(s)
98-
if status == 'ok':
99-
ok += 1
100-
elif status == 'warning':
101-
warning += 1
102-
elif status == 'critical':
103-
critical += 1
104-
else:
105-
unknown += 1
106-
107-
return CombinedStatus(ok, warning, critical, unknown)
108-
109-
110-
def status_merger(ok: int, warning: int, critical: int, unknown: int) -> int:
111-
if critical > 0:
112-
return 2
113-
elif warning > 0:
114-
return 1
115-
elif unknown > 0:
116-
return 3
117-
elif ok > 0:
118-
return 0
100+
formatted += s + '|'
101+
combined = update_status_code(combined, status_converter(s))
102+
103+
if len(formatted) > 1: formatted = formatted[:-1]
104+
return CombinedStatus(combined, formatted)
105+
106+
107+
# def status_merger(ok: int, warning: int, critical: int, unknown: int) -> int:
108+
# if critical > 0:
109+
# return 2
110+
# elif warning > 0:
111+
# return 1
112+
# elif unknown > 0:
113+
# return 3
114+
# elif ok > 0:
115+
# return 0
116+
# else:
117+
# return 3
118+
119+
120+
def update_status_code(old_status_code: int, status_code: int) -> int:
121+
if status_code not in StatusMap: print_and_exit('Unknown status code.', 3)
122+
if old_status_code not in StatusMap: return status_code
123+
124+
if StatusMap[old_status_code]['severity'] < StatusMap[status_code]['severity']:
125+
return status_code
119126
else:
120-
return 3
127+
return old_status_code
121128

122129

123130
# execution
@@ -134,25 +141,29 @@ def status_merger(ok: int, warning: int, critical: int, unknown: int) -> int:
134141
print_and_exit('Unknown vendor information.', 3)
135142

136143

137-
combinedOk, combinedWarning, combinedCritical, combinedUnknown, exitCode = 0, 0, 0, 0, 3
144+
exitCode, exitCodeImp = -1, -1
138145
for oid in Config[Vendor]['oids']:
139146
vendor = Config[Vendor]
140147
mib_dir = vendor['mib_dir']
141148
mib = vendor['mib']
142-
desc = vendor['oids'][oid]
143-
result = run(SnmpCommand('snmpwalk', Host, oid, mib_dir, mib, True))
149+
desc = vendor['oids'][oid]['description']
150+
imp = vendor['oids'][oid].get('important') is True
144151

152+
result = run(SnmpCommand('snmpwalk', Host, oid, mib_dir, mib, True))
145153
cs = multi_status_converter(result.stdout)
146-
combinedOk += cs.ok
147-
combinedWarning += cs.warning
148-
combinedCritical += cs.critical
149-
combinedUnknown += cs.unknown
154+
if imp: exitCodeImp = update_status_code(exitCodeImp, cs.code)
155+
exitCode = update_status_code(exitCode, cs.code)
150156

151-
merged_status = StatusMap[status_merger(cs.ok, cs.warning, cs.critical, cs.unknown)]
152-
print('{desc}: {status}'.format(desc=desc, status=merged_status['color'].format(merged_status['status'])))
157+
result_status = StatusMap[cs.code]
158+
print('{desc}: {status} ({formatted})'.format(desc=desc,
159+
status=result_status['color'].format(result_status['status']),
160+
formatted=cs.formatted))
153161

162+
# what if there is no important in Config?
163+
if RespectImp and exitCodeImp > -1:
164+
sys.exit(exitCodeImp)
165+
else:
166+
sys.exit(exitCode)
154167

155-
exitCode = status_merger(combinedOk, combinedWarning, combinedCritical, combinedUnknown)
156-
sys.exit(exitCode)
157168
# print_and_exit('Query completed.', exitCode)
158169

0 commit comments

Comments
 (0)