| Trees | Indices | Help |
|
|---|
|
|
1 ###########################################################################
2 #
3 # This program is part of Zenoss Core, an open source monitoring platform.
4 # Copyright (C) 2007, Zenoss Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License version 2 or (at your
8 # option) any later version as published by the Free Software Foundation.
9 #
10 # For complete information please visit: http://www.zenoss.com/oss/
11 #
12 ###########################################################################
13
14 __doc__="""IpInterface
15
16 IpInterface is a collection of devices and subsystems that make
17 up a business function
18 """
19
20 import re
21 import copy
22 import logging
23 log = logging.getLogger("zen.IpInterface")
24
25 from Globals import DTMLFile
26 from Globals import InitializeClass
27 from Acquisition import aq_base
28 from App.Dialogs import MessageDialog
29 from AccessControl import ClassSecurityInfo
30 from zope.event import notify
31 from zope.container.contained import ObjectMovedEvent
32
33 from Products.ZenRelations.RelSchema import *
34
35 from Products.ZenUtils.Utils import localIpCheck, localInterfaceCheck
36 from Products.ZenUtils.IpUtil import *
37
38 from ConfmonPropManager import ConfmonPropManager
39 from OSComponent import OSComponent
40 from Products.ZenModel.Exceptions import *
41 from Products.ZenModel.Linkable import Layer2Linkable
42
43 from Products.ZenModel.ZenossSecurity import *
44
46 """
47 Make a device via the ZMI
48 """
49 d = IpInterface(newId)
50 context._setObject(newId, d)
51 d = context._getOb(newId)
52 d.interfaceName = newId
53 if userCreated: d.setUserCreateFlag()
54 if REQUEST is not None:
55 REQUEST['RESPONSE'].redirect(context.absolute_url()
56 +'/manage_main')
57
58 addIpInterface = DTMLFile('dtml/addIpInterface',globals())
59
60
62 """
63 IpInterface object
64 """
65
66 portal_type = meta_type = 'IpInterface'
67
68 manage_editIpInterfaceForm = DTMLFile('dtml/manageEditIpInterface',
69 globals())
70
71 # catalog to find interfaces that should be pinged
72 # indexes are id and description
73 #default_catalog = 'interfaceSearch'
74
75 ifindex = '0'
76 interfaceName = ''
77 macaddress = ""
78 type = ""
79 description = ""
80 mtu = 0
81 speed = 0
82 adminStatus = 0
83 operStatus = 0
84 duplex = 0
85 _ipAddresses = []
86
87
88 _properties = OSComponent._properties + (
89 {'id':'ips', 'type':'lines', 'mode':'w', 'setter':'setIpAddresses'},
90 {'id':'interfaceName', 'type':'string', 'mode':'w'},
91 {'id':'ifindex', 'type':'string', 'mode':'w'},
92 {'id':'macaddress', 'type':'string', 'mode':'w'},
93 {'id':'type', 'type':'string', 'mode':'w'},
94 {'id':'description', 'type':'string', 'mode':'w'},
95 {'id':'mtu', 'type':'int', 'mode':'w'},
96 {'id':'speed', 'type':'long', 'mode':'w'},
97 {'id':'adminStatus', 'type':'int', 'mode':'w'},
98 {'id':'operStatus', 'type':'int', 'mode':'w'},
99 {'id':'duplex', 'type':'int', 'mode':'w'},
100 )
101
102 _relations = OSComponent._relations + (
103 ("os", ToOne(ToManyCont,"Products.ZenModel.OperatingSystem","interfaces")),
104 ("ipaddresses", ToMany(ToOne,"Products.ZenModel.IpAddress","interface")),
105 ("iproutes", ToMany(ToOne,"Products.ZenModel.IpRouteEntry","interface")),
106 )
107
108 zNoPropertiesCopy = ('ips','macaddress')
109
110 localipcheck = re.compile(r'^127.|^0.|^::1$|^fe80:').search
111 localintcheck = re.compile(r'^lo0').search
112
113 defaultIgnoreTypes = ('Other', 'softwareLoopback', 'CATV MAC Layer')
114
115 factory_type_information = (
116 {
117 'id' : 'IpInterface',
118 'meta_type' : 'IpInterface',
119 'description' : """Arbitrary device grouping class""",
120 'icon' : 'IpInterface_icon.gif',
121 'product' : 'ZenModel',
122 'factory' : 'manage_addIpInterface',
123 'immediate_view' : 'viewIpInterface',
124 'actions' :
125 (
126 { 'id' : 'status'
127 , 'name' : 'Status'
128 , 'action' : 'viewIpInterface'
129 , 'permissions' : (ZEN_VIEW,)
130 },
131 { 'id' : 'events'
132 , 'name' : 'Events'
133 , 'action' : 'viewEvents'
134 , 'permissions' : (ZEN_VIEW, )
135 },
136 { 'id' : 'perfConf'
137 , 'name' : 'Template'
138 , 'action' : 'objTemplates'
139 , 'permissions' : ("Change Device", )
140 },
141 )
142 },
143 )
144
145 security = ClassSecurityInfo()
146
148 """
149 Init OSComponent and set _ipAddresses to an empty list.
150 """
151 OSComponent.__init__(self, id, title)
152 self._ipAddresses = []
153
154
155 security.declareProtected('View', 'viewName')
157 """
158 Use the unmagled interface name for display
159 """
160 return self.interfaceName.rstrip('\x00') #Bogus fix for MS names
161 name = primarySortKey = viewName
162
164 """
165 Override from PerpertyManager to handle checks and ip creation
166 """
167 self._wrapperCheck(value)
168 if id == 'ips':
169 self.setIpAddresses(value)
170 else:
171 setattr(self,id,value)
172 if id == 'macaddress':
173 self.index_object()
174
176 """
177 Override the default so that links are indexed.
178 """
179 super(IpInterface, self).index_object(idxs)
180 self.index_links()
181 # index our ip addresses if necessary
182 for ip in self.ipaddresses():
183 ip.index_object()
184
186 """
187 Override the default so that links are unindexed.
188 """
189 self.unindex_links()
190 super(IpInterface, self).unindex_object()
191 # index our ip addresses if necessary
192 for ip in self.ipaddresses():
193 ip.index_object()
194
196 """
197 Reindexes all the ip addresses on this interface
198 after it has been deleted
199 """
200 ips = self.ipaddresses()
201 super(IpInterface, self).manage_deleteComponent(REQUEST)
202 for ip in ips:
203 ip.primaryAq().index_object()
204
206 """
207 Override from propertiyManager so we can trap errors
208 """
209 try:
210 return ConfmonPropManager.manage_editProperties(self, REQUEST)
211 except IpAddressError, e:
212 return MessageDialog(
213 title = "Input Error",
214 message = e.args[0],
215 action = "manage_main")
216
217
219 """
220 Allow access to ipAddresses via the ips attribute
221 """
222 if name == 'ips':
223 return self.getIpAddresses()
224 else:
225 raise AttributeError( name )
226
227
229 """
230 Split ips in the format 1.1.1.1/24 into ip and netmask.
231 Default netmask is 24.
232 """
233 iparray = ip.split("/")
234 if len(iparray) > 1:
235 ip = iparray[0]
236 checkip(ip)
237 netmask = maskToBits(iparray[1])
238 return ip, netmask
239
240
242 """
243 Add an ip to the ipaddresses relationship on this interface.
244 """
245 networks = self.device().getNetworkRoot()
246 ip, netmask = self._prepIp(ip, netmask)
247 #see if ip exists already and link it to interface
248 ipobj = networks.findIp(ip)
249 if ipobj:
250 dev = ipobj.device()
251 if dev and dev != self.device():
252 log.warn("Adding IP Address %s to %s found it on device %s",
253 ip, self.getId(), dev.getId())
254 self.ipaddresses.addRelation(ipobj)
255 #never seen this ip make a new one in correct subnet
256 else:
257 ipobj = networks.createIp(ip, netmask)
258 self.ipaddresses.addRelation(ipobj)
259 ipobj.index_object()
260 os = self.os()
261 notify(ObjectMovedEvent(self, os, self.id, os, self.id))
262
263
264
266 """
267 Add a locally stored ip. Ips like 127./8 are maintained locally.
268 """
269 (ip, netmask) = self._prepIp(ip, netmask)
270 ip = ip + '/' + str(netmask)
271 if not self._ipAddresses: self._ipAddresses = []
272 if not ip in self._ipAddresses:
273 self._ipAddresses = self._ipAddresses + [ip,]
274
275
277 """
278 If no IPs are sent remove all in the relation
279 """
280 if not ips:
281 self.removeRelation('ipaddresses')
282 return True
283
284
286 """
287 Set a list of ipaddresses in the form 1.1.1.1/24 on to this
288 interface. If networks for the ips don't exist they will be created.
289 """
290 if isinstance(ips, basestring): ips = [ips,]
291 if self.clearIps(ips): return
292
293 ipids = self.ipaddresses.objectIdsAll()
294 localips = copy.copy(self._ipAddresses)
295 for ip in ips:
296 if localIpCheck(self, ip) or localInterfaceCheck(self, self.id):
297 if not ip in localips:
298 self.addLocalIpAddress(ip)
299 else:
300 localips.remove(ip)
301 else:
302 # do this funky filtering because the id we have
303 # is a primary id /zport/dmd/Newtowrks... etc
304 # and we are looking for just the IP part
305 # we used the full id later when deleting the IPs
306 rawip = ipFromIpMask(ip)
307 ipmatch = filter(lambda x: x.find(rawip) > -1, ipids)
308 if not ipmatch:
309 self.addIpAddress(ip)
310 elif len(ipmatch) == 1:
311 ipids.remove(ipmatch[0])
312
313
314 #delete ips that are no longer in use
315 for ip in ipids:
316 ipobj = self.ipaddresses._getOb(ip)
317 self.removeRelation('ipaddresses', ipobj)
318 ipobj.index_object()
319 for ip in localips:
320 self._ipAddresses.remove(ip)
321
322
324 """
325 Remove an ipaddress from this interface.
326 """
327 for ipobj in self.ipaddresses():
328 if ipobj.id == ip:
329 self.ipaddresses.removeRelation(ipobj)
330 ipobj.index_object()
331 return
332
333
335 """
336 Return the first ip for this interface in the form: 1.1.1.1.
337 """
338 if self.ipaddresses.countObjects():
339 return self.ipaddresses()[0].getIp()
340 elif len(self._ipAddresses):
341 return self._ipAddresses[0].split('/')[0]
342
343
345 """
346 Return the IP address as an integter for sorting purposes.
347 """
348 if self.ipaddresses.countObjects():
349 return self.ipaddresses()[0].primarySortKey()
350 elif len(self._ipAddresses):
351 return numbip(self._ipAddresses[0].split('/')[0])
352
353
355 """
356 Return the first IP address with its netmask ie: 1.1.1.1/24.
357 """
358 if self.ipaddresses.countObjects():
359 return self.ipaddresses()[0].getIpAddress()
360 elif len(self._ipAddresses):
361 return self._ipAddresses[0]
362
363
365 """
366 Return the first real IP address object or None if none are found.
367 """
368 if len(self.ipaddresses()):
369 return self.ipaddresses()[0]
370
371
373 """
374 Return a list of the ip objects on this interface.
375 """
376 retval=[]
377 for ip in self.ipaddresses.objectValuesAll():
378 retval.append(ip)
379 for ip in self._ipAddresses:
380 retval.append(ip)
381 return retval
382
383
385 """
386 Return list of ip addresses as strings in the form 1.1.1.1/24.
387 """
388 return map(str, self.getIpAddressObjs())
389
390
392 """
393 Return the network for the first ip on this interface.
394 """
395 if self.ipaddresses.countObjects():
396 return self.ipaddresses()[0].network()
397
398
400 """
401 Return the network name for the first ip on this interface.
402 """
403 net = self.getNetwork()
404 if net: return net.getNetworkName()
405 return ""
406
407
409 """
410 Return the network link for the first ip on this interface.
411 """
412 if len(self.ipaddresses()):
413 addr = self.ipaddresses.objectValuesAll()[0]
414 if addr:
415 if hasattr(aq_base(addr), 'network'):
416 if self.checkRemotePerm("View", addr.network):
417 return addr.network.getPrimaryLink()
418 else:
419 return addr.network.getRelatedId()
420 else:
421 return ""
422
423
425 """
426 Return a list of network links for each ip in this interface.
427 """
428 addrs = self.ipaddresses() + self._ipAddresses
429 if addrs:
430 links = []
431 for addr in addrs:
432 if hasattr(aq_base(addr), 'network'):
433 if self.checkRemotePerm('View', addr.network()):
434 links.append(addr.network.getPrimaryLink())
435 else:
436 links.append(addr.network.getRelatedId())
437 else:
438 links.append("")
439 return "<br/>".join(links)
440 else:
441 return ""
442
443
444 security.declareProtected('View', 'getInterfaceName')
446 """
447 Return the name of this interface.
448 """
449 if self.interfaceName: return self.interfaceName
450 elif self.viewName(): return self.viewName()
451 else: return "None"
452
453
454 security.declareProtected('View', 'getInterfaceMacaddress')
460
461
463 """
464 Return the interface type as the target type name.
465 """
466 return self.prepId(self.type or "Unknown")
467
468
470 """
471 Return a list containing the appropriate RRDTemplate for this
472 IpInterface. If none is found then the list will be empty.
473
474 Order of preference if the interface supports 64bit counters.
475 1. <type>_64
476 2. ethernetCsmacd_64
477 3. <type>
478 4. ethernetCsmacd
479
480 Order of preference if the interface doesn't support 64bit counters.
481 1. <type>
482 2. ethernetCsmacd
483 """
484 templateName = self.getRRDTemplateName()
485
486 order = ['ethernetCsmacd']
487 if templateName.endswith('_64'):
488 order.insert(0, 'ethernetCsmacd_64')
489 if templateName not in order:
490 order.insert(0, templateName)
491 order.insert(2, templateName[:-3])
492 else:
493 if templateName not in order:
494 order.insert(0, templateName)
495
496 for name in order:
497 template = self.getRRDTemplateByName(name)
498 if template:
499 return [template]
500
501 return []
502
503
505 """
506 Ignore interface that are administratively down.
507 """
508 # This must be based off the modeled admin status or zenhub could
509 # lock itself up while building configurations.
510 return self.adminStatus > 1 or self.monitor == False
511
512
514 """
515 Get the current administrative state of the interface. Prefer real-time
516 value over modeled value.
517 """
518 s = self.cacheRRDValue('ifAdminStatus', None)
519 if s is None: s = self.adminStatus
520 return s
521
522
524 """
525 Return the current administrative state of the interface converted to
526 its string version.
527 """
528 return {1: 'Up', 2: 'Down', 3: 'Testing'}.get(
529 self.getAdminStatus(), 'Unknown')
530
531
533 """
534 Get the current operational state of the interface. Prefer real-time
535 value over modeled value.
536 """
537 s = self.cacheRRDValue('ifOperStatus', None)
538 if s is None: s = self.operStatus
539 return s
540
541
543 """
544 Return the current operational state of the interface converted to
545 its string version.
546 """
547 return {
548 1: 'Up', 2: 'Down', 3: 'Testing', 5: 'Dormant', 6: 'Not Present',
549 7: 'Lower Layer Down'}.get(
550 self.getOperStatus(), 'Unknown')
551
552
554 """
555 Return the status number for this interface.
556 """
557 # Unknown status if we're not monitoring the interface.
558 if self.snmpIgnore():
559 return -1
560
561 return super(IpInterface, self).getStatus()
562
563
565 """
566 Return a string that expresses self.speed in reasonable units.
567 """
568 if not self.speed:
569 return 'Unknown'
570 speed = self.speed
571 for unit in ('bps', 'Kbps', 'Mbps', 'Gbps'):
572 if speed < 1000: break
573 speed /= 1000.0
574 return "%.3f%s" % (speed, unit)
575
577 """
578 The device id, for indexing purposes.
579 """
580 d = self.device()
581 if d: return d.getPrimaryId()
582 else: return None
583
589
595
606
607 InitializeClass(IpInterface)
608
610 if (event.object==ob or event.object==ob.device() or
611 getattr(event.object, "_operation", -1) < 1):
612 ob.unindex_object()
613
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1.1812 on Tue Oct 11 12:51:40 2011 | http://epydoc.sourceforge.net |