1
2
3
4
5
6
7
8
9
10
11
12
13
14 import sys
15 import socket
16 import logging
17
18 from Products.ZenEvents.ZenEventClasses import Status_Ping
19 from Products.ZenUtils.Utils import localIpCheck
20 from AsyncPing import PingJob
21
22 gDevicemap = {}
23 gNetsmap = {}
24 gAllnodes = {}
25
31
32
33
34 log = logging.getLogger("zen.ZenStatus")
35
42
44 """Rnode is a router node in the tree map.
45 """
46
48 self.pj = PingJob(ip, devname, status, 20)
49 self.pj.parent = parent
50 self.parent = parent
51 self.children = []
52 self.nets = []
53 if not parent:
54 initglobals(devname)
55 self.addNet("default","default")
56
57
59 """Walk back up the path to the ping server looking for failed routers.
60 """
61 node = self
62 while node.parent and node.pj.status == 0:
63 node = node.parent
64 if node.parent: return node.pj.hostname
65
66
68 """Return the pingJob of our parent router.
69 """
70 return self.pj
71
72
76
77
81
82
90
91
92 - def addNet(self, netip, enterip):
93 global gNetsmap
94 if self.hasNet(netip): return gNetsmap[netip]
95 net = Net(netip, enterip, self)
96 self.nets.append(net)
97 gNetsmap[netip] = net
98 return net
99
100
102 """Return the net node for net name
103 """
104 global gNetsmap
105 net = gNetsmap.get(netname,None)
106 if not net: net = gNetsmap['default']
107 return net
108
109
110 - def addDevice(self, device, unused_cycle=60):
133
134
136 self.pj.reset()
137 yield self.pj
138 if self.pj.status != 0: return
139 for rnode in self.children:
140 for pj in rnode.pjgen():
141 yield pj
142 for net in iter(self.nets):
143 for pj in net.pjgen():
144 yield pj
145
146
148 global gAllnodes
149 if nodes is None:
150 nodes = [self,]
151 for n in gAllnodes:
152 n._seen=False
153 gAllnodes = []
154 nnodes = []
155 for node in nodes:
156 if getattr(node, "_seen", False): continue
157 node._seen = True
158 gAllnodes.append(node)
159 print node
160 nnodes.extend(node.children)
161 print
162 if nnodes: self.pprint(nnodes)
163
164
174
175
177 return "%s->(%s)" % (self.pj.ipaddr, ",".join(map(str,self.nets)))
178
179
180
182 """Net object represents a network in the tree map.
183 """
185 self.ip = ip
186 self.enterip = enterip
187 self.parent = parent
188 self.pingjobs = []
189
190
192 """Walk back up the path to the ping server.
193 """
194 return self.parent.checkpath()
195
196
198 """Return the pingJob of our parent router.
199 """
200 return self.parent.pj
201
202
204 for pj in self.pingjobs:
205 yield pj
206
208 self.pingjobs.append(pj)
209
212
215
216
218 """Returns tree where tree that maps the network from root's
219 perspective and nmap is a dict that points network ids to the
220 network objects in the tree. nmap is used to add devices to be pinged
221 to the tree.
222 """
223 if memo is None: memo = []
224 if devs is None:
225 ipaddr = root.getManageIp()
226 if not ipaddr:
227 raise ValueError("zenping host %s has no manage ip"%root.id)
228 rootnode = Rnode(ipaddr, root.id, getStatus(root))
229 devs = [(root,rootnode)]
230 nextdevs = []
231 for dev, rnode in devs:
232 if dev.id in memo: return
233 log.debug("mapping device '%s'", dev.id)
234 memo.append(dev.id)
235 for route in dev.os.routes():
236 if route.routetype == "direct":
237 netid=route.getTarget()
238 if not route.ipcheck(netid):
239 netid = route.getTarget()
240 if rootnode.hasNet(netid): continue
241 net = rnode.addNet(netid,route.getInterfaceIp())
242 log.debug("add net: %s to rnode: %s", net, rnode)
243 else:
244 ndev = route.getNextHopDevice()
245 if ndev:
246 if rootnode.hasDev(ndev.id): continue
247 if route.getNextHopDevice():
248 nextHopIp = route.getNextHopDevice().manageIp
249 else:
250 nextHopIp = route.getNextHopIp()
251 nrnode = rnode.addRouter(nextHopIp,ndev.id,
252 getStatus(ndev))
253 log.debug("create rnode: %s", nrnode)
254 nextdevs.append((ndev, nrnode))
255 for iface in dev.os.interfaces():
256 netid = iface.getNetworkName()
257 if not netid: continue
258 if localIpCheck(dev, netid) or rootnode.hasNet(netid): continue
259 net = rnode.addNet(netid,iface.getIp())
260 log.debug("add net: %s to rnode: %s", net, rnode)
261 if nextdevs: buildTree(root, rootnode, nextdevs, memo)
262 return rootnode
263
264
265
267 """Return a mapping object with network ip as key and distance as value.
268 This is a recursive method that does a breadth first search of the route
269 space. It is called with no parameters (they are used by the recursion)
270 """
271 if nmap is None: nmap = {}
272 if memo is None: memo = []
273 if devs is None: devs = [root,]
274 nextdevs = []
275 for dev in devs:
276 if dev.id in memo: return
277 log.debug("mapping device '%s' distance '%s'", dev.id, distance)
278 memo.append(dev.id)
279 for route in dev.os.routes():
280 if route.routetype == "direct":
281 netid=route.getTarget()
282 if not route.ipcheck(netid):
283 netip = route.getTargetIp()
284 curdist = nmap.get(netip,sys.maxint)
285 if curdist > distance:
286 log.debug("netip '%s' distance '%d'",
287 netip, distance)
288 nmap[netip] = distance
289 else:
290 ndev = route.getNextHopDevice()
291 if ndev: nextdevs.append(ndev)
292 distance += 1
293 netDistMap(root, nmap, distance, nextdevs, memo)
294 return nmap
295