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 { 'id' : 'viewHistory' 142 , 'name' : 'Modifications' 143 , 'action' : 'viewHistory' 144 , 'permissions' : (ZEN_VIEW_MODIFICATIONS,) 145 }, 146 ) 147 }, 148 ) 149 150 security = ClassSecurityInfo() 151
152 - def __init__(self, id, title = None):
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')
161 - def viewName(self):
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
168 - def _setPropValue(self, id, value):
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
180 - def index_object(self, idxs=None):
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
190 - def unindex_object(self):
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
200 - def manage_deleteComponent(self, REQUEST=None):
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
210 - def manage_editProperties(self, REQUEST):
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
223 - def __getattr__(self, name):
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
233 - def _prepIp(self, ip, netmask=24):
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
246 - def addIpAddress(self, ip, netmask=24):
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
270 - def addLocalIpAddress(self, ip, netmask=24):
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
281 - def clearIps(self, ips):
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
290 - def setIpAddresses(self, ips):
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
328 - def removeIpAddress(self, ip):
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
339 - def getIp(self):
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
349 - def getIpSortKey(self):
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
359 - def getIpAddress(self):
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
369 - def getIpAddressObj(self):
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
377 - def getIpAddressObjs(self):
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
389 - def getIpAddresses(self):
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
396 - def getNetwork(self):
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
404 - def getNetworkName(self):
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 427 428 447 448 449 security.declareProtected('View', 'getInterfaceName')
450 - def getInterfaceName(self):
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')
460 - def getInterfaceMacaddress(self):
461 """ 462 Return the mac address of this interface. 463 """ 464 return self.macaddress
465 466
467 - def getRRDTemplateName(self):
468 """ 469 Return the interface type as the target type name. 470 """ 471 return self.prepId(self.type or "Unknown")
472 473
474 - def getRRDTemplates(self):
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
509 - def snmpIgnore(self):
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
518 - def getAdminStatus(self):
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
528 - def getAdminStatusString(self):
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
537 - def getOperStatus(self):
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
547 - def getOperStatusString(self):
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
558 - def getStatus(self, statClass=None):
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
569 - def niceSpeed(self):
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
581 - def deviceId(self):
582 """ 583 The device id, for indexing purposes. 584 """ 585 d = self.device() 586 if d: return d.getPrimaryId() 587 else: return None
588
589 - def interfaceId(self):
590 """ 591 The interface id, for indexing purposes. 592 """ 593 return self.getPrimaryId()
594
595 - def lanId(self):
596 """ 597 pass 598 """ 599 return 'None'
600
601 - def niceDuplex(self):
602 """ 603 Return a string that expresses self.duplex into human readable format. 604 """ 605 606 if self.duplex == 2: 607 return 'halfDuplex' 608 elif self.duplex == 3: 609 return 'fullDuplex' 610 return 'unknown'
611 612 InitializeClass(IpInterface) 613
614 -def beforeDeleteIpInterface(ob, event):
615 if (event.object==ob or event.object==ob.device() or 616 getattr(event.object, "_operation", -1) < 1): 617 ob.unindex_object()
618