-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprtg-custom-forti-cl.py
143 lines (112 loc) · 4.84 KB
/
prtg-custom-forti-cl.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
from pysnmp.hlapi import *
from pysnmp.entity.rfc3413.oneliner import cmdgen
import sys
import json
import re
from paepy.ChannelDefinition import CustomSensorResult
class SNMPClient:
# This is the SNMPClient constructor
def __init__(self, host, port=161, community='public'):
self.host = host
self.port = port
self.community = community
def snmpget(self, oid, *more_oids):
cmdGen = cmdgen.CommandGenerator()
errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd(
cmdgen.CommunityData(self.community),
cmdgen.UdpTransportTarget((self.host, self.port)),
oid,
*more_oids
)
# Predefine our results list
results = {}
# Check for errors and print out results
if errorIndication:
print(errorIndication)
else:
if errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex)-1] or '?'
)
)
else:
for name, val in varBinds:
results[str(val)] = str(name)
return results
def snmpwalk(self, oid):
cmdGen = cmdgen.CommandGenerator()
errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd(
cmdgen.CommunityData(self.community),
cmdgen.UdpTransportTarget((self.host, self.port)),
oid
)
# Predefine our results list
results = {}
if errorIndication:
print(errorIndication)
else:
if errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
)
)
else:
for varBindTableRow in varBindTable:
for name, val in varBindTableRow:
results[str(val)] = str(name)
return results
# find word regex function
def findWholeWord(w):
return re.compile(r'\b({0})\b'.format(w), flags=re.IGNORECASE).search
# load PRTG parameters
params = json.loads(sys.argv[1])
conn = SNMPClient(params['host'], 161, params['snmpcommv2'])
# get serial numbers of cluster members
deviceSerialsHashtable = conn.snmpget('1.3.6.1.4.1.12356.101.13.2.1.1.2.1', '1.3.6.1.4.1.12356.101.13.2.1.1.2.2')
# switch keys and values and replace oid with unit number
device = dict((v,k) for k,v in deviceSerialsHashtable.items())
device['unit1'] = device.pop('1.3.6.1.4.1.12356.101.13.2.1.1.2.1')
device['unit2'] = device.pop('1.3.6.1.4.1.12356.101.13.2.1.1.2.2')
for k,v in device.items():
device[k] = {'serial': v}
for i in device:
# construct snmp community for each cluster member
device[i]['snmpc'] = params['snmpcommv2'] + '-' + device[i]['serial']
# snmpwalk ifName OID
conn = SNMPClient(params['host'], 161, device[i]['snmpc'])
interfaces = conn.snmpwalk('1.3.6.1.2.1.31.1.1.1.1')
# cut oid to interface id
for k,v in interfaces.items():
interfaces[k] = {'ifindex': v.replace("1.3.6.1.2.1.31.1.1.1.1.","")}
# join to 'device' dict
device[i]['int'] = interfaces
# get cluster index of unit
clindex = conn.snmpget('1.3.6.1.4.1.12356.101.13.2.1.1.1.' + i.replace('unit',''))
for p in clindex.keys():
device[i].update({'clindex': str(p)})
# get hsotname
hostname = conn.snmpget('1.3.6.1.4.1.12356.101.13.2.1.1.11.1')
for p in hostname.keys():
device[i].update({'hostname': str(p)})
# get ifOperstatus for all interfaces
for p in device[i]['int'].keys():
ifstatus = conn.snmpget('1.3.6.1.2.1.2.2.1.8' + "." + device[i]['int'][p]['ifindex'])
for k,v in ifstatus.items():
device[i]['int'][p].update({'ifstatus': str(k)})
# create interface list from sensor additional parameters
iflist = params['params']
# create PRTG sensor channels
result = CustomSensorResult("Result from FortiGate Sensor " + params['host'])
for i in device:
for k in device[i]['int'].keys():
cname = device[i]['hostname'] + " " + k
if findWholeWord(k)(iflist) is not None:
if k == 'wan1' and device[i]['clIndex'] == '1':
result.add_channel(channel_name = cname, value = device[i]['int'][k]['ifstatus'], value_lookup = 'custom.lookup.forti.interfaces', primary_channel=True)
else:
result.add_channel(channel_name = cname, value = device[i]['int'][k]['ifstatus'], value_lookup = 'custom.lookup.forti.interfaces')
else:
pass
print(result.get_json_result())