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

# Source Code for Module Products.ZenModel.IpInterface

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