-
Notifications
You must be signed in to change notification settings - Fork 38
/
example_agent.py
executable file
·229 lines (206 loc) · 6.62 KB
/
example_agent.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#!/usr/bin/env python
#
# python-netsnmpagent example agent
#
# Copyright (c) 2013 Pieter Hollants <pieter@hollants.com>
# Licensed under the GNU Public License (GPL) version 3
#
#
# This is an example of a SNMP sub-agent using the AgentX protocol
# to connect to a master agent (snmpd), extending its MIB with the
# information from the included EXAMPLE-MIB.tx.
#
# To run, net-snmp must be installed and snmpd must have as minimal
# configuration:
#
# master agentx
#
# snmpd must be started first, then this agent must be started as root
# (because of the AgentX socket under /var/run/agentx/master).
#
# Then, from a separate console, you can run eg.:
#
# snmpwalk -v 2c -c public -M+. localhost EXAMPLE-MIB::exampleMIB
#
# If you wish to test setting values as well, your snmpd.conf needs a
# line like this:
#
# rwcommunity <secret> 127.0.0.1
#
# Then you can try something like:
#
# snmpset -v 2c -c <secret> -M+. localhost \
# EXAMPLE-MIB::exampleInteger i 0
#
import sys, os, signal
import optparse
import pprint
import netsnmpagent
prgname = sys.argv[0]
# Process command line arguments
parser = optparse.OptionParser()
parser.add_option(
"-m",
"--mastersocket",
dest="mastersocket",
help="Sets the path to the master agent's AgentX unix domain socket",
default="/var/run/agentx/master"
)
parser.add_option(
"-p",
"--persistencedir",
dest="persistencedir",
help="Sets the path to the persistence directory",
default="/var/lib/net-snmp"
)
(options, args) = parser.parse_args()
# Get terminal width for usage with pprint
rows,columns = os.popen("stty size", "r").read().split()
# First, create an instance of the netsnmpAgent class. We specify the
# fully-qualified path to EXAMPLE-MIB.txt ourselves here, so that you
# don't have to copy the MIB to /usr/share/snmp/mibs.
agent = netsnmpagent.netsnmpAgent(
AgentName = "ExampleAgent",
MasterSocket = options.mastersocket,
PersistenceDir = options.persistencedir,
MIBFiles = [ os.path.abspath(os.path.dirname(sys.argv[0])) +
"/EXAMPLE-MIB.txt" ]
)
# Then we create all SNMP scalar variables we're willing to serve.
exampleInteger = agent.Integer32(
oidstr = "EXAMPLE-MIB::exampleInteger"
)
exampleIntegerContext1 = agent.Integer32(
oidstr = "EXAMPLE-MIB::exampleInteger",
context = "context1",
initval = 200,
)
exampleIntegerRO = agent.Integer32(
oidstr = "EXAMPLE-MIB::exampleIntegerRO",
writable = False
)
exampleUnsigned = agent.Unsigned32(
oidstr = "EXAMPLE-MIB::exampleUnsigned"
)
exampleUnsignedRO = agent.Unsigned32(
oidstr = "EXAMPLE-MIB::exampleUnsignedRO",
writable = False
)
exampleCounter32 = agent.Counter32(
oidstr = "EXAMPLE-MIB::exampleCounter32"
)
exampleCounter32Context2 = agent.Counter32(
oidstr = "EXAMPLE-MIB::exampleCounter32",
context = "context2",
initval = pow(2,32) - 10,
)
exampleCounter64Context2 = agent.Counter64(
oidstr = "EXAMPLE-MIB::exampleCounter64",
context = "context2",
initval = pow(2,64) - 10,
)
exampleCounter64 = agent.Counter64(
oidstr = "EXAMPLE-MIB::exampleCounter64"
)
exampleTimeTicks = agent.TimeTicks(
oidstr = "EXAMPLE-MIB::exampleTimeTicks"
)
exampleIpAddress = agent.IpAddress(
oidstr = "EXAMPLE-MIB::exampleIpAddress",
initval="127.0.0.1"
)
exampleOctetString = agent.OctetString(
oidstr = "EXAMPLE-MIB::exampleOctetString",
initval = "Hello World"
)
exampleDisplayString = agent.DisplayString(
oidstr = "EXAMPLE-MIB::exampleDisplayString",
initval = "Nice to meet you"
)
# Create the first table
firstTable = agent.Table(
oidstr = "EXAMPLE-MIB::firstTable",
indexes = [
agent.DisplayString()
],
columns = [
(2, agent.DisplayString("Unknown place")),
(3, agent.Integer32(0))
],
counterobj = agent.Unsigned32(
oidstr = "EXAMPLE-MIB::firstTableNumber"
)
)
# Add the first table row
firstTableRow1 = firstTable.addRow([agent.DisplayString("aa")])
firstTableRow1.setRowCell(2, agent.DisplayString("Prague"))
firstTableRow1.setRowCell(3, agent.Integer32(20))
# Add the second table row
firstTableRow2 = firstTable.addRow([agent.DisplayString("ab")])
firstTableRow2.setRowCell(2, agent.DisplayString("Barcelona"))
firstTableRow2.setRowCell(3, agent.Integer32(28))
# Add the third table row
firstTableRow3 = firstTable.addRow([agent.DisplayString("bb")])
firstTableRow3.setRowCell(3, agent.Integer32(18))
# Create the second table
secondTable = agent.Table(
oidstr = "EXAMPLE-MIB::secondTable",
indexes = [
agent.Integer32()
],
columns = [
(2, agent.DisplayString("Unknown interface")),
(3, agent.Unsigned32())
],
counterobj = agent.Unsigned32(
oidstr = "EXAMPLE-MIB::secondTableNumber"
)
)
# Add the first table row
secondTableRow1 = secondTable.addRow([agent.Integer32(1)])
secondTableRow1.setRowCell(2, agent.DisplayString("foo0"))
secondTableRow1.setRowCell(3, agent.Unsigned32(5030))
# Add the second table row
secondTableRow2 = secondTable.addRow([agent.Integer32(2)])
secondTableRow2.setRowCell(2, agent.DisplayString("foo1"))
secondTableRow2.setRowCell(3, agent.Unsigned32(12842))
# Finally, we tell the agent to "start". This actually connects the
# agent to the master agent.
agent.start()
# Helper function that dumps the state of all registered SNMP variables
def DumpRegistered():
for context in agent.getContexts():
print "{0}: Registered SNMP objects in Context \"{1}\": ".format(prgname, context)
vars = agent.getRegistered(context)
pprint.pprint(vars, width=columns)
print
DumpRegistered()
# Install a signal handler that terminates our example agent when
# CTRL-C is pressed or a KILL signal is received
def TermHandler(signum, frame):
global loop
loop = False
signal.signal(signal.SIGINT, TermHandler)
signal.signal(signal.SIGTERM, TermHandler)
# Install a signal handler that dumps the state of all registered values
# when SIGHUP is received
def HupHandler(signum, frame):
DumpRegistered()
signal.signal(signal.SIGHUP, HupHandler)
# The example agent's main loop. We loop endlessly until our signal
# handler above changes the "loop" variable.
print "{0}: Serving SNMP requests, press ^C to terminate...".format(prgname)
loop = True
while (loop):
# Block and process SNMP requests, if available
agent.check_and_process()
# Since we didn't give exampleCounter, exampleCounter64 and exampleTimeTicks
# a real meaning in the EXAMPLE-MIB, we can basically do with them whatever
# we want. Here, we just increase them, although in different manners.
exampleCounter32.update(exampleCounter32.value() + 2)
exampleCounter64.update(exampleCounter64.value() + 4294967294)
exampleTimeTicks.update(exampleTimeTicks.value() + 1)
# With counters, you can also increment them
exampleCounter32Context2.increment() # By 1
exampleCounter64Context2.increment(5) # By 5
print "{0}: Terminating.".format(prgname)