Beispiel #1
0
 def _loadThresholdClasses(self, thresholdClasses):
     self.log.debug("Loading classes %s", thresholdClasses)
     for c in thresholdClasses:
         try:
             importClass(c)
         except ImportError:
             log.exception("Unable to import class %s", c)
Beispiel #2
0
    def _getService(self, name, instance):
        """Utility method to create the service (like PingConfig)
        for instance (like localhost)

        @type name: string
        @param name: the dotted-name of the module to load
        (uses @L{Products.ZenUtils.Utils.importClass})
        @param instance: string
        @param instance: each service serves only one specific collector instances (like 'localhost').  instance defines the collector's instance name.
        @return: a service loaded from ZenHub/services or one of the zenpacks.
        """
        try:
            return self.services[name, instance]
        except KeyError:
            from Products.ZenUtils.Utils import importClass
            try:
                ctor = importClass(name)
            except ImportError:
                ctor = importClass('Products.ZenHub.services.%s' % name, name)
            svc = ctor(self.dmd, instance)
            self.services[name, instance] = svc

            # dict for tracking statistics on method calls invoked on this service,
            # including number of times called and total elapsed time, keyed
            # by method name
            svc.callStats = defaultdict(_CumulativeWorkerStats)

            return svc
Beispiel #3
0
    def _getService(self, name, instance):
        """Utility method to create the service (like PingConfig)
        for instance (like localhost)

        @type name: string
        @param name: the dotted-name of the module to load
        (uses @L{Products.ZenUtils.Utils.importClass})
        @param instance: string
        @param instance: each service serves only one specific collector instances (like 'localhost').  instance defines the collector's instance name.
        @return: a service loaded from ZenHub/services or one of the zenpacks.
        """
        try:
            return self.services[name, instance]
        except KeyError:
            from Products.ZenUtils.Utils import importClass
            try:
                ctor = importClass(name)
            except ImportError:
                ctor = importClass('Products.ZenHub.services.%s' % name, name)
            svc = ctor(self.dmd, instance)
            self.services[name, instance] = svc

            # dict for tracking statistics on method calls invoked on this service,
            # including number of times called and total elapsed time, keyed
            # by method name
            svc.callStats = defaultdict(_CumulativeWorkerStats)

            return svc
Beispiel #4
0
 def _importPluginClass(self, name):
     """
     Find the named plugin and import it.
     """
     klass = None
     if name.startswith('/'):
         if name.endswith('.py'):
             name = name.replace('.py', '')
         if os.path.exists(name + '.py'):
             try:
                 d, name = name.rsplit('/', 1)
                 sys.path.insert(0, d)
                 klass = importClass(name)
             finally:
                 sys.path.remove(d)
     else:
         for d in self._getPluginDirectories():
             if os.path.exists('%s/%s.py' % (d, name)):
                 try:
                     sys.path.insert(0, d)
                     klass = importClass(name)
                     break
                 finally:
                     sys.path.remove(d)
     return klass
Beispiel #5
0
 def _loadThresholdClasses(self, thresholdClasses):
     self.log.debug("Loading classes %s", thresholdClasses)
     for c in thresholdClasses:
         try:
             importClass(c)
         except ImportError:
             log.exception("Unable to import class %s", c)
Beispiel #6
0
 def remote_updateThresholdClasses(self, classes):
     from Products.ZenUtils.Utils import importClass
     self.log.debug("Loading classes %s", classes)
     for c in classes:
         try:
             importClass(c)
         except ImportError:
             self.log.error("Unable to import class %s", c)
Beispiel #7
0
 def remote_updateThresholdClasses(self, classes):
     from Products.ZenUtils.Utils import importClass
     self.log.debug("Loading classes %s", classes)
     for c in classes:
         try:
             importClass(c)
         except ImportError:
             self.log.error("Unable to import class %s", c)
Beispiel #8
0
    def migrate(self, previousVersion=None):
        """
        Migrate to a new version

        @param previousVersion: previous version number
        @type previousVersion: string
        """
        instances = []
        # find all the migrate modules
        root = self.path("migrate")
        for p, ds, fs in os.walk(root):
            for f in fs:
                if f.endswith('.py') and not f.startswith("__"):
                    path = os.path.join(p[len(root) + 1:], f)
                    log.debug("Loading %s", path)
                    sys.path.insert(0, p)
                    try:
                        try:
                            c = importClass(path[:-3].replace("/", "."))
                            instances.append(c())
                        finally:
                            sys.path.remove(p)
                    except ImportError, ex:
                        log.exception("Problem loading migration step %s",
                                      path)
 def testClassLoading(self):
     """
     Test that the class can be imported from the module dynamically
     """
     moduleName = "ZenPacks.zenoss.NtpMonitor.datasources.NtpMonitorDataSource"
     className = "NtpMonitorDataSource"
     constructor = importClass(moduleName, className)
     self.assert_(constructor is not None)
Beispiel #10
0
    def createObject(self, attrs):
        """
        Create an object and set it into its container

        @param attrs: attrs
        @type attrs: string
        @return: newly created object
        @rtype: object
        """
        # Does the object exist already?
        id = attrs.get('id')
        obj = None
        try:
            if id.startswith('/'):
                obj = getObjByPath2(self.app, id)
            else:
                obj = self.context()._getOb(id)
        except (KeyError, AttributeError, NotFound):
            pass

        if obj is None:
            klass = importClass(attrs.get('module'), attrs.get('class'))
            if id.find('/') > -1:
                (contextpath, id) = os.path.split(id)
                try:
                    pathobj = getObjByPath(self.context(), contextpath)
                except (KeyError, AttributeError, NotFound):
                    self.log.warn( "Unable to find context path %s (line %s ?) for %s" % (
                        contextpath, self._locator.getLineNumber(), id ))
                    if not self.options.noCommit:
                        self.log.warn( "Not committing any changes" )
                        self.options.noCommit = True
                    return None
                self.objstack.append(pathobj)
            self.log.debug('Building instance %s of class %s',id,klass.__name__)
            try:
                if klass.__name__ == 'AdministrativeRole':
                    user = [x for x in self.dmd.ZenUsers.objectValues() if x.id == id]
                    if user:
                        obj = klass(user[0], self.context().device())
                    else:
                        msg = "No AdminRole user %s exists (line %s)" % (
                                       id, self._locator.getLineNumber())
                        self.log.error(msg)
                        raise Exception(msg)
                else:
                    obj = klass(id)
            except TypeError, ex:
                # This happens when the constructor expects more arguments
                self.log.exception("Unable to build %s instance of class %s (line %s)",
                                   id, klass.__name__, self._locator.getLineNumber())
                raise
            self.context()._setObject(obj.id, obj)
            obj = self.context()._getOb(obj.id)
            self.objectnumber += 1
            self.uncommittedObjects += 1
            self.log.debug('Added object %s to database'
                            % obj.getPrimaryId())
Beispiel #11
0
    def getService(self, name, instance):
        """
        Helper method to load services dynamically for a collector.
        Returned instances are cached: reconnecting collectors will
        get the same service object.

        @type name: string
        @param name: the dotted-name of the module to load
        (uses @L{Products.ZenUtils.Utils.importClass})
        @param instance: string
        @param instance: each service serves only one specific collector
        instances (like 'localhost').  instance defines the collector's
        instance name.
        @return: a service loaded from ZenHub/services or one of the zenpacks.
        """
        # Sanity check the names given to us
        if not self.dmd.Monitors.Performance._getOb(instance, False):
            raise RemoteBadMonitor(
                "The provided performance monitor '%s'" % instance +
                " is not in the current list", None)

        try:
            return self.services[name, instance]

        except KeyError:
            from Products.ZenUtils.Utils import importClass
            try:
                ctor = importClass(name)
            except ImportError:
                ctor = importClass('Products.ZenHub.services.%s' % name, name)
            try:
                svc = ctor(self.dmd, instance)
            except Exception:
                self.log.exception("Failed to initialize %s", ctor)
                # Module can't be used, so unload it.
                if ctor.__module__ in sys.modules:
                    del sys.modules[ctor.__module__]
                return None
            else:
                if self.options.workers:
                    svc = WorkerInterceptor(self, svc)
                self.services[name, instance] = svc
                notify(ServiceAddedEvent(name, instance))
                return svc
Beispiel #12
0
    def _createRelObject(self, device, objmap, relname):
        """Create an object on a relationship using its objmap.
        """
        constructor = importClass(objmap.modname, objmap.classname)
        if hasattr(objmap, 'id'):
            remoteObj = constructor(objmap.id)
        else:
            remoteObj = constructor(device, objmap)
        if remoteObj is None:
            log.debug("Constructor returned None")
            return False, None
        id = remoteObj.id
        if not remoteObj:
            raise ObjectCreationError(
                "failed to create object %s in relation %s" % (id, relname))

        realdevice = device.device()
        if realdevice.isLockedFromUpdates():
            objtype = ""
            try:
                objtype = objmap.modname.split(".")[-1]
            except:
                pass
            msg = "Add Blocked: %s '%s' on %s" % (objtype, id, realdevice.id)
            log.warn(msg)
            if realdevice.sendEventWhenBlocked():
                self.logEvent(realdevice, id, Change_Add_Blocked, msg,
                              Event.Warning)
            return False, None
        rel = device._getOb(relname, None)
        if not rel:
            raise ObjectCreationError(
                "No relation %s found on device %s (%s)" %
                (relname, device.id, device.__class__))
            #"No relation %s found on device %s" % (relname, device.id))
        changed = False
        try:
            remoteObj = rel._getOb(remoteObj.id)
        except AttributeError:
            self.logChange(
                realdevice, remoteObj, Change_Add,
                "adding object %s to relationship %s" %
                (remoteObj.id, relname))
            rel._setObject(remoteObj.id, remoteObj)
            remoteObj = rel._getOb(remoteObj.id)
            changed = True
            if not isinstance(rel, ToManyContRelationship):
                notify(
                    ObjectMovedEvent(remoteObj, rel, remoteObj.id, rel,
                                     remoteObj.id))
        up_changed = self._updateObject(remoteObj, objmap)
        self.num_obj_changed += 1 if not up_changed and changed else 0
        return up_changed or changed, remoteObj
 def getTargetPythonClass(self):
     """
     Returns the python class object that this template can be bound to.
     """
     from Products.ZenModel.Device import Device
     cname = getattr(self, "targetPythonClass", None)
     if cname:
         try:
             return importClass(cname)
         except ImportError:
             log.exception("Unable to import class " + cname)
     return Device
Beispiel #14
0
 def getTargetPythonClass(self):
     """
     Returns the python class object that this template can be bound to.
     """
     from Products.ZenModel.Device import Device
     cname = getattr(self, "targetPythonClass", None)
     if cname:
         try:
             return importClass(cname)
         except ImportError:
             log.exception("Unable to import class " + cname)
     return Device
Beispiel #15
0
    def run(self):
        service = self.options.service
        if not service:
            raise RuntimeError("You must specify a service")

        try:
            cls = importClass(service)
        except ImportError:
            path = os.path.abspath(service)
            if os.path.isfile(service):
                dir_ = os.path.dirname(path)
                sys.path.append(dir_)
                name = re.findall(r"/?([A-Za-z]+[A-Za-z0-9])*\.", service)[0]
                cls = importClass(name)

        service = cls(self.dmd, "localhost")
        method = getattr(service, self.options.method)
        results = method(self.args)

        for result in results:
            pp(vars(result))
Beispiel #16
0
 def __addservice(self, name, monitor):
     try:
         cls = importClass(name)
     except ImportError:
         try:
             cls = importClass("Products.ZenHub.services.%s" % name, name)
         except ImportError:
             raise UnknownServiceError(str(name))
     try:
         # Will it construct/initialize?
         svc = cls(self.__dmd, monitor)
     except Exception:
         # Module can't be used, so unload it.
         if cls.__module__ in sys.modules:
             del sys.modules[cls.__module__]
         raise
     else:
         svc = self.__factory.build(svc, name, monitor)
         self.__services[name, monitor] = svc
         notify(ServiceAddedEvent(name, monitor))
         return svc
 def get_imported_class(self, classname):
     """import target class by reference"""
     # this might be provided by the ZenPack but not defined in the YAML
     if '.' not in classname:
         classname = '{}.{}.{}'.format(self.zenpack_spec.name, classname, classname)
     if '.' in classname and classname.split('.')[-1] not in self.zenpack_spec.classes:
         module = ".".join(classname.split('.')[0:-1])
         try:
             kls = importClass(module)
             self.zenpack_spec.imported_classes[classname] = kls
         except ImportError as e:
             self.LOG.error('Failed to import class {} from {} ({})'.format(classname, module, e))
             pass
Beispiel #18
0
 def _getClassesByPath(self, name):
     dsClasses = []
     for path, dirs, files in os.walk(self.path(name)):
         dirs[:] = [d for d in dirs if not d.startswith('.')]
         for f in files:
             if not f.startswith('.') \
                     and f.endswith('.py') \
                     and not f == '__init__.py':
                 subPath = path[len(self.path()):]
                 parts = subPath.strip('/').split('/')
                 parts.append(f[:f.rfind('.')])
                 modName = '.'.join([self.moduleName()] + parts)
                 dsClasses.append(importClass(modName))
     return dsClasses
Beispiel #19
0
 def _getClassesByPath(self, name):
     dsClasses = []
     for path, dirs, files in os.walk(self.path(name)):
         dirs[:] = [d for d in dirs if not d.startswith('.')]
         for f in files:
             if not f.startswith('.') \
                     and f.endswith('.py') \
                     and not f == '__init__.py':
                 subPath = path[len(self.path()):]
                 parts = subPath.strip('/').split('/')
                 parts.append(f[:f.rfind('.')])
                 modName = '.'.join([self.moduleName()] + parts)
                 dsClasses.append(importClass(modName))
     return dsClasses
 def get_imported_class(self, classname):
     """import target class by reference"""
     # this might be provided by the ZenPack but not defined in the YAML
     if '.' not in classname:
         classname = '{}.{}.{}'.format(self.zenpack_spec.name, classname,
                                       classname)
     if '.' in classname and classname.split(
             '.')[-1] not in self.zenpack_spec.classes:
         module = ".".join(classname.split('.')[0:-1])
         try:
             kls = importClass(module)
             self.zenpack_spec.imported_classes[classname] = kls
         except ImportError as e:
             self.LOG.error('Failed to import class {} from {} ({})'.format(
                 classname, module, e))
             pass
Beispiel #21
0
    def _createRelObject(self, device, objmap, relname):
        """Create an object on a relationship using its objmap.
        """
        constructor = importClass(objmap.modname, objmap.classname)
        if hasattr(objmap, 'id'):
            remoteObj = constructor(objmap.id)
        else:
            remoteObj = constructor(device, objmap)
        if remoteObj is None:
            log.debug("Constructor returned None")
            return False, None
        id = remoteObj.id
        if not remoteObj:
            raise ObjectCreationError(
                    "failed to create object %s in relation %s" % (id, relname))

        realdevice = device.device()
        if realdevice.isLockedFromUpdates():
            objtype = ""
            try: objtype = objmap.modname.split(".")[-1]
            except Exception: pass
            msg = "Add Blocked: %s '%s' on %s" % (
                    objtype, id, realdevice.id)
            log.warn(msg)
            if realdevice.sendEventWhenBlocked():
                self.logEvent(realdevice, id, Change_Add_Blocked,
                                msg, Event.Warning)
            return False, None
        rel = device._getOb(relname, None)
        if not rel:
            raise ObjectCreationError(
                    "No relation %s found on object %s (%s)" % (relname, device.id, device.__class__ ))
        changed = False
        try:
            remoteObj = rel._getOb(remoteObj.id)
        except AttributeError:
            self.logChange(realdevice, remoteObj, Change_Add,
                           "adding object %s to relationship %s" %
                           (remoteObj.id, relname))
            rel._setObject(remoteObj.id, remoteObj)
            remoteObj = rel._getOb(remoteObj.id)
            changed = True
            if not isinstance(rel, ToManyContRelationship):
                notify(ObjectMovedEvent(remoteObj, rel, remoteObj.id, rel, remoteObj.id))
        up_changed = self._updateObject(remoteObj, objmap)
        self.num_obj_changed += 1 if not up_changed and changed else 0
        return up_changed or changed, remoteObj
Beispiel #22
0
def _create_object(object_map, parent_device=None):
    '''Create a new zodb object from an ObjectMap
    '''
    parent = getattr(object_map, '_parent', None)
    constructor = importClass(object_map.modname, object_map.classname)

    if hasattr(object_map, 'id'):
        new_object = constructor(object_map.id)
    elif parent:
        new_object = constructor(parent, object_map)
    elif parent_device:
        new_object = constructor(parent_device, object_map)
    else:
        log.error('_create_object requires object_map.id or parent_device')
        new_object = None

    return new_object
Beispiel #23
0
    def getPythonDeviceClass(self):
        """
        Return the Python class object to be used for device instances in this
        device class.  This is done by walking up the aq_chain of a deviceclass
        to find a node that has the same name as a Python class or has an
        attribute named zPythonClass that matches a Python class.

        @return: device class
        @rtype: device class
        """
        from Device import Device
        cname = getattr(self, "zPythonClass", None)
        if cname:
            try:
                return importClass(cname)
            except ImportError:
                log.exception("Unable to import class " + cname)
        return Device
Beispiel #24
0
    def getPythonDeviceClass(self):
        """
        Return the Python class object to be used for device instances in this
        device class.  This is done by walking up the aq_chain of a deviceclass
        to find a node that has the same name as a Python class or has an
        attribute named zPythonClass that matches a Python class.

        @return: device class
        @rtype: device class
        """
        from Device import Device
        cname = getattr(self, "zPythonClass", None)
        if cname:
            try:
                return importClass(cname)
            except ImportError:
                log.exception("Unable to import class " + cname)
        return Device
Beispiel #25
0
    def migrate(self, previousVersion=None):
        """
        Migrate to a new version

        @param previousVersion: previous version number
        @type previousVersion: string
        """
        instances = []
        # find all the migrate modules
        root = self.path("migrate")
        for p, ds, fs in os.walk(root):
            for f in fs:
                if f.endswith('.py') and not f.startswith("__"):
                    path = os.path.join(p[len(root) + 1:], f)
                    log.debug("Loading %s", path)
                    sys.path.insert(0, p)
                    try:
                        try:
                            c = importClass(path[:-3].replace("/", "."))
                            instances.append(c())
                        finally:
                            sys.path.remove(p)
                    except ImportError, ex:
                        log.exception("Problem loading migration step %s", path)
Beispiel #26
0
    def remove(self, app, leaveObjects=False):
        if self._v_specparams is None:
            return

        from Products.Zuul.interfaces import ICatalogTool
        if leaveObjects:
            # Check whether the ZPL-managed monitoring templates have
            # been modified by the user.  If so, those changes will
            # be lost during the upgrade.
            #
            # Ideally, I would inspect self.packables() to find these
            # objects, but we do not have access to that relationship
            # at this point in the process.
            for dcname, dcspec in self._v_specparams.device_classes.iteritems():
                deviceclass = dcspec.get_organizer(app.zport.dmd)
                if not deviceclass:
                    self.LOG.warning(
                        "DeviceClass {} has been removed at some point "
                        "after the {} ZenPack was installed.  It will be "
                        "reinstated if this ZenPack is upgraded or reinstalled".format(
                        dcname, self.id))
                    continue

                for orig_mtname, orig_mtspec in dcspec.templates.iteritems():
                    # attempt to find an existing template
                    template = self.get_object(deviceclass, 'rrdTemplates', orig_mtname)
                    # back it up if it exists
                    if template:
                        self.get_or_create_backup(deviceclass, 'rrdTemplates', orig_mtname)
                    else:
                        self.LOG.warning(
                            "Monitoring template {}/{} has been removed at some point "
                            "after the {} ZenPack was installed.  It will be "
                            "reinstated if this ZenPack is upgraded or reinstalled".format(
                            dcname, orig_mtname, self.id))

        else:
            dc = app.Devices
            for catalog in self.GLOBAL_CATALOGS:
                catObj = getattr(dc, catalog, None)
                if catObj:
                    self.LOG.info('Removing Catalog {}'.format(catalog))
                    dc._delObject(catalog)

            if self.NEW_COMPONENT_TYPES:
                self.LOG.info('Removing {} components'.format(self.id))
                cat = ICatalogTool(app.zport.dmd)
                for brain in cat.search(types=self.NEW_COMPONENT_TYPES):
                    try:
                        component = brain.getObject()
                    except Exception as e:
                        self.LOG.error("Trying to remove non-existent object {}".format(e))
                        continue
                    else:
                        component.getPrimaryParent()._delObject(component.id)

                # Remove our Device relations additions.
                from Products.ZenUtils.Utils import importClass
                for device_module_id in self.NEW_RELATIONS:
                    Device = importClass(device_module_id)
                    Device._relations = tuple([x for x in Device._relations
                                               if x[0] not in self.NEW_RELATIONS[device_module_id]])

                self.LOG.info('Removing {} relationships from existing devices.'.format(self.id))
                self._buildDeviceRelations(app)

            for dcname, dcspec in self.device_classes.iteritems():
                dcspec.remove_organizer(app.zport.dmd, self)

            for ecname, ecspec in self.event_classes.iteritems():
                ecspec.remove_organizer(app.zport.dmd, self)

            for pcname, pcspec in self.process_class_organizers.iteritems():
                pcspec.remove_organizer_or_subs(
                    app.zport.dmd, 'process_classes', 'removeOSProcessClasses', self)

        super(ZenPack, self).remove(app, leaveObjects=leaveObjects)
Beispiel #27
0
 def importPlugin(self, package, modPath):
     # ZenPack plugins are specified absolutely; we can import
     # them using the old method
     return importClass(modPath)
Beispiel #28
0
    def createObject(self, attrs):
        """
        Create an object and set it into its container

        @param attrs: attrs
        @type attrs: string
        @return: newly created object
        @rtype: object
        """
        # Does the object exist already?
        id = attrs.get('id')
        obj = None
        try:
            if id.startswith('/'):
                obj = getObjByPath(self.app, id)
            else:
                obj = self.context()._getOb(id)
        except (KeyError, AttributeError, NotFound):
            pass

        if obj is None:
            klass = importClass(attrs.get('module'), attrs.get('class'))
            if id.find('/') > -1:
                (contextpath, id) = os.path.split(id)
                try:
                    pathobj = getObjByPath(self.context(), contextpath)
                except (KeyError, AttributeError, NotFound):
                    self.log.warn(
                        "Unable to find context path %s (line %s ?) for %s" %
                        (contextpath, self._locator.getLineNumber(), id))
                    if not self.options.noCommit:
                        self.log.warn("Not committing any changes")
                        self.options.noCommit = True
                    return None
                self.objstack.append(pathobj)
            self.log.debug('Building instance %s of class %s', id,
                           klass.__name__)
            try:
                if klass.__name__ == 'AdministrativeRole':
                    user = [
                        x for x in self.dmd.ZenUsers.objectValues()
                        if x.id == id
                    ]
                    if user:
                        obj = klass(user[0], self.context().device())
                    else:
                        msg = "No AdminRole user %s exists (line %s)" % (
                            id, self._locator.getLineNumber())
                        self.log.error(msg)
                        raise Exception(msg)
                else:
                    obj = klass(id)
            except TypeError, ex:
                # This happens when the constructor expects more arguments
                self.log.exception(
                    "Unable to build %s instance of class %s (line %s)", id,
                    klass.__name__, self._locator.getLineNumber())
                raise
            self.context()._setObject(obj.id, obj)
            obj = self.context()._getOb(obj.id)
            self.objectnumber += 1
            self.log.debug('Added object %s to database' % obj.getPrimaryId())
 def importPlugin(self, package, modPath):
     # ZenPack plugins are specified absolutely; we can import
     # them using the old method
     return importClass(modPath)
    def remove(self, app, leaveObjects=False):
        if self._v_specparams is None:
            return

        from Products.Zuul.interfaces import ICatalogTool
        if leaveObjects:
            # Check whether the ZPL-managed monitoring templates have
            # been modified by the user.  If so, those changes will
            # be lost during the upgrade.
            #
            # Ideally, I would inspect self.packables() to find these
            # objects, but we do not have access to that relationship
            # at this point in the process.
            for dcname, dcspec in self._v_specparams.device_classes.iteritems(
            ):
                deviceclass = dcspec.get_organizer(app.zport.dmd)
                if not deviceclass:
                    self.LOG.warning(
                        "DeviceClass {} has been removed at some point "
                        "after the {} ZenPack was installed.  It will be "
                        "reinstated if this ZenPack is upgraded or reinstalled"
                        .format(dcname, self.id))
                    continue

                for orig_mtname, orig_mtspec in dcspec.templates.iteritems():
                    # attempt to find an existing template
                    template = self.get_object(deviceclass, 'rrdTemplates',
                                               orig_mtname)
                    # back it up if it exists
                    if template:
                        self.get_or_create_backup(deviceclass, 'rrdTemplates',
                                                  orig_mtname)
                    else:
                        self.LOG.warning(
                            "Monitoring template {}/{} has been removed at some point "
                            "after the {} ZenPack was installed.  It will be "
                            "reinstated if this ZenPack is upgraded or reinstalled"
                            .format(dcname, orig_mtname, self.id))

        else:
            dc = app.Devices
            for catalog in self.GLOBAL_CATALOGS:
                catObj = getattr(dc, catalog, None)
                if catObj:
                    self.LOG.info('Removing Catalog {}'.format(catalog))
                    dc._delObject(catalog)

            if self.NEW_COMPONENT_TYPES:
                self.LOG.info('Removing {} components'.format(self.id))
                cat = ICatalogTool(app.zport.dmd)
                for brain in cat.search(types=self.NEW_COMPONENT_TYPES):
                    try:
                        component = brain.getObject()
                    except Exception as e:
                        self.LOG.error(
                            "Trying to remove non-existent object {}".format(
                                e))
                        continue
                    else:
                        component.getPrimaryParent()._delObject(component.id)

                # Remove our Device relations additions.
                from Products.ZenUtils.Utils import importClass
                for device_module_id in self.NEW_RELATIONS:
                    Device = importClass(device_module_id)
                    Device._relations = tuple([
                        x for x in Device._relations
                        if x[0] not in self.NEW_RELATIONS[device_module_id]
                    ])

                self.LOG.info(
                    'Removing {} relationships from existing devices.'.format(
                        self.id))
                self._buildDeviceRelations(app)

            for dcname, dcspec in self.device_classes.iteritems():
                if dcspec.remove:
                    self.remove_device_class(app, dcspec)

            # Remove EventClasses with remove flag set
            self.remove_organizer_or_subs(app.zport.dmd.Events,
                                          self.event_classes, 'mappings',
                                          'removeInstances')
            # Remove Process Classes/Organizers with remove flag set
            self.remove_organizer_or_subs(app.zport.dmd.Processes,
                                          self.process_class_organizers,
                                          'process_classes',
                                          'removeOSProcessClasses')

        super(ZenPack, self).remove(app, leaveObjects=leaveObjects)