Package Products :: Package ZenHub :: Module invalidationfilter |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenHub.invalidationfilter

      1  ##############################################################################
      2  #
      3  # Copyright (C) Zenoss, Inc. 2011, 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  import re
     12  from hashlib import md5
     13  import logging
     14  from cStringIO import StringIO
     15  from zope.interface import implements
     16  from Products.ZenModel.DeviceClass import DeviceClass
     17  from Products.ZenModel.IpAddress import IpAddress
     18  from Products.ZenModel.IpNetwork import IpNetwork
     19  from Products.ZenModel.OSProcessOrganizer import OSProcessOrganizer
     20  from Products.ZenModel.OSProcessClass import OSProcessClass
     21  from Products.Zuul.interfaces import ICatalogTool
     22
     23  from .interfaces import IInvalidationFilter, FILTER_EXCLUDE, FILTER_CONTINUE
     24
     25  log = logging.getLogger('zen.InvalidationFilter')
     26
     27
     28 -class IpInvalidationFilter(object):
     29      implements(IInvalidationFilter)
     30
     31 -    def initialize(self, context):
     32          pass
     33
     34 -    def include(self, obj):
     35          if isinstance(obj, (IpAddress, IpNetwork)):
     36              return FILTER_EXCLUDE
     37          return FILTER_CONTINUE
     38
     39
     40 -class BaseOrganizerFilter(object):
     41      """
     42      Base invalidation filter for organizers. Calculates a checksum for
     43      the organizer based on its sorted z/c properties.
     44      """
     45      implements(IInvalidationFilter)
     46
     47      weight = 10
     48      iszorcustprop = re.compile("^[zc][A-Z]").search
     49
     50 -    def __init__(self, types):
     51          self._types = types
     52
     53 -    def getRoot(self, context):
     54          return context.dmd.primaryAq()
     55
     56 -    def initialize(self, context):
     57          root = self.getRoot(context)
     58          brains = ICatalogTool(root).search(self._types)
     59          results = {}
     60          for brain in brains:
     61              obj = brain.getObject()
     62              results[brain.getPath()] = self.organizerChecksum(obj)
     63          self.checksum_map = results
     64
     65 -    def getZorCProperties(self, organizer):
     66          for zId in sorted(organizer.zenPropertyIds(pfilt=self.iszorcustprop)):
     67              if organizer.zenPropIsPassword(zId):
     68                  propertyString = organizer.getProperty(zId, '')
     69              else:
     70                  propertyString = organizer.zenPropertyString(zId)
     71              yield zId, propertyString
     72
     73 -    def generateChecksum(self, organizer, md5_checksum):
     74          # Checksum all zProperties and custom properties
     75          for zId, propertyString in self.getZorCProperties(organizer):
     76              md5_checksum.update('%s|%s' % (zId, propertyString))
     77
     78 -    def organizerChecksum(self, organizer):
     79          m = md5()
     80          self.generateChecksum(organizer, m)
     81          return m.hexdigest()
     82
     83 -    def include(self, obj):
     84          # Move on if it's not one of our types
     85          if not isinstance(obj, self._types):
     86              return FILTER_CONTINUE
     87
     88          # Checksum the device class
     89          current_checksum = self.organizerChecksum(obj)
     90          organizer_path = '/'.join(obj.getPrimaryPath())
     91
     92          # Get what we have right now and compare
     93          existing_checksum = self.checksum_map.get(organizer_path)
     94          if current_checksum != existing_checksum:
     95              log.debug('%r has a new checksum! Including.', obj)
     96              self.checksum_map[organizer_path] = current_checksum
     97              return FILTER_CONTINUE
     98          log.debug('%r checksum unchanged. Skipping.', obj)
     99          return FILTER_EXCLUDE
    100
    101
    102 -class DeviceClassInvalidationFilter(BaseOrganizerFilter):
    103      """
    104      Subclass of BaseOrganizerFilter with specific logic for
    105      Device classes. Uses both z/c properties as well as locally
    106      bound RRD templates to create the checksum.
    107      """
    108
    109 -    def __init__(self):
    110          super(DeviceClassInvalidationFilter, self).__init__((DeviceClass,))
    111
    112 -    def getRoot(self, context):
    113          return context.dmd.Devices.primaryAq()
    114
    115 -    def generateChecksum(self, organizer, md5_checksum):
    116          """
    117          Generate a checksum representing the state of the device class as it
    118          pertains to configuration. This takes into account templates and
    119          zProperties, nothing more.
    120          """
    121          s = StringIO()
    122          # Checksum includes all bound templates
    123          for tpl in organizer.rrdTemplates():
    124              s.seek(0)
    125              s.truncate()
    126              # TODO: exportXml is a bit of a hack. Sorted, etc. would be better.
    127              tpl.exportXml(s)
    128              md5_checksum.update(s.getvalue())
    129          # Include z/c properties from base class
    130          super(DeviceClassInvalidationFilter, self).generateChecksum(organizer, md5_checksum)
    131
    132
    133 -class OSProcessOrganizerFilter(BaseOrganizerFilter):
    134      """
    135      Invalidation filter for OSProcessOrganizer objects. This filter only
    136      looks at z/c properties defined on the organizer.
    137      """
    138
    139 -    def __init__(self):
    140          super(OSProcessOrganizerFilter, self).__init__((OSProcessOrganizer,))
    141
    142 -    def getRoot(self, context):
    143          return context.dmd.Processes.primaryAq()
    144
    145
    146 -class OSProcessClassFilter(BaseOrganizerFilter):
    147      """
    148      Invalidation filter for OSProcessClass objects. This filter uses
    149      z/c properties as well as local _properties defined on the organizer
    150      to create a checksum.
    151      """
    152
    153 -    def __init__(self):
    154          super(OSProcessClassFilter, self).__init__((OSProcessClass,))
    155
    156 -    def getRoot(self, context):
    157          return context.dmd.Processes.primaryAq()
    158
    159 -    def generateChecksum(self, organizer, md5_checksum):
    160          # Include properties of OSProcessClass
    161          for prop in organizer._properties:
    162              prop_id = prop['id']
    163              md5_checksum.update("%s|%s" % (prop_id, getattr(organizer, prop_id, '')))
    164          # Include z/c properties from base class
    165          super(OSProcessClassFilter, self).generateChecksum(organizer, md5_checksum)
    166