Package Products :: Package ZenModel :: Module IpInterface
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenModel.IpInterface

  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   
45 -def manage_addIpInterface(context, newId, userCreated, REQUEST = None):
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
61 -class IpInterface(OSComponent, Layer2Linkable):
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
147 - def __init__(self, id, title = None):
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')
156 - def viewName(self):
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
163 - def _setPropValue(self, id, value):
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
175 - def index_object(self, idxs=None):
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
185 - def unindex_object(self):
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
195 - def manage_deleteComponent(self, REQUEST=None):
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
205 - def manage_editProperties(self, REQUEST):
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
218 - def __getattr__(self, name):
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
228 - def _prepIp(self, ip, netmask=24):
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
241 - def addIpAddress(self, ip, netmask=24):
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
265 - def addLocalIpAddress(self, ip, netmask=24):
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
276 - def clearIps(self, ips):
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
285 - def setIpAddresses(self, ips):
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
323 - def removeIpAddress(self, ip):
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
334 - def getIp(self):
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
344 - def getIpSortKey(self):
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
354 - def getIpAddress(self):
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
364 - def getIpAddressObj(self):
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
372 - def getIpAddressObjs(self):
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
384 - def getIpAddresses(self):
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
391 - def getNetwork(self):
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
399 - def getNetworkName(self):
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 422 423 442 443 444 security.declareProtected('View', 'getInterfaceName')
445 - def getInterfaceName(self):
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')
455 - def getInterfaceMacaddress(self):
456 """ 457 Return the mac address of this interface. 458 """ 459 return self.macaddress
460 461
462 - def getRRDTemplateName(self):
463 """ 464 Return the interface type as the target type name. 465 """ 466 return self.prepId(self.type or "Unknown")
467 468
469 - def getRRDTemplates(self):
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
504 - def snmpIgnore(self):
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
513 - def getAdminStatus(self):
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
523 - def getAdminStatusString(self):
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
532 - def getOperStatus(self):
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
542 - def getOperStatusString(self):
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
553 - def getStatus(self, statClass=None):
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
564 - def niceSpeed(self):
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
576 - def deviceId(self):
577 """ 578 The device id, for indexing purposes. 579 """ 580 d = self.device() 581 if d: return d.getPrimaryId() 582 else: return None
583
584 - def interfaceId(self):
585 """ 586 The interface id, for indexing purposes. 587 """ 588 return self.getPrimaryId()
589
590 - def lanId(self):
591 """ 592 pass 593 """ 594 return 'None'
595
596 - def niceDuplex(self):
597 """ 598 Return a string that expresses self.duplex into human readable format. 599 """ 600 601 if self.duplex == 2: 602 return 'halfDuplex' 603 elif self.duplex == 3: 604 return 'fullDuplex' 605 return 'unknown'
606 607 InitializeClass(IpInterface) 608
609 -def beforeDeleteIpInterface(ob, event):
610 if (event.object==ob or event.object==ob.device() or 611 getattr(event.object, "_operation", -1) < 1): 612 ob.unindex_object()
613