2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
10 # | Copyright Mathias Kettner 2013 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
27 # <<ucs_bladecenter_if:sep(9)>>>
28 # fcStats Dn sys/switch-A/slot-1/switch-fc/port-37/stats BytesRx 2411057759048 BytesTx 1350394110752 Suspect no
29 # fcStats Dn sys/switch-A/slot-1/switch-fc/port-40/stats BytesRx 0 BytesTx 0 Suspect no
30 # fcErrStats Dn sys/switch-B/slot-1/switch-fc/port-47/err-stats CrcRx 0 DiscardRx 0 DiscardTx 0
31 # fcErrStats Dn sys/switch-B/slot-1/switch-fc/port-48/err-stats CrcRx 0 DiscardRx 0 DiscardTx 0
32 # fabricFcSanEp Dn fabric/san/A/phys-slot-1-port-40 EpDn sys/switch-A/slot-1/switch-fc/port-40 AdminState disabled OperState up
33 # fabricFcSanEp Dn fabric/san/A/phys-slot-1-port-41 EpDn sys/switch-A/slot-1/switch-fc/port-41 AdminState disabled OperState up
37 # 'sys/switch-A/slot-1/switch-fc/port-38':
38 # {'AdminState': 'enabled',
39 # 'BytesRx': '51789849113704',
40 # 'BytesTx': '15914991789936',
44 # 'EpDn': 'sys/switch-A/slot-1/switch-fc/port-38',
46 # 'PacketsRx': '26771306796',
47 # 'PacketsTx': '8735571946',
55 # 'sys/switch-A/slot-1/switch-ether/port-18':
56 # {'AdminState': 'enabled',
57 # 'Dn': 'fabric/lan/A/pc-1/ep-slot-1-port-18',
58 # 'EpDn': 'sys/switch-A/slot-1/switch-ether/port-18',
63 # 'etherRxStats': {'BroadcastPackets': '116544272',
64 # 'Dn': 'sys/switch-A/slot-1/switch-ether/port-18/rx-stats',
65 # 'MulticastPackets': '560456841',
66 # 'TotalBytes': '53066141169147',
67 # 'UnicastPackets': '138412352259'},
68 # 'etherTxStats': {'BroadcastPackets': '4922247',
69 # 'Dn': 'sys/switch-A/slot-1/switch-ether/port-18/tx-stats',
70 # 'MulticastPackets': '82743790',
71 # 'TotalBytes': '79420242621595',
72 # 'UnicastPackets': '135007642584'},
74 # 'sys/switch-A/slot-1/switch-ether/port-2':
75 # {'AdminState': 'enabled',
76 # 'Dn': 'fabric/server/sw-A/pc-1025/ep-slot-1-port-2',
77 # 'EpDn': 'sys/switch-A/slot-1/switch-ether/port-2',
82 # 'etherErrStats': {'Dn': 'sys/switch-A/slot-1/switch-ether/port-2/err-stats',
85 # 'etherRxStats': {'BroadcastPackets': '50432549',
86 # 'Dn': 'sys/switch-A/slot-1/switch-ether/port-2/rx-stats',
87 # 'MulticastPackets': '80349542',
88 # 'TotalBytes': '50633308808192',
89 # 'UnicastPackets': '53535107978'},
90 # 'etherTxStats': {'BroadcastPackets': '4892153',
91 # 'Dn': 'sys/switch-A/slot-1/switch-ether/port-2/tx-stats',
92 # 'MulticastPackets': '328878878',
93 # 'TotalBytes': '97004901202254',
94 # 'UnicastPackets': '79555260499'},
95 # 'portchannel': {'AdminState': 'enabled',
96 # 'Dn': 'fabric/server/sw-A/pc-1025',
97 # 'OperSpeed': '10gbps',
103 # We need to fill this structure
108 # [], # 3 ifHighSpeed .. 1000 means 1Gbit
109 # [], # 4 ifOperStatus 4
110 # [], # 5 ifHCInOctets 5
111 # [], # 6 ifHCInUcastPkts 6
112 # [], # 7 ifHCInMulticastPkts 7
113 # [], # 8 ifHCInBroadcastPkts 8
114 # [], # 9 ifInDiscards 9
115 # [], # 10 ifInErrors 10
116 # [], # 11 ifHCOutOctets 11
117 # [], # 12 ifHCOutUcastPkts 12
118 # [], # 13 ifHCOutMulticastPkts 13
119 # [], # 14 ifHCOutBroadcastPkts 14
120 # [], # 15 ifOutDiscards 15
121 # [], # 16 ifOutErrors 16
122 # [], # 17 ifOutQLen 17
123 # [], # 18 ifAlias 18
124 # [], # 19 ifPhysAddress 19
127 # Specify which values are to put into the resulting interface
130 # a list of class and field
131 2: "6", # This means Ethernet. We should set the real type here
132 # if.include does not support the interface type 56
133 5: [ ("fcStats", "BytesRx") ],
134 6: [ ("fcStats", "PacketsRx") ],
135 9: [ ("fcErrStats", "DiscardRx") ],
136 10: [ ("fcErrStats", "Rx"), ("fcErrStats", "CrcRx") ],
138 11: [ ("fcStats", "BytesTx") ],
139 12: [ ("fcStats", "PacketsTx") ],
140 15: [ ("fcErrStats", "DiscardTx") ],
141 16: [ ("fcErrStats", "Tx") ]
145 5: [ ("etherRxStats", "TotalBytes") ],
146 6: [ ("etherRxStats", "UnicastPackets") ],
147 7: [ ("etherRxStats", "MulticastPackets") ],
148 8: [ ("etherRxStats", "BroadcastPackets") ],
149 10: [ ("etherErrStats", "Rcv") ],
151 11: [ ("etherTxStats", "TotalBytes") ],
152 12: [ ("etherTxStats", "UnicastPackets") ],
153 13: [ ("etherTxStats", "MulticastPackets") ],
154 14: [ ("etherTxStats", "BroadcastPackets") ],
155 15: [ ("etherErrStats", "OutDiscard") ],
159 5: [ ("etherRxStats", "TotalBytes") ],
160 6: [ ("etherRxStats", "UnicastPackets") ],
161 7: [ ("etherRxStats", "MulticastPackets") ],
162 8: [ ("etherRxStats", "BroadcastPackets") ],
163 10: [ ("etherErrStats", "Rcv") ],
165 11: [ ("etherTxStats", "TotalBytes") ],
166 12: [ ("etherTxStats", "UnicastPackets") ],
167 13: [ ("etherTxStats", "MulticastPackets") ],
168 14: [ ("etherTxStats", "BroadcastPackets") ],
169 15: [ ("etherErrStats", "OutDiscard") ],
173 def parse_ucs_bladecenter_if(info
):
174 data
= ucs_bladecenter_convert_info(info
)
176 fc_interfaces
= _parse_fc_interfaces(data
)
177 eth_interfaces
= _parse_eth_interfaces(data
)
178 icnt_interfaces
= _parse_icnt_interfaces(data
)
182 for what
, group_prefix
, interfaces
, item_template
in [
183 ("fibrechannel", "Fibrechannel-Group", fc_interfaces
, "Slot %s FC-Switch %s Port %s"),
184 ("ethernet", "Ethernet-Group", eth_interfaces
, "Slot %s Switch %s Port %s"),
185 ("interconnect", "Interconnect-Group", icnt_interfaces
, "Slot %s IC-Switch %s Port %s"),
188 for index
, (_name
, values
) in enumerate(interfaces
.iteritems()):
189 item
= item_template
% ( values
.get("SlotId"),
190 values
.get("SwitchId"),
191 values
.get("PortId") )
193 converted
.append(entry
)
195 # Interfaces in portchannels are automatically grouped by within if.include
196 # Grouped interfaces are identified when the type of the ifIndex field is a tuple
197 # Speed and OperState
198 if "portchannel" in values
:
199 entry
[0] = (group_prefix
+ " " + values
["portchannel"].get("Name", values
["portchannel"].get("PortId", "")),\
200 str(last_index
+ index
))
201 speed
= values
["portchannel"].get("AdminSpeed") or values
["portchannel"].get("OperSpeed")
202 # It looks like that the AdminSpeed of a portchannel is the speed of one member
203 # speed = str(int(float(speed.replace("gbps", "000000000")) / values["portchannel"]["members"]))
204 entry
[3] = speed
.replace("gbps", "000000000")
205 operStatus
= values
["portchannel"].get("AdminState", "disabled") == "enabled" and \
206 values
["portchannel"].get("OperState", "down") == "up"
208 entry
[0] = str(last_index
+ index
)
209 entry
[3] = values
.get("AdminSpeed", "").replace("gbps", "000000000")
210 operStatus
= values
.get("AdminState", "disabled") == "enabled" and \
211 values
.get("OperState", "down") == "up"
214 entry
[4] = "1" if operStatus
else "2"
215 entry
[18] = item
# ifAlias
216 entry
[19] = '' # MAC address not known here
217 for table_index
, ctr_keys
in tableindex
.get(what
).items():
219 # On summing keys there is a possiblility to overlook some counter wraps.
220 # Right now, it's only Recv-Errors (therefore unlikely). We can live with that
221 if type(ctr_keys
) != list: # fixed value
224 for ctr_class
, ctr_key
in ctr_keys
: # compute value from data
226 ctr_value
+= int(values
[ctr_class
].get(ctr_key
, "0"))
228 ctr_value
+= int(values
.get(ctr_key
, "0"))
229 entry
[table_index
] = str(ctr_value
)
231 last_index
+= index
+ 1
236 def _parse_fc_interfaces(data
):
239 for key
, values
in data
.get("fabricFcSanEp", {}).items():
240 fc_interfaces
.setdefault(values
["EpDn"], {}).update(values
)
242 # TODO: fabricFcSanPc
243 # TODO: fabricFcSanPcEp
244 for what
, cut
in [ ("fcStats", 6),
245 ("fcErrStats", 10) ]:
247 for key
, values
in data
[what
].items():
249 if fc_name
in fc_interfaces
:
250 fc_interfaces
[fc_name
].setdefault(what
, {})
251 fc_interfaces
[key
[:-cut
]][what
].update(values
)
256 def _parse_eth_interfaces(data
):
258 for key
, values
in data
.get("fabricEthLanEp", {}).items():
259 eth_interfaces
.setdefault(values
["EpDn"], {}).update(values
)
261 # Get info for each portchannel
263 for key
, values
in data
.get("fabricEthLanPc", {}).items():
264 eth_pc_info
[key
] = values
266 # Ethernet-Portchannel Members
267 for key
, values
in data
.get("fabricEthLanPcEp", {}).items():
268 pc_name
= "/".join(values
.get("Dn").split("/")[:-1])
269 values
["portchannel"] = eth_pc_info
[pc_name
]
270 eth_pc_info
[pc_name
].setdefault("members", 0)
271 eth_pc_info
[pc_name
]["members"] += 1
272 eth_interfaces
.setdefault(values
["EpDn"], {}).update(values
)
274 for what
, cut
in [ ("etherRxStats", 9),
276 ("etherErrStats", 10) ]:
278 for key
, values
in data
[what
].items():
279 eth_name
= key
[:-cut
]
280 if eth_name
in eth_interfaces
:
281 eth_interfaces
[eth_name
].setdefault(what
, {})
282 eth_interfaces
[key
[:-cut
]][what
].update(values
)
284 return eth_interfaces
287 def _parse_icnt_interfaces(data
):
289 for key
, values
in data
.get("fabricDceSwEp", {}).items():
290 icnt_interfaces
.setdefault(values
["EpDn"], {}).update(values
)
292 for key
, values
in data
.get("fabricDceSwSrvEp", {}).items():
293 icnt_interfaces
.setdefault(values
["EpDn"], {}).update(values
)
295 # Get info for each portchannel
297 for key
, values
in data
.get("fabricDceSwSrvPc", {}).items():
298 icnt_pc_info
[key
] = values
300 # Interconnect-Portchannel Members
301 for key
, values
in data
.get("fabricDceSwSrvPcEp", {}).items():
302 if len(values
.get("Dn").split("/")[:-1]) == 4:
303 pc_name
= "/".join(values
.get("Dn").split("/")[:-1])
305 pc_name
= "/".join(values
.get("Dn").split("/")[:-2])
306 values
["portchannel"] = icnt_pc_info
[pc_name
]
307 icnt_pc_info
[pc_name
].setdefault("members", 0)
308 icnt_pc_info
[pc_name
]["members"] += 1
309 icnt_interfaces
.setdefault(values
["EpDn"], {}).update(values
)
312 for what
, cut
in [ ("etherRxStats", 9),
314 ("etherErrStats", 10) ]:
316 for key
, values
in data
[what
].items():
317 eth_name
= key
[:-cut
]
318 if eth_name
in icnt_interfaces
:
319 icnt_interfaces
[eth_name
].setdefault(what
, {})
320 icnt_interfaces
[key
[:-cut
]][what
].update(values
)
322 return icnt_interfaces
326 def inventory_ucs_bladecenter_if(info
):
327 return inventory_if_common(info
)
330 check_info
["ucs_bladecenter_if"] = {
331 'parse_function' : parse_ucs_bladecenter_if
,
332 'inventory_function' : inventory_ucs_bladecenter_if
,
333 'check_function' : check_if_common
,
334 'service_description' : 'Interface %s',
335 'has_perfdata' : True,
337 'includes' : [ 'ucs_bladecenter.include', 'if.include' ],
338 'default_levels_variable' : 'if_default_levels',