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 as published by 
  8  # 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.app.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.').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
169 - def _setPropValue(self, id, value):
170 """ 171 Override from PerpertyManager to handle checks and ip creation 172 """ 173 self._wrapperCheck(value) 174 if id == 'ips': 175 self.setIpAddresses(value) 176 else: 177 setattr(self,id,value) 178 if id == 'macaddress': 179 self.index_object()
180 181
182 - def index_object(self):
183 """ 184 Override the default so that links are indexed. 185 """ 186 super(IpInterface, self).index_object() 187 self.index_links()
188 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 197
198 - def manage_editProperties(self, REQUEST):
199 """ 200 Override from propertiyManager so we can trap errors 201 """ 202 try: 203 return ConfmonPropManager.manage_editProperties(self, REQUEST) 204 except IpAddressError, e: 205 return MessageDialog( 206 title = "Input Error", 207 message = e.args[0], 208 action = "manage_main")
209 210
211 - def __getattr__(self, name):
212 """ 213 Allow access to ipAddresses via the ips attribute 214 """ 215 if name == 'ips': 216 return self.getIpAddresses() 217 else: 218 raise AttributeError( name )
219 220
221 - def _prepIp(self, ip, netmask=24):
222 """ 223 Split ips in the format 1.1.1.1/24 into ip and netmask. 224 Default netmask is 24. 225 """ 226 iparray = ip.split("/") 227 if len(iparray) > 1: 228 ip = iparray[0] 229 checkip(ip) 230 netmask = maskToBits(iparray[1]) 231 return ip, netmask
232 233
234 - def addIpAddress(self, ip, netmask=24):
235 """ 236 Add an ip to the ipaddresses relationship on this interface. 237 """ 238 networks = self.device().getNetworkRoot() 239 ip, netmask = self._prepIp(ip, netmask) 240 #see if ip exists already and link it to interface 241 ipobj = networks.findIp(ip) 242 if ipobj: 243 dev = ipobj.device() 244 if dev and dev != self.device(): 245 log.warn("Adding IP Address %s to %s found it on device %s", 246 ip, self.getId(), dev.getId()) 247 self.ipaddresses.addRelation(ipobj) 248 #never seen this ip make a new one in correct subnet 249 else: 250 ipobj = networks.createIp(ip, netmask) 251 self.ipaddresses.addRelation(ipobj) 252 ipobj.index_links() 253 os = self.os() 254 notify(ObjectMovedEvent(self, os, self.id, os, self.id))
255 256 257
258 - def addLocalIpAddress(self, ip, netmask=24):
259 """ 260 Add a locally stored ip. Ips like 127./8 are maintained locally. 261 """ 262 (ip, netmask) = self._prepIp(ip, netmask) 263 ip = ip + '/' + str(netmask) 264 if not self._ipAddresses: self._ipAddresses = [] 265 if not ip in self._ipAddresses: 266 self._ipAddresses = self._ipAddresses + [ip,]
267 268
269 - def clearIps(self, ips):
270 """ 271 If no IPs are sent remove all in the relation 272 """ 273 if not ips: 274 self.removeRelation('ipaddresses') 275 return True
276 277
278 - def setIpAddresses(self, ips):
279 """ 280 Set a list of ipaddresses in the form 1.1.1.1/24 on to this 281 interface. If networks for the ips don't exist they will be created. 282 """ 283 if type(ips) == type(''): ips = [ips,] 284 if self.clearIps(ips): return 285 286 ipids = self.ipaddresses.objectIdsAll() 287 localips = copy.copy(self._ipAddresses) 288 for ip in ips: 289 if localIpCheck(self, ip) or localInterfaceCheck(self, self.id): 290 if not ip in localips: 291 self.addLocalIpAddress(ip) 292 else: 293 localips.remove(ip) 294 else: 295 # do this funky filtering because the id we have 296 # is a primary id /zport/dmd/Newtowrks... etc 297 # and we are looking for just the IP part 298 # we used the full id later when deleting the IPs 299 rawip = ipFromIpMask(ip) 300 ipmatch = filter(lambda x: x.find(rawip) > -1, ipids) 301 if not ipmatch: 302 self.addIpAddress(ip) 303 elif len(ipmatch) == 1: 304 ipids.remove(ipmatch[0]) 305 306 307 #delete ips that are no longer in use 308 for ip in ipids: 309 ipobj = self.ipaddresses._getOb(ip) 310 self.removeRelation('ipaddresses', ipobj) 311 ipobj.index_links() 312 for ip in localips: 313 self._ipAddresses.remove(ip)
314 315
316 - def removeIpAddress(self, ip):
317 """ 318 Remove an ipaddress from this interface. 319 """ 320 for ipobj in self.ipaddresses(): 321 if ipobj.id == ip: 322 self.ipaddresses.removeRelation(ipobj) 323 ipobj.index_links() 324 return
325 326
327 - def getIp(self):
328 """ 329 Return the first ip for this interface in the form: 1.1.1.1. 330 """ 331 if self.ipaddresses.countObjects(): 332 return self.ipaddresses()[0].getIp() 333 elif len(self._ipAddresses): 334 return self._ipAddresses[0].split('/')[0]
335 336
337 - def getIpSortKey(self):
338 """ 339 Return the ipaddress as a 32bit integter for sorting purposes. 340 """ 341 if self.ipaddresses.countObjects(): 342 return self.ipaddresses()[0].primarySortKey() 343 elif len(self._ipAddresses): 344 return numbip(self._ipAddresses[0].split('/')[0])
345 346
347 - def getIpAddress(self):
348 """ 349 Return the first ipaddress with its netmask ie: 1.1.1.1/24. 350 """ 351 if self.ipaddresses.countObjects(): 352 return self.ipaddresses()[0].getIpAddress() 353 elif len(self._ipAddresses): 354 return self._ipAddresses[0]
355 356
357 - def getIpAddressObj(self):
358 """ 359 Return the first real ipaddress object or None if none are found. 360 """ 361 if len(self.ipaddresses()): 362 return self.ipaddresses()[0]
363 364
365 - def getIpAddressObjs(self):
366 """ 367 Return a list of the ip objects on this interface. 368 """ 369 retval=[] 370 for ip in self.ipaddresses.objectValuesAll(): 371 retval.append(ip) 372 for ip in self._ipAddresses: 373 retval.append(ip) 374 return retval
375 376
377 - def getIpAddresses(self):
378 """ 379 Return list of ip addresses as strings in the form 1.1.1.1/24. 380 """ 381 return map(str, self.getIpAddressObjs())
382 383
384 - def getNetwork(self):
385 """ 386 Return the network for the first ip on this interface. 387 """ 388 if self.ipaddresses.countObjects(): 389 return self.ipaddresses()[0].network()
390 391
392 - def getNetworkName(self):
393 """ 394 Return the network name for the first ip on this interface. 395 """ 396 net = self.getNetwork() 397 if net: return net.getNetworkName() 398 return ""
399 400 415 416 435 436 437 security.declareProtected('View', 'getInterfaceName')
438 - def getInterfaceName(self):
439 """ 440 Return the name of this interface. 441 """ 442 if self.interfaceName: return self.interfaceName 443 elif self.viewName(): return self.viewName() 444 else: return "None"
445 446 447 security.declareProtected('View', 'getInterfaceMacaddress')
448 - def getInterfaceMacaddress(self):
449 """ 450 Return the mac address of this interface. 451 """ 452 return self.macaddress
453 454
455 - def getRRDTemplateName(self):
456 """ 457 Return the interface type as the target type name. 458 """ 459 return self.prepId(self.type or "Unknown")
460 461
462 - def getRRDTemplates(self):
463 """ 464 Return a list containing the appropriate RRDTemplate for this 465 IpInterface. If none is found then the list will be empty. 466 467 Order of preference if the interface supports 64bit counters. 468 1. <type>_64 469 2. ethernetCsmacd_64 470 3. <type> 471 4. ethernetCsmacd 472 473 Order of preference if the interface doesn't support 64bit counters. 474 1. <type> 475 2. ethernetCsmacd 476 """ 477 templateName = self.getRRDTemplateName() 478 479 order = ['ethernetCsmacd'] 480 if templateName.endswith('_64'): 481 order.insert(0, 'ethernetCsmacd_64') 482 if templateName not in order: 483 order.insert(0, templateName) 484 order.insert(2, templateName[:-3]) 485 else: 486 if templateName not in order: 487 order.insert(0, templateName) 488 489 for name in order: 490 template = self.getRRDTemplateByName(name) 491 if template: 492 return [template] 493 494 return []
495 496
497 - def snmpIgnore(self):
498 """ 499 Ignore interface that are administratively down. 500 """ 501 # This must be based off the modeled admin status or zenhub could 502 # lock itself up while building configurations. 503 return self.adminStatus > 1 or self.monitor == False
504 505
506 - def getAdminStatus(self):
507 """ 508 Get the current administrative state of the interface. Prefer real-time 509 value over modeled value. 510 """ 511 s = self.cacheRRDValue('ifAdminStatus', None) 512 if s is None: s = self.adminStatus 513 return s
514 515
516 - def getOperStatus(self):
517 """ 518 Get the current operational state of the interface. Prefer real-time 519 value over modeled value. 520 """ 521 s = self.cacheRRDValue('ifOperStatus', None) 522 if s is None: s = self.operStatus 523 return s
524 525
526 - def getStatus(self, statClass=None):
527 """ 528 Return the status number for this interface. 529 """ 530 # Unknown status if we're not monitoring the interface. 531 if self.snmpIgnore(): 532 return -1 533 534 return super(IpInterface, self).getStatus()
535 536
537 - def niceSpeed(self):
538 """ 539 Return a string that expresses self.speed in reasonable units. 540 """ 541 if not self.speed: 542 return 'Unknown' 543 speed = self.speed 544 for unit in ('bps', 'Kbps', 'Mbps', 'Gbps'): 545 if speed < 1000: break 546 speed /= 1000.0 547 return "%.3f%s" % (speed, unit)
548
549 - def deviceId(self):
550 """ 551 The device id, for indexing purposes. 552 """ 553 d = self.device() 554 if d: return d.getPrimaryId() 555 else: return None
556
557 - def interfaceId(self):
558 """ 559 The interface id, for indexing purposes. 560 """ 561 return self.getPrimaryId()
562
563 - def lanId(self):
564 """ 565 pass 566 """ 567 return 'None'
568
569 - def niceDuplex(self):
570 """ 571 Return a string that expresses self.duplex into human readable format. 572 """ 573 574 if self.duplex == 2: 575 return 'halfDuplex' 576 elif self.duplex == 3: 577 return 'fullDuplex' 578 return 'unknown'
579 580 InitializeClass(IpInterface) 581
582 -def beforeDeleteIpInterface(ob, event):
583 if (event.object==ob or event.object==ob.device() or 584 getattr(event.object, "_operation", -1) < 1): 585 ob.unindex_object()
586