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