1
2
3
4
5
6
7
8
9
10
11
12
13
14 __doc__="""IpNetwork
15
16 IpNetwork represents an IP network which contains
17 many IP addresses.
18
19 $Id: IpNetwork.py,v 1.22 2004/04/12 16:21:25 edahl Exp $"""
20
21 __version__ = "$Revision: 1.22 $"[11:-2]
22
23 import os
24 import sys
25 import math
26 import transaction
27 import logging
28 log = logging.getLogger('zen')
29
30 from Globals import DTMLFile
31 from Globals import InitializeClass
32 from Acquisition import aq_base
33 from AccessControl import ClassSecurityInfo
34 from AccessControl import Permissions as permissions
35
36
37 from Products.ZenUtils.IpUtil import *
38 from Products.ZenRelations.RelSchema import *
39 from Products.ZenUtils.Search import makeCaseInsensitiveFieldIndex
40
41 from IpAddress import IpAddress
42 from DeviceOrganizer import DeviceOrganizer
43
44 from Products.ZenModel.Exceptions import *
45
46 from Products.ZenUtils.Utils import setWebLoggingStream, clearWebLoggingStream
47 from Products.ZenUtils.Utils import zenPath
48 from Products.ZenUtils import NetworkTree
49 from Products.ZenUtils.Utils import edgesToXML
50
62
63
64 addIpNetwork = DTMLFile('dtml/addIpNetwork',globals())
65
66
67
68
69 defaultNetworkTree = (32,)
70
72 """IpNetwork object"""
73
74 isInTree = True
75
76 buildLinks = True
77
78
79 dmdRootName = "Networks"
80
81
82 default_catalog = 'ipSearch'
83
84 portal_type = meta_type = 'IpNetwork'
85
86 _properties = (
87 {'id':'netmask', 'type':'int', 'mode':'w'},
88 {'id':'description', 'type':'text', 'mode':'w'},
89 )
90
91 _relations = DeviceOrganizer._relations + (
92 ("ipaddresses", ToManyCont(ToOne, "Products.ZenModel.IpAddress", "network")),
93 ("clientroutes", ToMany(ToOne,"Products.ZenModel.IpRouteEntry","target")),
94 ("location", ToOne(ToMany, "Products.ZenModel.Location", "networks")),
95 )
96
97
98 factory_type_information = (
99 {
100 'id' : 'IpNetwork',
101 'meta_type' : 'IpNetwork',
102 'description' : """Arbitrary device grouping class""",
103 'icon' : 'IpNetwork_icon.gif',
104 'product' : 'ZenModel',
105 'factory' : 'manage_addIpNetwork',
106 'immediate_view' : 'viewNetworkOverview',
107 'actions' :
108 (
109 { 'id' : 'overview'
110 , 'name' : 'Overview'
111 , 'action' : 'viewNetworkOverview'
112 , 'permissions' : (
113 permissions.view, )
114 },
115 { 'id' : 'zProperties'
116 , 'name' : 'zProperties'
117 , 'action' : 'zPropertyEdit'
118 , 'permissions' : ("Manage DMD",)
119 },
120 { 'id' : 'viewHistory'
121 , 'name' : 'Modifications'
122 , 'action' : 'viewHistory'
123 , 'permissions' : (
124 permissions.view, )
125 },
126 )
127 },
128 )
129
130 security = ClassSecurityInfo()
131
132
133 - def __init__(self, id, netmask=24, description=''):
140
141
147
148
150 """Return and create if nessesary netip. netip in form 1.1.1.0/24 or
151 with netmask passed as parameter.
152 Subnetworks created based on the zParameter zDefaulNetworkTree.
153 """
154 netroot = self.getDmdRoot("Networks")
155 if netip.find("/") > -1:
156 netip, netmask = netip.split("/",1)
157 netmask = int(netmask)
158 netobj = netroot.getNet(netip)
159 if netobj: return netobj
160 if netmask == 0:
161 raise ValueError("netip '%s' without netmask", netip)
162 netip = getnetstr(netip,netmask)
163 netTree = getattr(netroot, 'zDefaultNetworkTree', defaultNetworkTree)
164 netTree = map(int, netTree)
165 netobj = netroot
166 for treemask in netTree:
167 if treemask >= netmask:
168 netobj = netobj.addSubNetwork(netip, netmask)
169 break
170 else:
171 supnetip = getnetstr(netip, treemask)
172 netobj = netobj.addSubNetwork(supnetip, treemask)
173 return netobj
174
175
177 """Return the net starting form the Networks root for ip.
178 """
179 return self.getDmdRoot("Networks")._getNet(ip)
180
181
183 """Recurse down the network tree to find the net of ip.
184 """
185 for net in self.children():
186 if net.hasIp(ip):
187 if len(net.children()):
188 subnet = net._getNet(ip)
189 if subnet:
190 return subnet
191 else:
192 return net
193 else:
194 return net
195
196
198 """Return an ip and create if nessesary in a hierarchy of
199 subnetworks based on the zParameter zDefaulNetworkTree.
200 """
201 netobj = self.getDmdRoot("Networks")
202 ipobj = self.findIp(ip)
203 if ipobj: return ipobj
204 ipobj = netobj.addIp(ip)
205 if ipobj: return ipobj
206 netobj = self.createNet(ip, netmask)
207 ipobj = netobj.addIpAddress(ip,netmask)
208 return ipobj
209
210
212 """Add an ip to the system. Its network object must already exist.
213 """
214 for net in self.children():
215 if net.hasIp(ip):
216 if not len(net.children()):
217 return net.addIpAddress(ip, net.netmask)
218 else:
219 return net.addIp(ip)
220 return None
221
222
224 """Number of free Ips left in this network.
225 """
226 freeips = int(math.pow(2,32-self.netmask)-(self.countIpAddresses()))
227 if self.netmask >= 31:
228 return freeips
229 return freeips - 2
230
231
238
239
241 """Return a list of all ips in this network.
242 """
243 if (self.netmask == 32): return [self.id]
244 ipnumb = numbip(self.id)
245 maxip = math.pow(2,32-self.netmask)
246 start = int(ipnumb+1)
247 end = int(ipnumb+maxip-1)
248 return map(strip, range(start,end))
249
250
257
258
260 """Return the ip of the default router for this network.
261 It is based on zDefaultRouterNumber which specifies the sequence
262 number that locates the router in this network. If:
263 zDefaultRouterNumber==1 for 10.2.1.0/24 -> 10.2.1.1
264 zDefaultRouterNumber==254 for 10.2.1.0/24 -> 10.2.1.254
265 zDefaultRouterNumber==1 for 10.2.2.128/25 -> 10.2.2.129
266 zDefaultRouterNumber==126 for 10.2.2.128/25 -> 10.2.2.254
267 """
268 roffset = getattr(self, "zDefaultRouterNumber", 1)
269 return strip((numbip(self.id) + roffset))
270
271
273 """return the full network name of this network"""
274 return "%s/%d" % (self.id, self.netmask)
275
276
277 security.declareProtected('View', 'primarySortKey')
279 """make sure that networks sort correctly"""
280 return numbip(self.id)
281
282
283 security.declareProtected('Change Network', 'addSubNetwork')
292
293
294 security.declareProtected('View', 'getSubNetwork')
296 """get an ip on this network"""
297 return self._getOb(ip, None)
298
299
301 """Return all network objects below this one.
302 """
303 nets = self.children()
304 for subgroup in self.children():
305 nets.extend(subgroup.getSubNetworks())
306 return nets
307
308 security.declareProtected('Change Network', 'addIpAddress')
314
315
316 security.declareProtected('View', 'getIpAddress')
320
321 security.declareProtected('Change Network', 'manage_deleteIpAddresses')
330
331 security.declareProtected('View', 'countIpAddresses')
341
342 security.declareProtected('View', 'countDevices')
343 countDevices = countIpAddresses
344
345
347 """Count all devices within a device group and get the
348 ping and snmp counts as well"""
349 counts = [
350 self.ipaddresses.countObjects(),
351 self._status("Ping", "ipaddresses"),
352 self._status("Snmp", "ipaddresses"),
353 ]
354 for group in self.children():
355 sc = group.getAllCounts()
356 for i in range(3): counts[i] += sc[i]
357 return counts
358
359
361 """aggregate ping status for all devices in this group and below"""
362 return DeviceOrganizer.pingStatus(self, "ipaddresses")
363
364
366 """aggregate snmp status for all devices in this group and below"""
367 return DeviceOrganizer.snmpStatus(self, "ipaddresses")
368
369
373
374
387
388
397
398
400 nets = self.getDmdRoot("Networks")
401 if getattr(aq_base(nets), "zDefaultNetworkTree", False):
402 return
403 nets._setProperty("zDefaultNetworkTree", (24,32), type="lines")
404 nets._setProperty("zDrawMapLinks", True, type="boolean")
405 nets._setProperty("zAutoDiscover", True, type="boolean")
406 nets._setProperty("zPingFailThresh", 168, type="int")
407 nets._setProperty("zIcon", "/zport/dmd/img/icons/network.png")
408
409
419
420
432
433
435 """
436 Load a device into the database connecting its major relations
437 and collecting its configuration.
438 """
439 xmlrpc = False
440 if REQUEST and REQUEST['CONTENT_TYPE'].find('xml') > -1:
441 xmlrpc = True
442
443 if not organizerPaths:
444 if xmlrpc: return 1
445 return self.callZenScreen(REQUEST)
446
447 if REQUEST and not xmlrpc:
448 response = REQUEST.RESPONSE
449 dlh = self.discoverLoggingHeader()
450 idx = dlh.rindex("</table>")
451 dlh = dlh[:idx]
452 idx = dlh.rindex("</table>")
453 dlh = dlh[:idx]
454 response.write(str(dlh[:idx]))
455 handler = setWebLoggingStream(response)
456
457 orgroot = self.getDmdRoot(self.dmdRootName)
458 from popen2 import Popen4
459 for organizerName in organizerPaths:
460 try:
461 organizer = orgroot._getNet(organizerName)
462 import os
463 zd = zenPath('bin', 'zendisc')
464 zendiscCmd = [zd, "run", '--net', organizer.id]
465 log.info('Executing command: %s' % ' '.join(zendiscCmd))
466 f = Popen4(zendiscCmd)
467 while 1:
468 s = f.fromchild.readline()
469 if not s: break
470 log.info(s.rstrip())
471 except (SystemExit, KeyboardInterrupt):
472 if xmlrpc: return 1
473 raise
474 except ZentinelException, e:
475 if xmlrpc: return 1
476 log.critical(e)
477 except:
478 if xmlrpc: return 1
479 raise
480 log.info('Done')
481
482 if REQUEST and not xmlrpc:
483 self.loaderFooter(response)
484 clearWebLoggingStream(handler)
485 if xmlrpc: return 0
486
487
489 """setup logging package to send to browser"""
490 from logging import StreamHandler, Formatter
491 root = logging.getLogger()
492 self._v_handler = StreamHandler(response)
493 fmt = Formatter("""<tr class="tablevalues">
494 <td>%(asctime)s</td><td>%(levelname)s</td>
495 <td>%(name)s</td><td>%(message)s</td></tr>
496 """, "%Y-%m-%d %H:%M:%S")
497 self._v_handler.setFormatter(fmt)
498 root.addHandler(self._v_handler)
499 root.setLevel(10)
500
501
503 log = logging.getLogger()
504 if getattr(self, "_v_handler", False):
505 log.removeHandler(self._v_handler)
506
507
514
515 security.declareProtected('View', 'getXMLEdges')
522
524 """ gets icon """
525 return self.dmd.getIconPath(self)
526
527
528 InitializeClass(IpNetwork)
529