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 ()
1213Host = _args .host
14+ RespectImp = _args .r
15+
1316
1417# get base folder
1518os .chdir (os .path .dirname (os .path .realpath (__file__ )))
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}
5154StatusOK = ('ok' , 'true' , 'yes' , 'on' , 'online' , 'spunup' , 'full' , 'ready' , 'enabled' , 'presence' , 'non-raid' , 'nonraid' , 0 )
52- StatusWarning = ('noncritical' )
55+ StatusWarning = ('noncritical' , 'removed' , 'foreign' , 'offline' )
5356StatusCritical = ('fail' , 'failed' , 'critical' , 'nonrecoverable' , 'notredundant' , 'lost' , 'degraded' , 'redundancyoffline' )
5457StatusMap = {
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
6164SnmpCommand = NamedTuple ('SnmpCommand' , [('command' , str ), ('host' , str ), ('oid' , str ), ('mib_dir' , str ), ('mib' , str ), ('value_only' , bool )])
6265SnmpResult = 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
6669def 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
9497def 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
138145for 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