| 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 { 'id' : 'viewHistory'
142 , 'name' : 'Modifications'
143 , 'action' : 'viewHistory'
144 , 'permissions' : (ZEN_VIEW_MODIFICATIONS,)
145 },
146 )
147 },
148 )
149
150 security = ClassSecurityInfo()
151
153 """
154 Init OSComponent and set _ipAddresses to an empty list.
155 """
156 OSComponent.__init__(self, id, title)
157 self._ipAddresses = []
158
159
160 security.declareProtected('View', 'viewName')
162 """
163 Use the unmagled interface name for display
164 """
165 return self.interfaceName.rstrip('\x00') #Bogus fix for MS names
166 name = primarySortKey = viewName
167
169 """
170 Override from PerpertyManager to handle checks and ip creation
171 """
172 self._wrapperCheck(value)
173 if id == 'ips':
174 self.setIpAddresses(value)
175 else:
176 setattr(self,id,value)
177 if id == 'macaddress':
178 self.index_object()
179
181 """
182 Override the default so that links are indexed.
183 """
184 super(IpInterface, self).index_object(idxs)
185 self.index_links()
186 # index our ip addresses if necessary
187 for ip in self.ipaddresses():
188 ip.index_object()
189
191 """
192 Override the default so that links are unindexed.
193 """
194 self.unindex_links()
195 super(IpInterface, self).unindex_object()
196 # index our ip addresses if necessary
197 for ip in self.ipaddresses():
198 ip.index_object()
199
201 """
202 Reindexes all the ip addresses on this interface
203 after it has been deleted
204 """
205 ips = self.ipaddresses()
206 super(IpInterface, self).manage_deleteComponent(REQUEST)
207 for ip in ips:
208 ip.primaryAq().index_object()
209
211 """
212 Override from propertiyManager so we can trap errors
213 """
214 try:
215 return ConfmonPropManager.manage_editProperties(self, REQUEST)
216 except IpAddressError, e:
217 return MessageDialog(
218 title = "Input Error",
219 message = e.args[0],
220 action = "manage_main")
221
222
224 """
225 Allow access to ipAddresses via the ips attribute
226 """
227 if name == 'ips':
228 return self.getIpAddresses()
229 else:
230 raise AttributeError( name )
231
232
234 """
235 Split ips in the format 1.1.1.1/24 into ip and netmask.
236 Default netmask is 24.
237 """
238 iparray = ip.split("/")
239 if len(iparray) > 1:
240 ip = iparray[0]
241 checkip(ip)
242 netmask = maskToBits(iparray[1])
243 return ip, netmask
244
245
247 """
248 Add an ip to the ipaddresses relationship on this interface.
249 """
250 networks = self.device().getNetworkRoot()
251 ip, netmask = self._prepIp(ip, netmask)
252 #see if ip exists already and link it to interface
253 ipobj = networks.findIp(ip)
254 if ipobj:
255 dev = ipobj.device()
256 if dev and dev != self.device():
257 log.warn("Adding IP Address %s to %s found it on device %s",
258 ip, self.getId(), dev.getId())
259 self.ipaddresses.addRelation(ipobj)
260 #never seen this ip make a new one in correct subnet
261 else:
262 ipobj = networks.createIp(ip, netmask)
263 self.ipaddresses.addRelation(ipobj)
264 ipobj.index_object()
265 os = self.os()
266 notify(ObjectMovedEvent(self, os, self.id, os, self.id))
267
268
269
271 """
272 Add a locally stored ip. Ips like 127./8 are maintained locally.
273 """
274 (ip, netmask) = self._prepIp(ip, netmask)
275 ip = ip + '/' + str(netmask)
276 if not self._ipAddresses: self._ipAddresses = []
277 if not ip in self._ipAddresses:
278 self._ipAddresses = self._ipAddresses + [ip,]
279
280
282 """
283 If no IPs are sent remove all in the relation
284 """
285 if not ips:
286 self.removeRelation('ipaddresses')
287 return True
288
289
291 """
292 Set a list of ipaddresses in the form 1.1.1.1/24 on to this
293 interface. If networks for the ips don't exist they will be created.
294 """
295 if isinstance(ips, basestring): ips = [ips,]
296 if self.clearIps(ips): return
297
298 ipids = self.ipaddresses.objectIdsAll()
299 localips = copy.copy(self._ipAddresses)
300 for ip in ips:
301 if localIpCheck(self, ip) or localInterfaceCheck(self, self.id):
302 if not ip in localips:
303 self.addLocalIpAddress(ip)
304 else:
305 localips.remove(ip)
306 else:
307 # do this funky filtering because the id we have
308 # is a primary id /zport/dmd/Newtowrks... etc
309 # and we are looking for just the IP part
310 # we used the full id later when deleting the IPs
311 rawip = ipFromIpMask(ip)
312 ipmatch = filter(lambda x: x.find(rawip) > -1, ipids)
313 if not ipmatch:
314 self.addIpAddress(ip)
315 elif len(ipmatch) == 1:
316 ipids.remove(ipmatch[0])
317
318
319 #delete ips that are no longer in use
320 for ip in ipids:
321 ipobj = self.ipaddresses._getOb(ip)
322 self.removeRelation('ipaddresses', ipobj)
323 ipobj.index_object()
324 for ip in localips:
325 self._ipAddresses.remove(ip)
326
327
329 """
330 Remove an ipaddress from this interface.
331 """
332 for ipobj in self.ipaddresses():
333 if ipobj.id == ip:
334 self.ipaddresses.removeRelation(ipobj)
335 ipobj.index_object()
336 return
337
338
340 """
341 Return the first ip for this interface in the form: 1.1.1.1.
342 """
343 if self.ipaddresses.countObjects():
344 return self.ipaddresses()[0].getIp()
345 elif len(self._ipAddresses):
346 return self._ipAddresses[0].split('/')[0]
347
348
350 """
351 Return the IP address as an integter for sorting purposes.
352 """
353 if self.ipaddresses.countObjects():
354 return self.ipaddresses()[0].primarySortKey()
355 elif len(self._ipAddresses):
356 return numbip(self._ipAddresses[0].split('/')[0])
357
358
360 """
361 Return the first IP address with its netmask ie: 1.1.1.1/24.
362 """
363 if self.ipaddresses.countObjects():
364 return self.ipaddresses()[0].getIpAddress()
365 elif len(self._ipAddresses):
366 return self._ipAddresses[0]
367
368
370 """
371 Return the first real IP address object or None if none are found.
372 """
373 if len(self.ipaddresses()):
374 return self.ipaddresses()[0]
375
376
378 """
379 Return a list of the ip objects on this interface.
380 """
381 retval=[]
382 for ip in self.ipaddresses.objectValuesAll():
383 retval.append(ip)
384 for ip in self._ipAddresses:
385 retval.append(ip)
386 return retval
387
388
390 """
391 Return list of ip addresses as strings in the form 1.1.1.1/24.
392 """
393 return map(str, self.getIpAddressObjs())
394
395
397 """
398 Return the network for the first ip on this interface.
399 """
400 if self.ipaddresses.countObjects():
401 return self.ipaddresses()[0].network()
402
403
405 """
406 Return the network name for the first ip on this interface.
407 """
408 net = self.getNetwork()
409 if net: return net.getNetworkName()
410 return ""
411
412
414 """
415 Return the network link for the first ip on this interface.
416 """
417 if len(self.ipaddresses()):
418 addr = self.ipaddresses.objectValuesAll()[0]
419 if addr:
420 if hasattr(aq_base(addr), 'network'):
421 if self.checkRemotePerm("View", addr.network):
422 return addr.network.getPrimaryLink()
423 else:
424 return addr.network.getRelatedId()
425 else:
426 return ""
427
428
430 """
431 Return a list of network links for each ip in this interface.
432 """
433 addrs = self.ipaddresses() + self._ipAddresses
434 if addrs:
435 links = []
436 for addr in addrs:
437 if hasattr(aq_base(addr), 'network'):
438 if self.checkRemotePerm('View', addr.network()):
439 links.append(addr.network.getPrimaryLink())
440 else:
441 links.append(addr.network.getRelatedId())
442 else:
443 links.append("")
444 return "<br/>".join(links)
445 else:
446 return ""
447
448
449 security.declareProtected('View', 'getInterfaceName')
451 """
452 Return the name of this interface.
453 """
454 if self.interfaceName: return self.interfaceName
455 elif self.viewName(): return self.viewName()
456 else: return "None"
457
458
459 security.declareProtected('View', 'getInterfaceMacaddress')
465
466
468 """
469 Return the interface type as the target type name.
470 """
471 return self.prepId(self.type or "Unknown")
472
473
475 """
476 Return a list containing the appropriate RRDTemplate for this
477 IpInterface. If none is found then the list will be empty.
478
479 Order of preference if the interface supports 64bit counters.
480 1. <type>_64
481 2. ethernetCsmacd_64
482 3. <type>
483 4. ethernetCsmacd
484
485 Order of preference if the interface doesn't support 64bit counters.
486 1. <type>
487 2. ethernetCsmacd
488 """
489 templateName = self.getRRDTemplateName()
490
491 order = ['ethernetCsmacd']
492 if templateName.endswith('_64'):
493 order.insert(0, 'ethernetCsmacd_64')
494 if templateName not in order:
495 order.insert(0, templateName)
496 order.insert(2, templateName[:-3])
497 else:
498 if templateName not in order:
499 order.insert(0, templateName)
500
501 for name in order:
502 template = self.getRRDTemplateByName(name)
503 if template:
504 return [template]
505
506 return []
507
508
510 """
511 Ignore interface that are administratively down.
512 """
513 # This must be based off the modeled admin status or zenhub could
514 # lock itself up while building configurations.
515 return self.adminStatus > 1 or self.monitor == False
516
517
519 """
520 Get the current administrative state of the interface. Prefer real-time
521 value over modeled value.
522 """
523 s = self.cacheRRDValue('ifAdminStatus', None)
524 if s is None: s = self.adminStatus
525 return s
526
527
529 """
530 Return the current administrative state of the interface converted to
531 its string version.
532 """
533 return {1: 'Up', 2: 'Down', 3: 'Testing'}.get(
534 self.getAdminStatus(), 'Unknown')
535
536
538 """
539 Get the current operational state of the interface. Prefer real-time
540 value over modeled value.
541 """
542 s = self.cacheRRDValue('ifOperStatus', None)
543 if s is None: s = self.operStatus
544 return s
545
546
548 """
549 Return the current operational state of the interface converted to
550 its string version.
551 """
552 return {
553 1: 'Up', 2: 'Down', 3: 'Testing', 5: 'Dormant', 6: 'Not Present',
554 7: 'Lower Layer Down'}.get(
555 self.getOperStatus(), 'Unknown')
556
557
559 """
560 Return the status number for this interface.
561 """
562 # Unknown status if we're not monitoring the interface.
563 if self.snmpIgnore():
564 return -1
565
566 return super(IpInterface, self).getStatus()
567
568
570 """
571 Return a string that expresses self.speed in reasonable units.
572 """
573 if not self.speed:
574 return 'Unknown'
575 speed = self.speed
576 for unit in ('bps', 'Kbps', 'Mbps', 'Gbps'):
577 if speed < 1000: break
578 speed /= 1000.0
579 return "%.3f%s" % (speed, unit)
580
582 """
583 The device id, for indexing purposes.
584 """
585 d = self.device()
586 if d: return d.getPrimaryId()
587 else: return None
588
594
600
611
612 InitializeClass(IpInterface)
613
615 if (event.object==ob or event.object==ob.device() or
616 getattr(event.object, "_operation", -1) < 1):
617 ob.unindex_object()
618
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1.1812 on Thu Sep 1 19:03:47 2011 | http://epydoc.sourceforge.net |